lib/lrama/states_reporter.rb in lrama-0.6.9 vs lib/lrama/states_reporter.rb in lrama-0.6.10

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + module Lrama class StatesReporter include Lrama::Report::Duration def initialize(states) @@ -12,19 +14,58 @@ end end private - def _report(io, grammar: false, states: false, itemsets: false, lookaheads: false, solved: false, counterexamples: false, verbose: false) - # TODO: Unused terms - # TODO: Unused rules - + def _report(io, grammar: false, rules: false, terms: false, states: false, itemsets: false, lookaheads: false, solved: false, counterexamples: false, verbose: false) + report_unused_rules(io) if rules + report_unused_terms(io) if terms report_conflicts(io) report_grammar(io) if grammar report_states(io, itemsets, lookaheads, solved, counterexamples, verbose) end + def report_unused_terms(io) + look_aheads = @states.states.each do |state| + state.reduces.flat_map do |reduce| + reduce.look_ahead unless reduce.look_ahead.nil? + end + end + + next_terms = @states.states.flat_map do |state| + state.shifts.map(&:next_sym).select(&:term?) + end + + unused_symbols = @states.terms.select do |term| + !(look_aheads + next_terms).include?(term) + end + + unless unused_symbols.empty? + io << "#{unused_symbols.count} Unused Terms\n\n" + unused_symbols.each_with_index do |term, index| + io << sprintf("%5d %s\n", index, term.id.s_value) + end + io << "\n\n" + end + end + + def report_unused_rules(io) + used_rules = @states.rules.flat_map(&:rhs) + + unused_rules = @states.rules.map(&:lhs).select do |rule| + !used_rules.include?(rule) && rule.token_id != 0 + end + + unless unused_rules.empty? + io << "#{unused_rules.count} Unused Rules\n\n" + unused_rules.each_with_index do |rule, index| + io << sprintf("%5d %s\n", index, rule.display_name) + end + io << "\n\n" + end + end + def report_conflicts(io) has_conflict = false @states.states.each do |state| messages = [] @@ -35,11 +76,11 @@ if cs[:reduce_reduce] messages << "#{cs[:reduce_reduce].count} reduce/reduce" end - if !messages.empty? + unless messages.empty? has_conflict = true io << "State #{state.id} conflicts: #{messages.join(', ')}\n" end end @@ -96,11 +137,11 @@ end la = "" if lookaheads && item.end_of_rule? reduce = state.find_reduce_by_item!(item) look_ahead = reduce.selected_look_ahead - if !look_ahead.empty? + unless look_ahead.empty? la = " [#{look_ahead.map(&:display_name).join(", ")}]" end end last_lhs = item.lhs @@ -116,11 +157,11 @@ end max_len = tmp.map(&:first).map(&:display_name).map(&:length).max tmp.each do |term, state_id| io << " #{term.display_name.ljust(max_len)} shift, and go to state #{state_id}\n" end - io << "\n" if !tmp.empty? + io << "\n" unless tmp.empty? # Report error caused by %nonassoc nl = false tmp = state.resolved_conflicts.select do |resolved| resolved.which == :error @@ -130,11 +171,11 @@ max_len = tmp.map(&:length).max tmp.each do |name| nl = true io << " #{name.ljust(max_len)} error (nonassociative)\n" end - io << "\n" if !tmp.empty? + io << "\n" unless tmp.empty? # Report reduces nl = false max_len = state.non_default_reduces.flat_map(&:look_ahead).compact.map(&:display_name).map(&:length).max || 0 max_len = [max_len, "$default".length].max if state.default_reduction_rule @@ -179,18 +220,18 @@ nterm.number end tmp.each do |nterm, state_id| io << " #{nterm.id.s_value.ljust(max_len)} go to state #{state_id}\n" end - io << "\n" if !tmp.empty? + io << "\n" unless tmp.empty? if solved # Report conflict resolutions state.resolved_conflicts.each do |resolved| io << " #{resolved.report_message}\n" end - io << "\n" if !state.resolved_conflicts.empty? + io << "\n" unless state.resolved_conflicts.empty? end if counterexamples && state.has_conflicts? # Report counterexamples examples = cex.compute(state) @@ -217,11 +258,11 @@ # Report direct_read_sets io << " [Direct Read sets]\n" direct_read_sets = @states.direct_read_sets @states.nterms.each do |nterm| terms = direct_read_sets[[state.id, nterm.token_id]] - next if !terms + next unless terms next if terms.empty? str = terms.map {|sym| sym.id.s_value }.join(", ") io << " read #{nterm.id.s_value} shift #{str}\n" end @@ -229,11 +270,11 @@ # Report reads_relation io << " [Reads Relation]\n" @states.nterms.each do |nterm| a = @states.reads_relation[[state.id, nterm.token_id]] - next if !a + next unless a a.each do |state_id2, nterm_id2| n = @states.nterms.find {|n| n.token_id == nterm_id2 } io << " (State #{state_id2}, #{n.id.s_value})\n" end @@ -243,11 +284,11 @@ # Report read_sets io << " [Read sets]\n" read_sets = @states.read_sets @states.nterms.each do |nterm| terms = read_sets[[state.id, nterm.token_id]] - next if !terms + next unless terms next if terms.empty? terms.each do |sym| io << " #{sym.id.s_value}\n" end @@ -256,11 +297,11 @@ # Report includes_relation io << " [Includes Relation]\n" @states.nterms.each do |nterm| a = @states.includes_relation[[state.id, nterm.token_id]] - next if !a + next unless a a.each do |state_id2, nterm_id2| n = @states.nterms.find {|n| n.token_id == nterm_id2 } io << " (State #{state.id}, #{nterm.id.s_value}) -> (State #{state_id2}, #{n.id.s_value})\n" end @@ -269,26 +310,26 @@ # Report lookback_relation io << " [Lookback Relation]\n" @states.rules.each do |rule| a = @states.lookback_relation[[state.id, rule.id]] - next if !a + next unless a a.each do |state_id2, nterm_id2| n = @states.nterms.find {|n| n.token_id == nterm_id2 } - io << " (Rule: #{rule}) -> (State #{state_id2}, #{n.id.s_value})\n" + io << " (Rule: #{rule.display_name}) -> (State #{state_id2}, #{n.id.s_value})\n" end end io << "\n" # Report follow_sets io << " [Follow sets]\n" follow_sets = @states.follow_sets @states.nterms.each do |nterm| terms = follow_sets[[state.id, nterm.token_id]] - next if !terms + next unless terms terms.each do |sym| io << " #{nterm.id.s_value} -> #{sym.id.s_value}\n" end end @@ -298,20 +339,20 @@ io << " [Look-Ahead Sets]\n" tmp = [] max_len = 0 @states.rules.each do |rule| syms = @states.la[[state.id, rule.id]] - next if !syms + next unless syms tmp << [rule, syms] max_len = ([max_len] + syms.map {|s| s.id.s_value.length }).max end tmp.each do |rule, syms| syms.each do |sym| io << " #{sym.id.s_value.ljust(max_len)} reduce using rule #{rule.id} (#{rule.lhs.id.s_value})\n" end end - io << "\n" if !tmp.empty? + io << "\n" unless tmp.empty? end # End of Report State io << "\n" end