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