diff --git a/lib/racc/grammarfileparser.rb b/lib/racc/grammarfileparser.rb index 69870257..12b6a314 100644 --- a/lib/racc/grammarfileparser.rb +++ b/lib/racc/grammarfileparser.rb @@ -200,6 +200,7 @@ def parse(src, filename = '-', lineno = 1) @grammar = Grammar.new @result = Result.new(@grammar) @embedded_action_seq = 0 + @current_rule_target = nil yyparse @scanner, :yylex parse_user_code @result.grammar.init @@ -228,11 +229,21 @@ def location end def add_rule_block(list) - target = list.shift - case target - when OrMark, OptionMark, ManyMark, Many1Mark, GroupStartMark, GroupEndMark, UserAction, Prec - raise CompileError, "#{target.lineno}: unexpected symbol #{target.name}" + if !list.empty? && list[0].is_a?(OrMark) + list.shift + target = @current_rule_target + if target.nil? + raise CompileError, "#{location()}: no target for rule continuation" + end + else + target = list.shift + case target + when OrMark, OptionMark, ManyMark, Many1Mark, GroupStartMark, GroupEndMark, UserAction, Prec + raise CompileError, "#{target.lineno}: unexpected symbol #{target.name}" + end + @current_rule_target = target end + enum = list.each.with_index _, sym, idx = _add_rule_block(target, enum) if idx diff --git a/test/assets/term.y b/test/assets/term.y new file mode 100644 index 00000000..2e875176 --- /dev/null +++ b/test/assets/term.y @@ -0,0 +1,11 @@ +class Parse +rule + target : term + { p 'target:term' } + term : :TERM1 + { p 'term:TERM1' } + | :TERM2 + { p 'term:TERM2'} + | term :TERM3 + { p 'term:TERM3' } +end diff --git a/test/regress/term b/test/regress/term new file mode 100644 index 00000000..79c6a148 --- /dev/null +++ b/test/regress/term @@ -0,0 +1,126 @@ +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "term.y". +# + +require 'racc/parser.rb' +class Parse < Racc::Parser +##### State transition tables begin ### + +racc_action_table = [ + 3, 4, 5, 6, 7 ] + +racc_action_check = [ + 0, 0, 0, 1, 6 ] + +racc_action_pointer = [ + -2, 3, nil, nil, nil, nil, 4, nil ] + +racc_action_default = [ + -4, -6, -1, -2, -3, -5, -6, 8 ] + +racc_goto_table = [ + 1, 2 ] + +racc_goto_check = [ + 1, 2 ] + +racc_goto_pointer = [ + nil, 0, 1 ] + +racc_goto_default = [ + nil, nil, nil ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 6, :_reduce_1, + 1, 7, :_reduce_2, + 1, 7, :_reduce_3, + 0, 7, :_reduce_none, + 1, 7, :_reduce_5 ] + +racc_reduce_n = 6 + +racc_shift_n = 8 + +racc_token_table = { + false => 0, + :error => 1, + :TERM1 => 2, + :TERM2 => 3, + :TERM3 => 4 } + +racc_nt_base = 5 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "TERM1", + "TERM2", + "TERM3", + "$start", + "target", + "term" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +module_eval(<<'.,.,', 'term.y', 3) + def _reduce_1(val, _values, result) + p 'target:term' + result + end +.,., + +module_eval(<<'.,.,', 'term.y', 5) + def _reduce_2(val, _values, result) + p 'term:TERM1' + result + end +.,., + +module_eval(<<'.,.,', 'term.y', 7) + def _reduce_3(val, _values, result) + p 'term:TERM2' + result + end +.,., + +# reduce 4 omitted + +module_eval(<<'.,.,', 'term.y', 9) + def _reduce_5(val, _values, result) + p 'term:TERM3' + result + end +.,., + +def _reduce_none(val, _values, result) + val[0] +end + +end # class Parse diff --git a/test/test_racc_command.rb b/test/test_racc_command.rb index 3f3f9593..ea876651 100644 --- a/test/test_racc_command.rb +++ b/test/test_racc_command.rb @@ -374,5 +374,11 @@ def test_group assert_debugfile 'group.y', [0, 0, 0, 0] assert_output_unchanged 'group.y' end + + def test_term + assert_compile 'term.y' + assert_debugfile 'term.y', [0, 0, 0, 0] + assert_output_unchanged 'term.y' + end end end