lib/lrama/grammar.rb in lrama-0.5.12 vs lib/lrama/grammar.rb in lrama-0.6.0

- old
+ new

@@ -6,10 +6,14 @@ require "lrama/grammar/precedence" require "lrama/grammar/printer" require "lrama/grammar/reference" require "lrama/grammar/rule" require "lrama/grammar/rule_builder" +require "lrama/grammar/parameterizing_rule_builder" +require "lrama/grammar/parameterizing_rule_resolver" +require "lrama/grammar/parameterizing_rule_rhs_builder" +require "lrama/grammar/parameterizing_rule" require "lrama/grammar/symbol" require "lrama/grammar/type" require "lrama/grammar/union" require "lrama/lexer" @@ -34,10 +38,11 @@ @symbols = [] @types = [] @rule_builders = [] @rules = [] @sym_to_rules = {} + @parameterizing_resolver = ParameterizingRuleResolver.new @empty_symbol = nil @eof_symbol = nil @error_symbol = nil @undef_symbol = nil @accept_symbol = nil @@ -67,11 +72,11 @@ end return sym end - if sym = @symbols.find {|s| s.id == id } + if (sym = @symbols.find {|s| s.id == id }) return sym end sym = Symbol.new( id: id, alias_name: alias_name, number: nil, tag: tag, @@ -127,10 +132,14 @@ def add_rule_builder(builder) @rule_builders << builder end + def add_parameterizing_rule_builder(builder) + @parameterizing_resolver.add_parameterizing_rule_builder(builder) + end + def prologue_first_lineno=(prologue_first_lineno) @aux.prologue_first_lineno = prologue_first_lineno end def prologue=(prologue) @@ -308,11 +317,11 @@ end end def setup_rules @rule_builders.each do |builder| - builder.setup_rules + builder.setup_rules(@parameterizing_resolver) end end def find_nterm_by_id!(id) nterms.find do |nterm| @@ -348,59 +357,24 @@ term = add_nterm(id: Lrama::Lexer::Token::Ident.new(s_value: "$accept")) term.accept_symbol = true @accept_symbol = term end - # 1. Add $accept rule to the top of rules - # 2. Extract action in the middle of RHS into new Empty rule - # 3. Append id and extract action then create Rule - # - # Bison 3.8.2 uses different orders for symbol number and rule number - # when a rule has actions in the middle of a rule. - # - # For example, - # - # `program: $@1 top_compstmt` - # - # Rules are ordered like below, - # - # 1 $@1: ε - # 2 program: $@1 top_compstmt - # - # Symbols are ordered like below, - # - # 164 program - # 165 $@1 - # def normalize_rules - # 1. Add $accept rule to the top of rules - accept = @accept_symbol - eof = @eof_symbol + # Add $accept rule to the top of rules lineno = @rule_builders.first ? @rule_builders.first.line : 0 - @rules << Rule.new(id: @rule_counter.increment, _lhs: accept.id, _rhs: [@rule_builders.first.lhs, eof.id], token_code: nil, lineno: lineno) + @rules << Rule.new(id: @rule_counter.increment, _lhs: @accept_symbol.id, _rhs: [@rule_builders.first.lhs, @eof_symbol.id], token_code: nil, lineno: lineno) setup_rules @rule_builders.each do |builder| - # Extract actions in the middle of RHS into new rules. - builder.midrule_action_rules.each do |rule| - @rules << rule - end - builder.rules.each do |rule| - add_nterm(id: rule._lhs) - @rules << rule - end - - builder.parameterizing_rules.each do |rule| add_nterm(id: rule._lhs, tag: rule.lhs_tag) @rules << rule end - - builder.midrule_action_rules.each do |rule| - add_nterm(id: rule._lhs) - end end + + @rules.sort_by!(&:id) end # Collect symbols from rules def collect_symbols @rules.flat_map(&:_rhs).each do |s|