lib/lrama/grammar/rule_builder.rb in lrama-0.6.1 vs lib/lrama/grammar/rule_builder.rb in lrama-0.6.2

- old
+ new

@@ -1,7 +1,5 @@ -require 'lrama/grammar/parameterizing_rules/builder' - module Lrama class Grammar class RuleBuilder attr_accessor :lhs, :line attr_reader :lhs_tag, :rhs, :user_code, :precedence_sym @@ -57,11 +55,11 @@ process_rhs(parameterizing_rule_resolver) build_rules end def rules - @parameterizing_rules + @old_parameterizing_rules + @midrule_action_rules + @rules + @parameterizing_rules + @midrule_action_rules + @rules end private def freeze_rhs @@ -95,48 +93,40 @@ # `#process_rhs` replaces some kind of tokens to `Ident` so that all `@replaced_rhs` are `Ident` or `Char`. def process_rhs(parameterizing_rule_resolver) return if @replaced_rhs @replaced_rhs = [] - @old_parameterizing_rules = [] rhs.each_with_index do |token, i| case token when Lrama::Lexer::Token::Char @replaced_rhs << token when Lrama::Lexer::Token::Ident @replaced_rhs << token when Lrama::Lexer::Token::InstantiateRule - if parameterizing_rule_resolver.defined?(token) - parameterizing_rule = parameterizing_rule_resolver.find(token) - raise "Unexpected token. #{token}" unless parameterizing_rule + parameterizing_rule = parameterizing_rule_resolver.find(token) + raise "Unexpected token. #{token}" unless parameterizing_rule - bindings = Binding.new(parameterizing_rule, token.args) - lhs_s_value = lhs_s_value(token, bindings) - if (created_lhs = parameterizing_rule_resolver.created_lhs(lhs_s_value)) - @replaced_rhs << created_lhs - else - lhs_token = Lrama::Lexer::Token::Ident.new(s_value: lhs_s_value, location: token.location) - @replaced_rhs << lhs_token - parameterizing_rule_resolver.created_lhs_list << lhs_token - parameterizing_rule.rhs_list.each do |r| - rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, i, lhs_tag: token.lhs_tag, skip_preprocess_references: true) - rule_builder.lhs = lhs_token - r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) } - rule_builder.line = line - rule_builder.user_code = r.user_code - rule_builder.precedence_sym = r.precedence_sym - rule_builder.complete_input - rule_builder.setup_rules(parameterizing_rule_resolver) - @rule_builders_for_parameterizing_rules << rule_builder - end - end + bindings = Binding.new(parameterizing_rule, token.args) + lhs_s_value = lhs_s_value(token, bindings) + if (created_lhs = parameterizing_rule_resolver.created_lhs(lhs_s_value)) + @replaced_rhs << created_lhs else - # TODO: Delete when the standard library will defined as a grammar file. - parameterizing_rule = ParameterizingRules::Builder.new(token, @rule_counter, token.lhs_tag, user_code, precedence_sym, line) - @old_parameterizing_rules = @old_parameterizing_rules + parameterizing_rule.build - @replaced_rhs << parameterizing_rule.build_token + lhs_token = Lrama::Lexer::Token::Ident.new(s_value: lhs_s_value, location: token.location) + @replaced_rhs << lhs_token + parameterizing_rule_resolver.created_lhs_list << lhs_token + parameterizing_rule.rhs_list.each do |r| + rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, i, lhs_tag: token.lhs_tag, skip_preprocess_references: true) + rule_builder.lhs = lhs_token + r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) } + rule_builder.line = line + rule_builder.user_code = r.user_code + rule_builder.precedence_sym = r.precedence_sym + rule_builder.complete_input + rule_builder.setup_rules(parameterizing_rule_resolver) + @rule_builders_for_parameterizing_rules << rule_builder + end end when Lrama::Lexer::Token::UserCode prefix = token.referred ? "@" : "$@" new_token = Lrama::Lexer::Token::Ident.new(s_value: prefix + @midrule_action_counter.increment.to_s) @replaced_rhs << new_token @@ -171,24 +161,29 @@ (rhs + [user_code]).compact.each.with_index(1) do |token, i| next unless token.is_a?(Lrama::Lexer::Token::UserCode) token.references.each do |ref| ref_name = ref.name - if ref_name && ref_name != '$' - if lhs.referred_by?(ref_name) + + if ref_name + if ref_name == '$' ref.name = '$' else - candidates = rhs.each_with_index.select {|token, i| token.referred_by?(ref_name) } + candidates = ([lhs] + rhs).each_with_index.select {|token, _i| token.referred_by?(ref_name) } if candidates.size >= 2 token.invalid_ref(ref, "Referring symbol `#{ref_name}` is duplicated.") end unless (referring_symbol = candidates.first) token.invalid_ref(ref, "Referring symbol `#{ref_name}` is not found.") end - ref.index = referring_symbol[1] + 1 + if referring_symbol[1] == 0 # Refers to LHS + ref.name = '$' + else + ref.index = referring_symbol[1] + end end end # TODO: Need to check index of @ too? next if ref.type == :at