diff --git a/lib/lrama/states_reporter.rb b/lib/lrama/states_reporter.rb index d05c48c9..c23932d6 100644 --- a/lib/lrama/states_reporter.rb +++ b/lib/lrama/states_reporter.rb @@ -26,39 +26,25 @@ def _report(io, grammar: false, terms: false, states: false, itemsets: false, lo end def report_unused_terms(io) - io << "Unused Terms\n\n" - - results = [] - terms = [] - used_symbols = [] - - terms = @states.symbols.select(&:term?) - - @states.states.select do |state| - state.shifts.map(&:next_sym) - end - - @states.states.each do |state| - state.reduces.select do |reduce| - used_symbols << reduce.look_ahead.flatten if !reduce.look_ahead.nil? + look_aheads = @states.states.each do |state| + state.reduces.flat_map do |reduce| + reduce.look_ahead unless reduce.look_ahead.nil? end end - @states.states.each do |state| - used_symbols << state.shifts.map(&:next_sym).select(&:term?).flatten + next_terms = @states.states.flat_map do |state| + state.shifts.map(&:next_sym).select(&:term?) end - used_symbols = used_symbols.flatten - - results = terms.select do |term| - !used_symbols.include?(term) + unused_symbols = @states.terms.select do |term| + !(look_aheads + next_terms).include?(term) end - results.each_with_index do |term, index| - io << sprintf("%5d %s\n", index, term.id.s_value) - end - - if !results.empty? + 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 diff --git a/spec/lrama/states_spec.rb b/spec/lrama/states_spec.rb index 6b924e69..e848f529 100644 --- a/spec/lrama/states_spec.rb +++ b/spec/lrama/states_spec.rb @@ -18,7 +18,7 @@ states.reporter.report(io, grammar: true, terms: true, states: true, itemsets: true, lookaheads: true) expect(io.string).to eq(<<~STR) - Unused Terms + 11 Unused Terms 0 YYerror 1 YYUNDEF