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