diff --git a/lib/lrama/grammar.rb b/lib/lrama/grammar.rb index 02ee9afcb..974f49eab 100644 --- a/lib/lrama/grammar.rb +++ b/lib/lrama/grammar.rb @@ -332,6 +332,12 @@ def _evaluate_nodes self.epilogue = node.code.s_value when Node::RequireDecl @required = true + when Node::ParamDecl + node.params.each do |param| + code = Grammar::Code::NoReferenceCode.new(type: :param, token_code: param).token_code.s_value + self.lex_param = code + self.parse_param = code + end when Node::LexParamDecl node.params.each do |param| self.lex_param = Grammar::Code::NoReferenceCode.new(type: :lex_param, token_code: param).token_code.s_value diff --git a/lib/lrama/grammar/node.rb b/lib/lrama/grammar/node.rb index 8166755e5..2739950c8 100644 --- a/lib/lrama/grammar/node.rb +++ b/lib/lrama/grammar/node.rb @@ -18,6 +18,7 @@ require_relative "node/locations_decl" require_relative "node/no_stdlib_decl" require_relative "node/nterm_decl" +require_relative "node/param_decl" require_relative "node/parameterized_rule" require_relative "node/parse_param_decl" require_relative "node/precedence_decl" diff --git a/lib/lrama/grammar/node/param_decl.rb b/lib/lrama/grammar/node/param_decl.rb new file mode 100644 index 000000000..1129c8dbb --- /dev/null +++ b/lib/lrama/grammar/node/param_decl.rb @@ -0,0 +1,18 @@ +# rbs_inline: enabled +# frozen_string_literal: true + +module Lrama + class Grammar + module Node + class ParamDecl < Base + attr_reader :params #: Array[Lexer::Token::UserCode] + + # @rbs (params: Array[Lexer::Token::UserCode], location: Lexer::Location) -> void + def initialize(params:, location:) + @params = params + super(location: location) + end + end + end + end +end diff --git a/lib/lrama/lexer.rb b/lib/lrama/lexer.rb index c70b91ce2..65d2ab44c 100644 --- a/lib/lrama/lexer.rb +++ b/lib/lrama/lexer.rb @@ -42,6 +42,7 @@ class Lexer %require %printer %destructor + %param %lex-param %parse-param %initial-action diff --git a/lib/lrama/parser.rb b/lib/lrama/parser.rb index 6be3f2b9d..cdedbe632 100644 --- a/lib/lrama/parser.rb +++ b/lib/lrama/parser.rb @@ -655,7 +655,7 @@ def token_to_str(t) module Lrama class Parser < Racc::Parser -module_eval(<<'...end parser.y/module_eval...', 'parser.y', 598) +module_eval(<<'...end parser.y/module_eval...', 'parser.y', 604) include Lrama::Tracer::Duration @@ -965,7 +965,7 @@ def merge_locations(*locations) 2, 70, :_reduce_20, 3, 70, :_reduce_21, 5, 70, :_reduce_22, - 2, 70, :_reduce_none, + 2, 70, :_reduce_23, 2, 70, :_reduce_24, 2, 70, :_reduce_25, 3, 70, :_reduce_26, @@ -1400,14 +1400,14 @@ def _reduce_15(val, _values, result) # reduce 17 omitted -module_eval(<<'.,.,', 'parser.y', 108) +module_eval(<<'.,.,', 'parser.y', 114) def _reduce_18(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 108) +module_eval(<<'.,.,', 'parser.y', 114) def _reduce_19(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result @@ -1449,9 +1449,18 @@ def _reduce_22(val, _values, result) end .,., -# reduce 23 omitted +module_eval(<<'.,.,', 'parser.y', 66) + def _reduce_23(val, _values, result) + result = Grammar::Node::ParamDecl.new( + params: val[1], + location: merge_locations(val[0].loc, val[1].last.loc) + ) + + result + end +.,., -module_eval(<<'.,.,', 'parser.y', 67) +module_eval(<<'.,.,', 'parser.y', 73) def _reduce_24(val, _values, result) result = Grammar::Node::LexParamDecl.new( params: val[1], @@ -1462,7 +1471,7 @@ def _reduce_24(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 74) +module_eval(<<'.,.,', 'parser.y', 80) def _reduce_25(val, _values, result) result = Grammar::Node::ParseParamDecl.new( params: val[1], @@ -1473,7 +1482,7 @@ def _reduce_25(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 81) +module_eval(<<'.,.,', 'parser.y', 87) def _reduce_26(val, _values, result) result = Grammar::Node::CodeDecl.new( id: val[1], @@ -1485,7 +1494,7 @@ def _reduce_26(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 89) +module_eval(<<'.,.,', 'parser.y', 95) def _reduce_27(val, _values, result) result = Grammar::Node::InitialActionDecl.new( code: val[1], @@ -1496,7 +1505,7 @@ def _reduce_27(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 96) +module_eval(<<'.,.,', 'parser.y', 102) def _reduce_28(val, _values, result) result = Grammar::Node::NoStdlibDecl.new( location: val[0].loc @@ -1506,7 +1515,7 @@ def _reduce_28(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 102) +module_eval(<<'.,.,', 'parser.y', 108) def _reduce_29(val, _values, result) result = Grammar::Node::LocationsDecl.new( location: val[0].loc @@ -1516,28 +1525,28 @@ def _reduce_29(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 179) +module_eval(<<'.,.,', 'parser.y', 185) def _reduce_30(val, _values, result) result = val result end .,., -module_eval(<<'.,.,', 'parser.y', 179) +module_eval(<<'.,.,', 'parser.y', 185) def _reduce_31(val, _values, result) result = val result end .,., -module_eval(<<'.,.,', 'parser.y', 179) +module_eval(<<'.,.,', 'parser.y', 185) def _reduce_32(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 179) +module_eval(<<'.,.,', 'parser.y', 185) def _reduce_33(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result @@ -1550,7 +1559,7 @@ def _reduce_33(val, _values, result) # reduce 36 omitted -module_eval(<<'.,.,', 'parser.y', 113) +module_eval(<<'.,.,', 'parser.y', 119) def _reduce_37(val, _values, result) result = Grammar::Node::UnionDecl.new( code: val[1], @@ -1561,7 +1570,7 @@ def _reduce_37(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 120) +module_eval(<<'.,.,', 'parser.y', 126) def _reduce_38(val, _values, result) result = Grammar::Node::DestructorDecl.new( ident_or_tags: val[2].flatten, @@ -1573,7 +1582,7 @@ def _reduce_38(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 128) +module_eval(<<'.,.,', 'parser.y', 134) def _reduce_39(val, _values, result) result = Grammar::Node::PrinterDecl.new( ident_or_tags: val[2].flatten, @@ -1585,7 +1594,7 @@ def _reduce_39(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 136) +module_eval(<<'.,.,', 'parser.y', 142) def _reduce_40(val, _values, result) result = Grammar::Node::ErrorTokenDecl.new( ident_or_tags: val[2].flatten, @@ -1597,7 +1606,7 @@ def _reduce_40(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 144) +module_eval(<<'.,.,', 'parser.y', 150) def _reduce_41(val, _values, result) result = Grammar::Node::AfterShiftDecl.new( id: val[1], @@ -1608,7 +1617,7 @@ def _reduce_41(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 151) +module_eval(<<'.,.,', 'parser.y', 157) def _reduce_42(val, _values, result) result = Grammar::Node::BeforeReduceDecl.new( id: val[1], @@ -1619,7 +1628,7 @@ def _reduce_42(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 158) +module_eval(<<'.,.,', 'parser.y', 164) def _reduce_43(val, _values, result) result = Grammar::Node::AfterReduceDecl.new( id: val[1], @@ -1630,7 +1639,7 @@ def _reduce_43(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 165) +module_eval(<<'.,.,', 'parser.y', 171) def _reduce_44(val, _values, result) result = Grammar::Node::AfterShiftErrorTokenDecl.new( id: val[1], @@ -1641,7 +1650,7 @@ def _reduce_44(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 172) +module_eval(<<'.,.,', 'parser.y', 178) def _reduce_45(val, _values, result) result = Grammar::Node::AfterPopStackDecl.new( id: val[1], @@ -1652,7 +1661,7 @@ def _reduce_45(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 181) +module_eval(<<'.,.,', 'parser.y', 187) def _reduce_46(val, _values, result) result = Grammar::Node::TokenDecl.new(tokens: val[1], location: merge_locations(val[0].loc, val[1].last.loc)) @@ -1660,7 +1669,7 @@ def _reduce_46(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 185) +module_eval(<<'.,.,', 'parser.y', 191) def _reduce_47(val, _values, result) result = Grammar::Node::TypeDecl.new( symbols: val[1], @@ -1671,7 +1680,7 @@ def _reduce_47(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 192) +module_eval(<<'.,.,', 'parser.y', 198) def _reduce_48(val, _values, result) result = Grammar::Node::NtermDecl.new( symbols: val[1], @@ -1682,7 +1691,7 @@ def _reduce_48(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 199) +module_eval(<<'.,.,', 'parser.y', 205) def _reduce_49(val, _values, result) result = Grammar::Node::PrecedenceDecl.new( type: :left, tokens: val[1], number: @precedence_number, @@ -1694,7 +1703,7 @@ def _reduce_49(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 207) +module_eval(<<'.,.,', 'parser.y', 213) def _reduce_50(val, _values, result) result = Grammar::Node::PrecedenceDecl.new( type: :right, tokens: val[1], number: @precedence_number, @@ -1706,7 +1715,7 @@ def _reduce_50(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 215) +module_eval(<<'.,.,', 'parser.y', 221) def _reduce_51(val, _values, result) result = Grammar::Node::PrecedenceDecl.new( type: :precedence, tokens: val[1], number: @precedence_number, @@ -1718,7 +1727,7 @@ def _reduce_51(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 223) +module_eval(<<'.,.,', 'parser.y', 229) def _reduce_52(val, _values, result) result = Grammar::Node::PrecedenceDecl.new( type: :nonassoc, tokens: val[1], number: @precedence_number, @@ -1730,7 +1739,7 @@ def _reduce_52(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 231) +module_eval(<<'.,.,', 'parser.y', 237) def _reduce_53(val, _values, result) result = Grammar::Node::StartDecl.new( id: val[1], @@ -1745,21 +1754,21 @@ def _reduce_53(val, _values, result) # reduce 55 omitted -module_eval(<<'.,.,', 'parser.y', 254) +module_eval(<<'.,.,', 'parser.y', 260) def _reduce_56(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 254) +module_eval(<<'.,.,', 'parser.y', 260) def _reduce_57(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 240) +module_eval(<<'.,.,', 'parser.y', 246) def _reduce_58(val, _values, result) val[1].each {|token| token.tag = val[0] @@ -1770,7 +1779,7 @@ def _reduce_58(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 247) +module_eval(<<'.,.,', 'parser.y', 253) def _reduce_59(val, _values, result) val[2].each {|token| token.tag = val[1] @@ -1785,7 +1794,7 @@ def _reduce_59(val, _values, result) # reduce 61 omitted -module_eval(<<'.,.,', 'parser.y', 255) +module_eval(<<'.,.,', 'parser.y', 261) def _reduce_62(val, _values, result) result = Grammar::Node::Token.new( id: val[0], token_id: val[1]&.s_value, alias_name: val[2]&.s_value, @@ -1796,7 +1805,7 @@ def _reduce_62(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 264) +module_eval(<<'.,.,', 'parser.y', 270) def _reduce_63(val, _values, result) result = Grammar::Node::ParameterizedRule.new( name: val[1].s_value, parameters: val[3], tag: val[5], @@ -1808,7 +1817,7 @@ def _reduce_63(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 274) +module_eval(<<'.,.,', 'parser.y', 280) def _reduce_64(val, _values, result) result = Grammar::Node::ParameterizedRule.new( name: val[2].s_value, parameters: [], @@ -1820,7 +1829,7 @@ def _reduce_64(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 282) +module_eval(<<'.,.,', 'parser.y', 288) def _reduce_65(val, _values, result) result = Grammar::Node::ParameterizedRule.new( name: val[2].s_value, parameters: val[4], @@ -1832,21 +1841,21 @@ def _reduce_65(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 290) +module_eval(<<'.,.,', 'parser.y', 296) def _reduce_66(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 291) +module_eval(<<'.,.,', 'parser.y', 297) def _reduce_67(val, _values, result) result = val[0].append(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 296) +module_eval(<<'.,.,', 'parser.y', 302) def _reduce_68(val, _values, result) result = [val[0]] @@ -1854,7 +1863,7 @@ def _reduce_68(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 300) +module_eval(<<'.,.,', 'parser.y', 306) def _reduce_69(val, _values, result) result = val[0].append(val[2]) @@ -1870,7 +1879,7 @@ def _reduce_69(val, _values, result) # reduce 73 omitted -module_eval(<<'.,.,', 'parser.y', 306) +module_eval(<<'.,.,', 'parser.y', 312) def _reduce_74(val, _values, result) reset_precs result = [] @@ -1879,7 +1888,7 @@ def _reduce_74(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 311) +module_eval(<<'.,.,', 'parser.y', 317) def _reduce_75(val, _values, result) on_action_error("intermediate %prec in a rule", val[1]) if @trailing_prec_seen node = Grammar::Node::RuleRhs::Symbol.new( @@ -1892,7 +1901,7 @@ def _reduce_75(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 320) +module_eval(<<'.,.,', 'parser.y', 326) def _reduce_76(val, _values, result) on_action_error("intermediate %prec in a rule", val[1]) if @trailing_prec_seen node = Grammar::Node::RuleRhs::InstantiateRule.new( @@ -1905,7 +1914,7 @@ def _reduce_76(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 329) +module_eval(<<'.,.,', 'parser.y', 335) def _reduce_77(val, _values, result) on_action_error("intermediate %prec in a rule", val[1]) if @trailing_prec_seen node = Grammar::Node::RuleRhs::InstantiateRule.new( @@ -1919,7 +1928,7 @@ def _reduce_77(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 339) +module_eval(<<'.,.,', 'parser.y', 345) def _reduce_78(val, _values, result) node = Grammar::Node::RuleRhs::Action.new( code: val[1], alias_name: val[2], @@ -1931,7 +1940,7 @@ def _reduce_78(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 347) +module_eval(<<'.,.,', 'parser.y', 353) def _reduce_79(val, _values, result) on_action_error("multiple %prec in a rule", val[0]) if prec_seen? @prec_seen = true @@ -1951,21 +1960,21 @@ def _reduce_79(val, _values, result) # reduce 82 omitted -module_eval(<<'.,.,', 'parser.y', 380) +module_eval(<<'.,.,', 'parser.y', 386) def _reduce_83(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 380) +module_eval(<<'.,.,', 'parser.y', 386) def _reduce_84(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 361) +module_eval(<<'.,.,', 'parser.y', 367) def _reduce_85(val, _values, result) result = val[1].map do |id| Grammar::Node::Symbol.new( @@ -1978,7 +1987,7 @@ def _reduce_85(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 370) +module_eval(<<'.,.,', 'parser.y', 376) def _reduce_86(val, _values, result) syms = val[2].map do |id| Grammar::Node::Symbol.new( @@ -1996,7 +2005,7 @@ def _reduce_86(val, _values, result) # reduce 88 omitted -module_eval(<<'.,.,', 'parser.y', 386) +module_eval(<<'.,.,', 'parser.y', 392) def _reduce_89(val, _values, result) begin_c_declaration("}") @@ -2004,7 +2013,7 @@ def _reduce_89(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 390) +module_eval(<<'.,.,', 'parser.y', 396) def _reduce_90(val, _values, result) end_c_declaration @@ -2012,7 +2021,7 @@ def _reduce_90(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 394) +module_eval(<<'.,.,', 'parser.y', 400) def _reduce_91(val, _values, result) result = val[2] @@ -2020,42 +2029,42 @@ def _reduce_91(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 437) +module_eval(<<'.,.,', 'parser.y', 443) def _reduce_92(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 437) +module_eval(<<'.,.,', 'parser.y', 443) def _reduce_93(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 437) +module_eval(<<'.,.,', 'parser.y', 443) def _reduce_94(val, _values, result) result = val result end .,., -module_eval(<<'.,.,', 'parser.y', 437) +module_eval(<<'.,.,', 'parser.y', 443) def _reduce_95(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 437) +module_eval(<<'.,.,', 'parser.y', 443) def _reduce_96(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 400) +module_eval(<<'.,.,', 'parser.y', 406) def _reduce_97(val, _values, result) result = val[0].map do |id| Grammar::Node::Token.new( @@ -2068,7 +2077,7 @@ def _reduce_97(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 409) +module_eval(<<'.,.,', 'parser.y', 415) def _reduce_98(val, _values, result) result = val[0].flat_map do |tag, ids| ids.map do |id| @@ -2084,7 +2093,7 @@ def _reduce_98(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 421) +module_eval(<<'.,.,', 'parser.y', 427) def _reduce_99(val, _values, result) # result = [{tag: nil, tokens: val[0]}, {tag: val[1], tokens: val[2]}] result = val[0].map do |id| @@ -2108,14 +2117,14 @@ def _reduce_99(val, _values, result) # reduce 101 omitted -module_eval(<<'.,.,', 'parser.y', 445) +module_eval(<<'.,.,', 'parser.y', 451) def _reduce_102(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 445) +module_eval(<<'.,.,', 'parser.y', 451) def _reduce_103(val, _values, result) result = val[1] ? val[1].unshift(val[0]) : val result @@ -2126,7 +2135,7 @@ def _reduce_103(val, _values, result) # reduce 105 omitted -module_eval(<<'.,.,', 'parser.y', 447) +module_eval(<<'.,.,', 'parser.y', 453) def _reduce_106(val, _values, result) result = val[3].map do |rhs| Grammar::Node::Rule.new( @@ -2141,7 +2150,7 @@ def _reduce_106(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 460) +module_eval(<<'.,.,', 'parser.y', 466) def _reduce_107(val, _values, result) if val[0].reject {|sym| sym.is_a?(Grammar::Node::RuleRhs::Action) || sym.is_a?(Grammar::Node::RuleRhs::Prec) }.count > 1 empties = val[0].select { |sym| sym.is_a?(Grammar::Node::RuleRhs::Empty) } @@ -2155,7 +2164,7 @@ def _reduce_107(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 470) +module_eval(<<'.,.,', 'parser.y', 476) def _reduce_108(val, _values, result) result = val[0].append(val[2]) @@ -2163,7 +2172,7 @@ def _reduce_108(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 476) +module_eval(<<'.,.,', 'parser.y', 482) def _reduce_109(val, _values, result) reset_precs result = [] @@ -2172,7 +2181,7 @@ def _reduce_109(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 481) +module_eval(<<'.,.,', 'parser.y', 487) def _reduce_110(val, _values, result) node = Grammar::Node::RuleRhs::Empty.new(location: val[1].loc) result.append(node) @@ -2181,7 +2190,7 @@ def _reduce_110(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 486) +module_eval(<<'.,.,', 'parser.y', 492) def _reduce_111(val, _values, result) on_action_error("intermediate %prec in a rule", val[1]) if @trailing_prec_seen node = Grammar::Node::RuleRhs::Symbol.new( @@ -2194,7 +2203,7 @@ def _reduce_111(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 495) +module_eval(<<'.,.,', 'parser.y', 501) def _reduce_112(val, _values, result) on_action_error("intermediate %prec in a rule", val[1]) if @trailing_prec_seen node = Grammar::Node::RuleRhs::InstantiateRule.new( @@ -2208,7 +2217,7 @@ def _reduce_112(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 505) +module_eval(<<'.,.,', 'parser.y', 511) def _reduce_113(val, _values, result) on_action_error("intermediate %prec in a rule", val[1]) if @trailing_prec_seen node = Grammar::Node::RuleRhs::InstantiateRule.new( @@ -2222,7 +2231,7 @@ def _reduce_113(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 515) +module_eval(<<'.,.,', 'parser.y', 521) def _reduce_114(val, _values, result) node = Grammar::Node::RuleRhs::Action.new( code: val[1], alias_name: val[2], tag: val[3], @@ -2234,7 +2243,7 @@ def _reduce_114(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 523) +module_eval(<<'.,.,', 'parser.y', 529) def _reduce_115(val, _values, result) on_action_error("multiple %prec in a rule", val[0]) if prec_seen? if val[0].empty? @@ -2253,21 +2262,21 @@ def _reduce_115(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 538) +module_eval(<<'.,.,', 'parser.y', 544) def _reduce_116(val, _values, result) result = "option" result end .,., -module_eval(<<'.,.,', 'parser.y', 539) +module_eval(<<'.,.,', 'parser.y', 545) def _reduce_117(val, _values, result) result = "nonempty_list" result end .,., -module_eval(<<'.,.,', 'parser.y', 540) +module_eval(<<'.,.,', 'parser.y', 546) def _reduce_118(val, _values, result) result = "list" result @@ -2278,7 +2287,7 @@ def _reduce_118(val, _values, result) # reduce 120 omitted -module_eval(<<'.,.,', 'parser.y', 545) +module_eval(<<'.,.,', 'parser.y', 551) def _reduce_121(val, _values, result) result = if val[1] [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[0])] @@ -2290,28 +2299,28 @@ def _reduce_121(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 551) +module_eval(<<'.,.,', 'parser.y', 557) def _reduce_122(val, _values, result) result = val[0].append(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 552) +module_eval(<<'.,.,', 'parser.y', 558) def _reduce_123(val, _values, result) result = val[0].append(Lrama::Lexer::Token::InstantiateRule.new(s_value: val[2].s_value, location: @lexer.location, args: val[4])) result end .,., -module_eval(<<'.,.,', 'parser.y', 553) +module_eval(<<'.,.,', 'parser.y', 559) def _reduce_124(val, _values, result) result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[0].s_value, location: @lexer.location, args: val[2])] result end .,., -module_eval(<<'.,.,', 'parser.y', 558) +module_eval(<<'.,.,', 'parser.y', 564) def _reduce_125(val, _values, result) if prec_seen? on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec @@ -2323,7 +2332,7 @@ def _reduce_125(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 566) +module_eval(<<'.,.,', 'parser.y', 572) def _reduce_126(val, _values, result) end_c_declaration @@ -2331,7 +2340,7 @@ def _reduce_126(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 570) +module_eval(<<'.,.,', 'parser.y', 576) def _reduce_127(val, _values, result) result = val[2] @@ -2339,14 +2348,14 @@ def _reduce_127(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 573) +module_eval(<<'.,.,', 'parser.y', 579) def _reduce_128(val, _values, result) result = val[1].s_value result end .,., -module_eval(<<'.,.,', 'parser.y', 578) +module_eval(<<'.,.,', 'parser.y', 584) def _reduce_129(val, _values, result) begin_c_declaration('\Z') @@ -2354,7 +2363,7 @@ def _reduce_129(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 582) +module_eval(<<'.,.,', 'parser.y', 588) def _reduce_130(val, _values, result) end_c_declaration result = Grammar::Node::EpilogueDecl.new(code: val[2], location: merge_locations(val[0].loc, val[2].loc)) @@ -2373,7 +2382,7 @@ def _reduce_130(val, _values, result) # reduce 135 omitted -module_eval(<<'.,.,', 'parser.y', 593) +module_eval(<<'.,.,', 'parser.y', 599) def _reduce_136(val, _values, result) result = Lrama::Lexer::Token::Ident.new(s_value: val[0].s_value, location: val[0].location) result diff --git a/parser.y b/parser.y index 2250abb34..332e492eb 100644 --- a/parser.y +++ b/parser.y @@ -63,6 +63,12 @@ rule ) } | "%param" param+ + { + result = Grammar::Node::ParamDecl.new( + params: val[1], + location: merge_locations(val[0].loc, val[1].last.loc) + ) + } | "%lex-param" param+ { result = Grammar::Node::LexParamDecl.new( diff --git a/sig/generated/lrama/grammar/node/param_decl.rbs b/sig/generated/lrama/grammar/node/param_decl.rbs new file mode 100644 index 000000000..9393c8a43 --- /dev/null +++ b/sig/generated/lrama/grammar/node/param_decl.rbs @@ -0,0 +1,14 @@ +# Generated from lib/lrama/grammar/node/param_decl.rb with RBS::Inline + +module Lrama + class Grammar + module Node + class ParamDecl < Base + attr_reader params: Array[Lexer::Token::UserCode] + + # @rbs (params: Array[Lexer::Token::UserCode], location: Lexer::Location) -> void + def initialize: (params: Array[Lexer::Token::UserCode], location: Lexer::Location) -> void + end + end + end +end diff --git a/spec/fixtures/integration/params.y b/spec/fixtures/integration/params.y index d9ad53873..256d50516 100644 --- a/spec/fixtures/integration/params.y +++ b/spec/fixtures/integration/params.y @@ -14,8 +14,7 @@ static int yyerror(YYLTYPE *loc, int parse_param, const char *str); %} -%lex-param {int parse_param} -%parse-param {int parse_param} +%param {int parse_param} %union { int val; diff --git a/spec/lrama/integration_spec.rb b/spec/lrama/integration_spec.rb index c0bba17f4..e07581c3e 100644 --- a/spec/lrama/integration_spec.rb +++ b/spec/lrama/integration_spec.rb @@ -100,7 +100,7 @@ def generate_object(grammar_file_path, c_path, obj_path, command_args: []) test_parser("contains_at_reference", "", "") end - describe "YYDEBUG, %lex-param, %parse-param option are enabled" do + describe "YYDEBUG and %param are enabled" do it "returns 9 for '(1+2)*3'" do test_parser("params", "(1+2)*3", "=> 9") end diff --git a/spec/lrama/parser_spec.rb b/spec/lrama/parser_spec.rb index cbccdc13a..2366cb32b 100644 --- a/spec/lrama/parser_spec.rb +++ b/spec/lrama/parser_spec.rb @@ -118,6 +118,19 @@ end describe '#parse' do + it 'uses %param for both lexer and parser parameters' do + grammar = Lrama::Parser.new(<<~'GRAMMAR', "param.y").parse + %param {struct context *ctx} + %% + start: ; + GRAMMAR + grammar.prepare + grammar.validate! + + expect(grammar.lex_param).to eq("struct context *ctx") + expect(grammar.parse_param).to eq("struct context *ctx") + end + it "no_union" do path = "common/no_union.y" y = File.read(fixture_path(path))