lib/lrama/grammar.rb in lrama-0.5.1 vs lib/lrama/grammar.rb in lrama-0.5.2

- old
+ new

@@ -153,20 +153,20 @@ references.reverse.each do |ref| first_column = ref.first_column last_column = ref.last_column case - when ref.number == "$" && ref.type == :dollar # $$ + when ref.value == "$" && ref.type == :dollar # $$ # Omit "<>" member = tag.s_value[1..-2] str = "((*yyvaluep).#{member})" - when ref.number == "$" && ref.type == :at # @$ + when ref.value == "$" && ref.type == :at # @$ str = "(*yylocationp)" when ref.type == :dollar # $n - raise "$#{ref.number} can not be used in %printer." + raise "$#{ref.value} can not be used in %printer." when ref.type == :at # @n - raise "@#{ref.number} can not be used in %printer." + raise "@#{ref.value} can not be used in %printer." else raise "Unexpected. #{self}, #{ref}" end t_code[first_column..last_column] = str @@ -188,23 +188,23 @@ references.reverse.each do |ref| first_column = ref.first_column last_column = ref.last_column case - when ref.number == "$" && ref.type == :dollar # $$ + when ref.value == "$" && ref.type == :dollar # $$ # Omit "<>" member = ref.tag.s_value[1..-2] str = "(yyval.#{member})" - when ref.number == "$" && ref.type == :at # @$ + when ref.value == "$" && ref.type == :at # @$ str = "(yyloc)" when ref.type == :dollar # $n - i = -ref.position_in_rhs + ref.number + i = -ref.position_in_rhs + ref.value # Omit "<>" member = ref.tag.s_value[1..-2] str = "(yyvsp[#{i}].#{member})" when ref.type == :at # @n - i = -ref.position_in_rhs + ref.number + i = -ref.position_in_rhs + ref.value str = "(yylsp[#{i}])" else raise "Unexpected. #{self}, #{ref}" end @@ -224,18 +224,18 @@ references.reverse.each do |ref| first_column = ref.first_column last_column = ref.last_column case - when ref.number == "$" && ref.type == :dollar # $$ + when ref.value == "$" && ref.type == :dollar # $$ str = "yylval" - when ref.number == "$" && ref.type == :at # @$ + when ref.value == "$" && ref.type == :at # @$ str = "yylloc" when ref.type == :dollar # $n - raise "$#{ref.number} can not be used in initial_action." + raise "$#{ref.value} can not be used in initial_action." when ref.type == :at # @n - raise "@#{ref.number} can not be used in initial_action." + raise "@#{ref.value} can not be used in initial_action." else raise "Unexpected. #{self}, #{ref}" end t_code[first_column..last_column] = str @@ -245,11 +245,11 @@ end end # type: :dollar or :at # ex_tag: "$<tag>1" (Optional) - Reference = Struct.new(:type, :number, :ex_tag, :first_column, :last_column, :referring_symbol, :position_in_rhs, keyword_init: true) do + Reference = Struct.new(:type, :value, :ex_tag, :first_column, :last_column, :referring_symbol, :position_in_rhs, keyword_init: true) do def tag if ex_tag ex_tag else referring_symbol.tag @@ -380,12 +380,12 @@ def add_rule(lhs:, rhs:, lineno:) @_rules << [lhs, rhs, lineno] end def build_references(token_code) - token_code.references.map! do |type, number, tag, first_column, last_column| - Reference.new(type: type, number: number, ex_tag: tag, first_column: first_column, last_column: last_column) + token_code.references.map! do |type, value, tag, first_column, last_column| + Reference.new(type: type, value: value, ex_tag: tag, first_column: first_column, last_column: last_column) end token_code end @@ -625,18 +625,26 @@ token.references.each do |ref| # Need to keep position_in_rhs for actions in the middle of RHS ref.position_in_rhs = i - 1 next if ref.type == :at # $$, $n, @$, @n can be used in any actions - number = ref.number - if number == "$" + if ref.value == "$" # TODO: Should be postponed after middle actions are extracted? ref.referring_symbol = lhs - else - raise "Can not refer following component. #{number} >= #{i}. #{token}" if number >= i - rhs1[number - 1].referred = true - ref.referring_symbol = rhs1[number - 1] + elsif ref.value.is_a?(Integer) + raise "Can not refer following component. #{ref.value} >= #{i}. #{token}" if ref.value >= i + rhs1[ref.value - 1].referred = true + ref.referring_symbol = rhs1[ref.value - 1] + elsif ref.value.is_a?(String) + target_tokens = ([lhs] + rhs1 + [code]).compact.first(i) + referring_symbol_candidate = target_tokens.filter {|token| token.referred_by?(ref.value) } + raise "Referring symbol `#{ref.value}` is duplicated. #{token}" if referring_symbol_candidate.size >= 2 + raise "Referring symbol `#{ref.value}` is not found. #{token}" if referring_symbol_candidate.count == 0 + + referring_symbol = referring_symbol_candidate.first + referring_symbol.referred = true + ref.referring_symbol = referring_symbol end end end end