From 13b52747f4732d1941119d6a73443f24b408ff70 Mon Sep 17 00:00:00 2001 From: yui-knk Date: Sun, 16 Feb 2025 12:30:17 +0900 Subject: [PATCH] Render inadequacy annotation of each state on output file --- lib/lrama/reporter.rb | 2 +- lib/lrama/reporter/states.rb | 41 +++++++++++++++++++++++-- lib/lrama/states.rb | 2 +- sig/generated/lrama/reporter/states.rbs | 4 +-- spec/lrama/states_spec.rb | 24 +++++++++++++++ 5 files changed, 67 insertions(+), 6 deletions(-) diff --git a/lib/lrama/reporter.rb b/lib/lrama/reporter.rb index 27535d75..d2b092dd 100644 --- a/lib/lrama/reporter.rb +++ b/lib/lrama/reporter.rb @@ -29,7 +29,7 @@ def report(io, states) @terms.report(io, states) @conflicts.report(io, states) @grammar.report(io, states) - @states.report(io, states) + @states.report(io, states, ielr: states.ielr_defined?) end end end diff --git a/lib/lrama/reporter/states.rb b/lib/lrama/reporter/states.rb index 69c83985..945ee0e3 100644 --- a/lib/lrama/reporter/states.rb +++ b/lib/lrama/reporter/states.rb @@ -13,8 +13,8 @@ def initialize(itemsets: false, lookaheads: false, solved: false, counterexample @verbose = verbose end - # @rbs (IO io, Lrama::States states) -> void - def report(io, states) + # @rbs (IO io, Lrama::States states, ielr: bool) -> void + def report(io, states, ielr: false) if @counterexamples cex = Counterexamples.new(states) end @@ -179,6 +179,43 @@ def report(io, states) end end + if ielr && !state.annotation_list.empty? + state.annotation_list.each do |annotation| + # binding.irb + io << " inadequacy annotation manifesting state #{annotation.state.id}, token #{annotation.token.id.s_value}\n" + + annotation.contribution_matrix.each do |action, contributions| + case action + when State::Shift + io << " state #{state.id} always contributes to shift by #{action.next_sym.id.s_value}\n" + when State::Reduce + reduce_rule = action.item.rule + reduce_rule_text = "#{reduce_rule.lhs.display_name}: #{reduce_rule.rhs.map(&:display_name).join(" ")}" + + if contributions + contributions.each do |item, contribution| + if item.empty_rule? + r = "ε •" + else + r = item.rhs.map(&:display_name).insert(item.position, "•").join(" ") + end + + if contribution + io << " '#{r}' potentially contributes to reduce by '#{reduce_rule_text}'\n" + else + io << " '#{r}' never contributes to reduce by '#{reduce_rule_text}'\n" + end + end + else + io << " state #{state.id} always contributes to reduce by '#{reduce_rule_text}'\n" + end + end + end + end + + io << "\n" + end + if @verbose # Report direct_read_sets io << " [Direct Read sets]\n" diff --git a/lib/lrama/states.rb b/lib/lrama/states.rb index 51a2852e..db8cdebe 100644 --- a/lib/lrama/states.rb +++ b/lib/lrama/states.rb @@ -14,7 +14,7 @@ class States include Lrama::Tracer::Duration def_delegators "@grammar", :symbols, :terms, :nterms, :rules, - :accept_symbol, :eof_symbol, :undef_symbol, :find_symbol_by_s_value! + :accept_symbol, :eof_symbol, :undef_symbol, :find_symbol_by_s_value!, :ielr_defined? attr_reader :states, :reads_relation, :includes_relation, :lookback_relation diff --git a/sig/generated/lrama/reporter/states.rbs b/sig/generated/lrama/reporter/states.rbs index f40e278d..54d1e317 100644 --- a/sig/generated/lrama/reporter/states.rbs +++ b/sig/generated/lrama/reporter/states.rbs @@ -6,8 +6,8 @@ module Lrama # @rbs (itemsets: bool, lookaheads: bool, solved: bool, counterexamples: bool, verbose: bool, **untyped _) -> void def initialize: (itemsets: bool, lookaheads: bool, solved: bool, counterexamples: bool, verbose: bool, **untyped _) -> void - # @rbs (IO io, Lrama::States states) -> void - def report: (IO io, Lrama::States states) -> void + # @rbs (IO io, Lrama::States states, ielr: bool) -> void + def report: (IO io, Lrama::States states, ielr: bool) -> void end end end diff --git a/spec/lrama/states_spec.rb b/spec/lrama/states_spec.rb index 222ca49b..7bc8ad4b 100644 --- a/spec/lrama/states_spec.rb +++ b/spec/lrama/states_spec.rb @@ -1824,6 +1824,10 @@ class go to state 5 S go to state 3 + inadequacy annotation manifesting state 14, token a + state 0 always contributes to shift by a + state 0 always contributes to reduce by 'E: ' + State 1 @@ -1833,6 +1837,10 @@ class go to state 5 A go to state 5 + inadequacy annotation manifesting state 14, token a + state 1 always contributes to shift by a + state 1 always contributes to reduce by 'E: ' + State 2 @@ -1842,6 +1850,10 @@ class go to state 5 A go to state 6 + inadequacy annotation manifesting state 14, token a + state 2 always contributes to shift by a + 'b • A B b' never contributes to reduce by 'E: ' + State 3 @@ -1859,6 +1871,10 @@ class go to state 5 C go to state 9 D go to state 10 + inadequacy annotation manifesting state 14, token a + state 4 always contributes to shift by a + 'a • C D E' potentially contributes to reduce by 'E: ' + State 5 @@ -1904,6 +1920,10 @@ class go to state 5 D go to state 14 + inadequacy annotation manifesting state 14, token a + state 9 always contributes to shift by a + 'a C • D E' potentially contributes to reduce by 'E: ' + State 10 @@ -1941,6 +1961,10 @@ class go to state 5 E go to state 18 + inadequacy annotation manifesting state 14, token a + state 14 always contributes to shift by a + 'a C D • E' potentially contributes to reduce by 'E: ' + State 15