From c15c76550af7db5db2da201992d71d437feafca8 Mon Sep 17 00:00:00 2001 From: ydah Date: Thu, 9 May 2024 22:29:27 +0900 Subject: [PATCH] [PoC] Intoroduce parameterizing rules with conditonal I would like to propose a new grammar in this PR. I believe that more parameterizing rules can handle more abstract rules if we can switch between rules and actions that are expanded by conditions in order to make rules common. Syntax is as follows: ``` %rule defined_rule(X, condition): /* empty */ | X { $$ = $1; } %if(condition) /* 1 */ | %if(condition) X %endif X { $$ = $1; } /* 2 */ ; %% r_true : defined_rule(number, %true) ; r_false : defined_rule(number, %false) ; ``` 1. It's like a postfix if in Ruby. If condition is false, it is equivalent to missing this line. 2. If statementIf condition is false, it is equivalent to missing RHS between `%if` and`% endif`. I believe it will solve the problem mentioned in the article below with the tight coupling with Lexer "to disable certain generation rules under certain conditions" and I would like to propose this feature to solve this problem. https://yui-knk.hatenablog.com/entry/2023/04/04/190413 We can trace the RHS to [f_args](https://github.com/ruby/ruby/blob/2f916812a9b818b432ee7c299e021ec62d4727fb/parse.y#L5523-L5575) > [args_tail](https://github.com/ruby/ruby/blob/2f916812a9b818b432ee7c299e021ec62d4727fb/parse.y#L5487-L5503) > [args_forward](https://github.com/ruby/ruby/blob/2f916812a9b818b432ee7c299e021ec62d4727fb/parse.y#L5586-L5597), where f_args is the RHS of both the lambda argument (f_larglist) and the method definition argument (f_arglist). So if we can switch between RHS and actions by passing parameters, we can break up the Lexer/Parser coupling here. --- lib/lrama/grammar.rb | 7 +- lib/lrama/grammar/binding.rb | 4 + lib/lrama/grammar/parameterizing_rule/rhs.rb | 25 + lib/lrama/grammar/rule_builder.rb | 5 +- lib/lrama/lexer.rb | 4 + lib/lrama/lexer/token.rb | 1 + lib/lrama/lexer/token/control_syntax.rb | 34 + lib/lrama/parser.rb | 947 ++++++++++-------- parser.y | 33 +- sig/lrama/grammar/parameterizing_rule/rhs.rbs | 2 + sig/lrama/lexer/token/control_syntax.rbs | 16 + .../parameterizing_rules/user_defined/if.y | 44 + spec/lrama/parser_spec.rb | 103 ++ 13 files changed, 800 insertions(+), 425 deletions(-) create mode 100644 lib/lrama/lexer/token/control_syntax.rb create mode 100644 sig/lrama/lexer/token/control_syntax.rbs create mode 100644 spec/fixtures/parameterizing_rules/user_defined/if.y diff --git a/lib/lrama/grammar.rb b/lib/lrama/grammar.rb index 44df2c59..59bdbf10 100644 --- a/lib/lrama/grammar.rb +++ b/lib/lrama/grammar.rb @@ -30,7 +30,7 @@ class Grammar :after_shift, :before_reduce, :after_reduce, :after_shift_error_token, :after_pop_stack, :symbols_resolver, :types, :rules, :rule_builders, - :sym_to_rules, :no_stdlib + :sym_to_rules, :no_stdlib, :if_count def_delegators "@symbols_resolver", :symbols, :nterms, :terms, :add_nterm, :add_term, :find_symbol_by_number!, :find_symbol_by_id!, :token_to_symbol, @@ -58,6 +58,7 @@ def initialize(rule_counter) @accept_symbol = nil @aux = Auxiliary.new @no_stdlib = false + @if_count = 0 append_special_symbols end @@ -170,6 +171,10 @@ def find_rules_by_symbol(sym) @sym_to_rules[sym.number] end + def initialize_if_count + @if_count = 0 + end + private def compute_nullable diff --git a/lib/lrama/grammar/binding.rb b/lib/lrama/grammar/binding.rb index e5ea3fb0..fecbcc83 100644 --- a/lib/lrama/grammar/binding.rb +++ b/lib/lrama/grammar/binding.rb @@ -15,6 +15,10 @@ def resolve_symbol(symbol) if symbol.is_a?(Lexer::Token::InstantiateRule) resolved_args = symbol.args.map { |arg| resolve_symbol(arg) } Lrama::Lexer::Token::InstantiateRule.new(s_value: symbol.s_value, location: symbol.location, args: resolved_args, lhs_tag: symbol.lhs_tag) + elsif symbol.is_a?(Lexer::Token::ControlSyntax) + resolved = symbol.dup + resolved.condition = @parameter_to_arg[symbol.condition_value] + resolved else @parameter_to_arg[symbol.s_value] || symbol end diff --git a/lib/lrama/grammar/parameterizing_rule/rhs.rb b/lib/lrama/grammar/parameterizing_rule/rhs.rb index d4188b8f..defe8abd 100644 --- a/lib/lrama/grammar/parameterizing_rule/rhs.rb +++ b/lib/lrama/grammar/parameterizing_rule/rhs.rb @@ -10,6 +10,31 @@ def initialize @precedence_sym = nil end + def skip?(bindings) + return false unless @symbols.last + last_sym = bindings.resolve_symbol(@symbols.last) + last_sym.is_a?(Lexer::Token::ControlSyntax) && last_sym.if? && last_sym.false? + end + + def resolve_symbols(bindings) + is_skip = [] + @symbols.map do |sym| + resolved = bindings.resolve_symbol(sym) + if resolved.is_a?(Lexer::Token::ControlSyntax) + if resolved.if? + is_skip.push(resolved.false?) + elsif resolved.endif? + is_skip.pop + else + raise "Unexpected control syntax: #{resolved.condition_value}" + end + nil + else + resolved unless is_skip.last + end + end.compact + end + def resolve_user_code(bindings) return unless user_code diff --git a/lib/lrama/grammar/rule_builder.rb b/lib/lrama/grammar/rule_builder.rb index 051c192d..efbfd43d 100644 --- a/lib/lrama/grammar/rule_builder.rb +++ b/lib/lrama/grammar/rule_builder.rb @@ -133,7 +133,10 @@ def process_rhs parameterizing_rule.rhs_list.each do |r| rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: token.lhs_tag || parameterizing_rule.tag) rule_builder.lhs = lhs_token - r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) } + next if r.skip?(bindings) + r.resolve_symbols(bindings).each do |sym| + rule_builder.add_rhs(sym) + end rule_builder.line = line rule_builder.precedence_sym = r.precedence_sym rule_builder.user_code = r.resolve_user_code(bindings) diff --git a/lib/lrama/lexer.rb b/lib/lrama/lexer.rb index 40622a51..e1e9e5ee 100644 --- a/lib/lrama/lexer.rb +++ b/lib/lrama/lexer.rb @@ -38,6 +38,10 @@ class Lexer %rule %no-stdlib %inline + %if + %endif + %true + %false ) def initialize(grammar_file) diff --git a/lib/lrama/lexer/token.rb b/lib/lrama/lexer/token.rb index 59b49d5f..6e179f45 100644 --- a/lib/lrama/lexer/token.rb +++ b/lib/lrama/lexer/token.rb @@ -1,4 +1,5 @@ require 'lrama/lexer/token/char' +require 'lrama/lexer/token/control_syntax' require 'lrama/lexer/token/ident' require 'lrama/lexer/token/instantiate_rule' require 'lrama/lexer/token/tag' diff --git a/lib/lrama/lexer/token/control_syntax.rb b/lib/lrama/lexer/token/control_syntax.rb new file mode 100644 index 00000000..9a89368c --- /dev/null +++ b/lib/lrama/lexer/token/control_syntax.rb @@ -0,0 +1,34 @@ +module Lrama + class Lexer + class Token + class ControlSyntax < Token + attr_accessor :condition + + def initialize(s_value:, location:, condition: nil) + @condition = condition + super(s_value: s_value, location: location) + end + + def if? + s_value == '%if' + end + + def endif? + s_value == '%endif' + end + + def true? + !!@condition&.s_value + end + + def false? + !true? + end + + def condition_value + @condition&.s_value + end + end + end + end +end diff --git a/lib/lrama/parser.rb b/lib/lrama/parser.rb index a6bfe511..b679ea37 100644 --- a/lib/lrama/parser.rb +++ b/lib/lrama/parser.rb @@ -658,7 +658,7 @@ def token_to_str(t) module Lrama class Parser < Racc::Parser -module_eval(<<'...end parser.y/module_eval...', 'parser.y', 536) +module_eval(<<'...end parser.y/module_eval...', 'parser.y', 563) include Lrama::Report::Duration @@ -732,322 +732,348 @@ def raise_parse_error(error_message, location) ##### State transition tables begin ### racc_action_table = [ - 98, 51, 99, 163, 88, 79, 51, 51, 180, 163, - 79, 79, 51, 162, 180, 156, 79, 165, 157, 51, - 3, 50, 181, 165, 70, 51, 8, 50, 181, 79, - 75, 51, 6, 50, 7, 161, 82, 47, 51, 51, - 50, 50, 89, 82, 82, 166, 41, 51, 100, 50, - 182, 166, 82, 51, 48, 50, 182, 23, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 47, 51, 51, 50, 50, 93, 79, 197, - 51, 51, 50, 50, 79, 197, 51, 51, 50, 50, - 79, 197, 23, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 9, 51, 54, - 50, 14, 15, 16, 17, 18, 19, 54, 54, 20, - 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 51, 51, - 50, 50, 79, 197, 51, 51, 50, 50, 79, 197, - 51, 51, 50, 50, 79, 197, 51, 51, 50, 50, - 79, 79, 51, 51, 50, 50, 79, 79, 51, 51, - 50, 50, 79, 79, 51, 51, 50, 207, 79, 79, - 51, 51, 207, 207, 79, 79, 51, 51, 50, 50, - 79, 187, 188, 189, 96, 187, 188, 189, 96, 217, - 221, 229, 218, 218, 218, 51, 51, 50, 50, 187, - 188, 189, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 90, 94, 96, 101, 101, 101, 103, - 109, 113, 114, 117, 117, 117, 117, 120, 47, 124, - 125, 127, 129, 130, 131, 132, 133, 136, 140, 141, - 142, 143, 146, 147, 148, 150, 160, 168, 170, 171, - 172, 173, 174, 176, 177, 178, 146, 184, 192, 193, - 200, 160, 204, 176, 211, 160, 215, 216, 178, 176, - 226, 176, 228, 96, 96, 176 ] + 98, 156, 99, 51, 157, 210, 51, 79, 222, 51, + 79, 210, 51, 79, 50, 51, 79, 210, 51, 79, + 50, 162, 79, 51, 3, 163, 51, 79, 180, 51, + 79, 180, 51, 79, 163, 228, 79, 8, 229, 165, + 88, 41, 181, 161, 51, 181, 50, 247, 165, 70, + 229, 48, 100, 215, 216, 249, 215, 216, 229, 215, + 216, 47, 215, 216, 54, 215, 216, 166, 215, 216, + 182, 183, 184, 182, 183, 184, 166, 6, 89, 7, + 54, 23, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 47, -126, 51, 54, + 50, 93, 79, 189, 190, 191, 51, 51, 50, 50, + 79, 75, 82, 51, 57, 50, 23, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 9, 51, 58, 50, 14, 15, 16, 17, 18, + 19, 59, 60, 20, 21, 22, 23, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 51, 51, 50, 50, 61, 82, 82, 51, + 51, 50, 50, 62, 82, 189, 190, 191, 63, 51, + 96, 50, 64, 79, 199, 51, 51, 50, 50, 79, + 199, 51, 51, 50, 50, 79, 199, 189, 190, 191, + 65, 51, 96, 50, 66, 79, 199, 51, 51, 50, + 50, 79, 199, 51, 51, 50, 50, 79, 199, 51, + 51, 50, 50, 79, 79, 51, 51, 50, 50, 79, + 79, 51, 51, 50, 50, 79, 79, 51, 51, 50, + 50, 51, 51, 50, 50, 189, 190, 191, 67, 90, + 94, 96, 101, 101, 101, 103, 109, 113, 114, 117, + 117, 117, 117, 120, 47, 124, 125, 127, 129, 130, + 131, 132, 133, 136, 140, 141, 142, 143, 146, 147, + 148, 150, 160, 168, 170, 171, 172, 173, 174, 176, + 177, 178, 146, 186, 194, 195, 202, 160, 206, 209, + 176, 218, 160, 225, 226, 227, 178, 232, 233, 235, + 237, 176, 242, 176, -124, 246, 96, -126, 96, 176, + -125 ] racc_action_check = [ - 49, 145, 49, 145, 39, 145, 159, 183, 159, 183, - 159, 183, 201, 144, 201, 139, 201, 145, 139, 33, - 1, 33, 159, 183, 33, 34, 3, 34, 201, 34, - 34, 35, 2, 35, 2, 144, 35, 9, 36, 37, - 36, 37, 39, 36, 37, 145, 7, 38, 49, 38, - 159, 183, 38, 15, 14, 15, 201, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 42, 69, 172, 69, 172, 42, 172, 172, - 173, 70, 173, 70, 173, 173, 174, 81, 174, 81, - 174, 174, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 4, 82, 16, - 82, 4, 4, 4, 4, 4, 4, 17, 18, 4, + 49, 139, 49, 186, 139, 186, 206, 186, 206, 227, + 206, 227, 229, 227, 229, 233, 229, 233, 235, 233, + 235, 144, 235, 145, 1, 145, 159, 145, 159, 203, + 159, 203, 185, 203, 185, 211, 185, 3, 211, 145, + 39, 7, 159, 144, 33, 203, 33, 238, 185, 33, + 238, 14, 49, 186, 186, 244, 206, 206, 244, 227, + 227, 9, 229, 229, 16, 233, 233, 145, 235, 235, + 159, 159, 159, 203, 203, 203, 185, 2, 39, 2, + 17, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 42, 223, 74, 18, + 74, 42, 74, 223, 223, 223, 34, 35, 34, 35, + 34, 34, 35, 15, 19, 15, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 4, 69, 20, 69, 4, 4, 4, 4, 4, + 4, 23, 25, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 194, 109, - 194, 109, 194, 194, 198, 111, 198, 111, 198, 198, - 199, 117, 199, 117, 199, 199, 74, 75, 74, 75, - 74, 75, 114, 116, 114, 116, 114, 116, 137, 166, - 137, 166, 137, 166, 182, 184, 182, 184, 182, 184, - 204, 216, 204, 216, 204, 216, 218, 119, 218, 119, - 218, 164, 164, 164, 164, 179, 179, 179, 179, 208, - 214, 223, 208, 214, 223, 134, 138, 134, 138, 209, - 209, 209, 19, 20, 23, 25, 26, 27, 28, 29, - 30, 31, 32, 40, 45, 46, 53, 55, 56, 57, - 68, 72, 73, 80, 85, 86, 87, 88, 89, 95, - 96, 102, 104, 105, 106, 107, 108, 112, 120, 121, - 122, 123, 124, 125, 126, 128, 141, 149, 151, 152, - 153, 154, 155, 156, 157, 158, 161, 163, 167, 169, - 175, 178, 180, 186, 190, 200, 205, 207, 213, 217, - 220, 221, 222, 226, 228, 230 ] + 4, 4, 36, 37, 36, 37, 26, 36, 37, 38, + 70, 38, 70, 27, 38, 164, 164, 164, 28, 172, + 164, 172, 29, 172, 172, 173, 81, 173, 81, 173, + 173, 174, 82, 174, 82, 174, 174, 179, 179, 179, + 30, 196, 179, 196, 31, 196, 196, 200, 109, 200, + 109, 200, 200, 201, 111, 201, 111, 201, 201, 75, + 114, 75, 114, 75, 114, 116, 137, 116, 137, 116, + 137, 166, 182, 166, 182, 166, 182, 117, 119, 117, + 119, 134, 138, 134, 138, 213, 213, 213, 32, 40, + 45, 46, 53, 55, 56, 57, 68, 72, 73, 80, + 85, 86, 87, 88, 89, 95, 96, 102, 104, 105, + 106, 107, 108, 112, 120, 121, 122, 123, 124, 125, + 126, 128, 141, 149, 151, 152, 153, 154, 155, 156, + 157, 158, 161, 163, 167, 169, 175, 178, 180, 183, + 188, 192, 202, 207, 209, 210, 220, 221, 222, 224, + 226, 228, 231, 232, 234, 236, 242, 245, 246, 248, + 249 ] racc_action_pointer = [ - nil, 20, 22, 26, 98, nil, nil, 39, nil, 33, - nil, nil, nil, nil, 48, 50, 90, 98, 99, 207, - 194, nil, nil, 195, nil, 196, 197, 198, 213, 214, - 215, 216, 217, 16, 22, 28, 35, 36, 44, -1, - 221, nil, 68, nil, nil, 201, 174, nil, nil, -5, - nil, nil, nil, 207, nil, 208, 209, 210, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 222, 70, - 78, nil, 225, 224, 153, 154, nil, nil, nil, nil, - 225, 84, 105, nil, nil, 226, 227, 228, 197, 234, - nil, nil, nil, nil, nil, 197, 235, nil, nil, nil, - nil, nil, 239, nil, 240, 241, 242, 243, 244, 136, - nil, 142, 240, nil, 159, nil, 160, 148, nil, 184, - 243, 207, 239, 249, 206, 201, 252, nil, 253, nil, - nil, nil, nil, nil, 202, nil, nil, 165, 203, -26, - nil, 210, nil, nil, -10, -2, nil, nil, nil, 237, - nil, 238, 239, 240, 241, 242, 255, 259, 220, 3, - nil, 220, nil, 227, 143, nil, 166, 248, nil, 249, - nil, nil, 71, 77, 83, 228, nil, nil, 225, 147, - 232, nil, 171, 4, 172, nil, 265, nil, nil, nil, - 272, nil, nil, nil, 135, nil, nil, nil, 141, 147, - 229, 9, nil, nil, 177, 274, nil, 237, 158, 161, - nil, nil, nil, 233, 159, nil, 178, 271, 183, nil, - 260, 273, 262, 160, nil, nil, 232, nil, 233, nil, - 277, nil, nil ] + nil, 24, 67, 37, 122, nil, nil, 34, nil, 57, + nil, nil, nil, nil, 45, 110, 45, 61, 80, 109, + 114, nil, nil, 122, nil, 123, 147, 154, 173, 177, + 195, 199, 243, 41, 103, 104, 159, 160, 166, 35, + 247, nil, 92, nil, nil, 227, 196, nil, nil, -5, + nil, nil, nil, 233, nil, 234, 235, 236, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 248, 129, + 167, nil, 251, 250, 95, 216, nil, nil, nil, nil, + 251, 183, 189, nil, nil, 252, 253, 254, 223, 260, + nil, nil, nil, nil, nil, 223, 261, nil, nil, nil, + nil, nil, 265, nil, 266, 267, 268, 269, 270, 205, + nil, 211, 266, nil, 217, nil, 222, 234, nil, 235, + 269, 233, 265, 275, 232, 223, 278, nil, 279, nil, + nil, nil, nil, nil, 238, nil, nil, 223, 239, -40, + nil, 236, nil, nil, -2, 20, nil, nil, nil, 263, + nil, 264, 265, 266, 267, 268, 281, 285, 246, 23, + nil, 246, nil, 253, 125, nil, 228, 274, nil, 275, + nil, nil, 176, 182, 188, 254, nil, nil, 251, 147, + 258, nil, 229, 259, nil, 29, 0, nil, 292, nil, + nil, nil, 299, nil, nil, nil, 198, nil, nil, nil, + 204, 210, 256, 26, nil, nil, 3, 301, nil, 299, + 265, -6, nil, 195, nil, nil, nil, nil, nil, nil, + 261, 266, 268, 53, 265, nil, 269, 6, 303, 9, + nil, 292, 305, 12, 270, 15, 295, nil, 6, nil, + nil, nil, 261, nil, 14, 273, 263, nil, 311, 276, + nil, nil ] racc_action_default = [ - -2, -138, -8, -138, -138, -3, -4, -138, 233, -138, - -9, -10, -11, -12, -138, -138, -138, -138, -138, -138, - -138, -24, -25, -138, -29, -138, -138, -138, -138, -138, - -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, - -138, -7, -123, -96, -98, -138, -120, -122, -13, -127, - -94, -95, -126, -15, -85, -16, -17, -138, -21, -26, + -2, -148, -8, -148, -148, -3, -4, -148, 252, -148, + -9, -10, -11, -12, -148, -148, -148, -148, -148, -148, + -148, -24, -25, -148, -29, -148, -148, -148, -148, -148, + -148, -148, -148, -148, -148, -148, -148, -148, -148, -148, + -148, -7, -133, -98, -100, -148, -130, -132, -13, -137, + -96, -97, -136, -15, -87, -16, -17, -148, -21, -26, -30, -33, -36, -39, -40, -41, -42, -43, -44, -50, - -138, -53, -71, -45, -75, -138, -78, -80, -81, -135, - -46, -88, -138, -91, -93, -47, -48, -49, -138, -138, - -5, -1, -97, -124, -99, -138, -138, -14, -128, -129, - -130, -82, -138, -18, -138, -138, -138, -138, -138, -138, - -54, -51, -73, -72, -138, -79, -76, -138, -92, -89, - -138, -138, -138, -138, -104, -138, -138, -86, -138, -22, - -27, -31, -34, -37, -52, -55, -74, -77, -90, -138, - -58, -62, -6, -125, -100, -101, -105, -121, -83, -138, - -19, -138, -138, -138, -138, -138, -136, -138, -57, -60, - -63, -104, -103, -94, -120, -109, -138, -138, -87, -138, - -23, -28, -138, -138, -138, -138, -137, -59, -62, -120, - -94, -67, -138, -102, -138, -106, -136, -113, -114, -115, - -138, -112, -84, -20, -32, -131, -133, -134, -35, -38, - -62, -61, -64, -65, -138, -138, -70, -94, -138, -116, - -107, -110, -132, -56, -138, -68, -138, -136, -138, -118, - -138, -136, -138, -138, -108, -117, -120, -66, -120, -119, - -136, -69, -111 ] + -148, -53, -73, -45, -77, -148, -80, -82, -83, -145, + -46, -90, -148, -93, -95, -47, -48, -49, -148, -148, + -5, -1, -99, -134, -101, -148, -148, -14, -138, -139, + -140, -84, -148, -18, -148, -148, -148, -148, -148, -148, + -54, -51, -75, -74, -148, -81, -78, -148, -94, -91, + -148, -148, -148, -148, -106, -148, -148, -88, -148, -22, + -27, -31, -34, -37, -52, -55, -76, -79, -92, -148, + -58, -62, -6, -135, -102, -103, -107, -131, -85, -148, + -19, -148, -148, -148, -148, -148, -146, -148, -57, -60, + -63, -106, -105, -96, -130, -111, -148, -148, -89, -148, + -23, -28, -148, -148, -148, -148, -147, -59, -62, -130, + -96, -67, -148, -148, -72, -104, -148, -108, -146, -115, + -116, -117, -148, -114, -86, -20, -32, -141, -143, -144, + -35, -38, -62, -61, -64, -65, -148, -148, -70, -148, + -96, -148, -122, -126, -127, -128, -129, -109, -112, -142, + -56, -148, -96, -118, -148, -68, -148, -148, -146, -148, + -124, -148, -146, -148, -120, -148, -148, -71, -148, -110, + -123, -126, -130, -66, -148, -119, -130, -125, -146, -121, + -69, -113 ] racc_goto_table = [ - 76, 95, 69, 52, 74, 158, 110, 175, 118, 119, - 145, 208, 1, 212, 186, 2, 43, 212, 212, 4, - 42, 72, 91, 84, 84, 84, 84, 5, 40, 203, - 122, 214, 80, 85, 86, 87, 10, 210, 11, 111, - 115, 76, 12, 223, 138, 116, 118, 183, 110, 92, - 53, 55, 56, 194, 198, 199, 13, 72, 72, 219, - 49, 97, 128, 169, 213, 118, 104, 151, 224, 84, - 84, 110, 227, 105, 152, 106, 153, 107, 134, 154, - 76, 232, 115, 108, 137, 155, 68, 73, 112, 135, - 139, 121, 201, 205, 222, 126, 167, 72, 102, 72, - 149, 144, 190, 115, 220, 84, 123, 84, nil, nil, - nil, 164, nil, nil, nil, nil, nil, nil, nil, 185, - nil, nil, 72, nil, nil, 179, 84, nil, nil, nil, - nil, nil, 191, nil, 202, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 206, 164, - 209, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 179, nil, nil, - 209, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, 230, 209, 231, 225 ] + 76, 175, 95, 52, 74, 69, 110, 158, 118, 211, + 145, 43, 240, 188, 119, 219, 1, 2, 240, 219, + 219, 72, 4, 84, 84, 84, 84, 42, 205, 224, + 53, 55, 56, 217, 80, 85, 86, 87, 91, 5, + 115, 76, 111, 40, 92, 116, 118, 185, 110, 138, + 238, 196, 200, 201, 122, 10, 244, 72, 72, 11, + 12, 13, 230, 49, 97, 118, 128, 169, 220, 84, + 84, 110, 234, 239, 104, 151, 105, 243, 152, 106, + 76, 134, 115, 153, 137, 107, 154, 108, 155, 68, + 73, 112, 135, 251, 139, 121, 203, 72, 221, 72, + 207, 236, 126, 115, 167, 84, 102, 84, 149, 144, + 192, 164, 231, 123, nil, nil, nil, nil, nil, nil, + 187, nil, 72, nil, nil, 179, 84, nil, nil, nil, + nil, nil, 193, nil, nil, 204, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 208, nil, + nil, 164, 213, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 179, + nil, nil, 223, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, 241, nil, nil, 248, 213, + nil, 245, 250 ] racc_goto_check = [ - 43, 44, 33, 35, 49, 40, 34, 39, 56, 55, - 60, 46, 1, 64, 45, 2, 57, 64, 64, 3, - 4, 35, 5, 35, 35, 35, 35, 6, 7, 45, - 8, 46, 32, 32, 32, 32, 9, 39, 10, 33, - 43, 43, 11, 46, 55, 49, 56, 60, 34, 57, - 15, 15, 15, 21, 21, 21, 12, 35, 35, 45, - 13, 14, 16, 17, 40, 56, 18, 19, 39, 35, - 35, 34, 39, 22, 23, 24, 25, 26, 33, 27, - 43, 39, 43, 28, 49, 29, 30, 31, 36, 37, - 38, 41, 42, 47, 48, 51, 52, 35, 53, 35, - 54, 59, 61, 43, 62, 35, 63, 35, nil, nil, - nil, 43, nil, nil, nil, nil, nil, nil, nil, 44, - nil, nil, 35, nil, nil, 43, 35, nil, nil, nil, - nil, nil, 43, nil, 44, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 43, 43, - 43, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 43, nil, nil, - 43, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, 44, 43, 44, 43 ] + 43, 39, 44, 35, 49, 33, 34, 40, 56, 61, + 60, 57, 64, 45, 55, 67, 1, 2, 64, 67, + 67, 35, 3, 35, 35, 35, 35, 4, 45, 61, + 15, 15, 15, 39, 32, 32, 32, 32, 5, 6, + 43, 43, 33, 7, 57, 49, 56, 60, 34, 55, + 61, 21, 21, 21, 8, 9, 61, 35, 35, 10, + 11, 12, 45, 13, 14, 56, 16, 17, 40, 35, + 35, 34, 45, 39, 18, 19, 22, 39, 23, 24, + 43, 33, 43, 25, 49, 26, 27, 28, 29, 30, + 31, 36, 37, 39, 38, 41, 42, 35, 46, 35, + 47, 48, 51, 43, 52, 35, 53, 35, 54, 59, + 62, 43, 63, 66, nil, nil, nil, nil, nil, nil, + 44, nil, 35, nil, nil, 43, 35, nil, nil, nil, + nil, nil, 43, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 43, nil, + nil, 43, 43, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 43, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 43, nil, 43, nil, nil, 44, 43, + nil, 43, 44 ] racc_goto_pointer = [ - nil, 12, 15, 17, 11, -20, 25, 22, -60, 32, - 34, 38, 52, 45, 12, 34, -41, -87, 8, -62, - nil, -119, 14, -56, 15, -55, 16, -53, 21, -48, - 53, 53, -3, -31, -63, -12, 16, -23, -30, -149, - -136, 2, -86, -34, -45, -150, -173, -88, -121, -30, - nil, -6, -52, 44, -27, -73, -73, 7, nil, -23, - -114, -63, -107, 13, -181 ] + nil, 16, 17, 20, 18, -4, 37, 37, -36, 51, + 55, 56, 57, 48, 15, 14, -37, -83, 16, -54, + nil, -121, 17, -52, 19, -48, 24, -46, 25, -45, + 56, 56, -1, -28, -63, -12, 19, -20, -26, -155, + -134, 6, -82, -34, -44, -151, -108, -81, -124, -30, + nil, 1, -44, 52, -19, -68, -73, 2, nil, -15, + -114, -177, -55, -106, -217, nil, 20, -181 ] racc_goto_default = [ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 71, 77, nil, nil, nil, nil, - nil, 46, 159, 196, nil, nil, nil, nil, nil, nil, + nil, 46, 159, 198, nil, nil, nil, nil, nil, nil, 78, nil, nil, nil, nil, 81, 83, nil, 44, nil, - nil, nil, nil, nil, 195 ] + nil, nil, nil, nil, 212, 214, nil, 197 ] racc_reduce_table = [ 0, 0, :racc_error, - 5, 55, :_reduce_none, - 0, 56, :_reduce_none, - 2, 56, :_reduce_none, - 0, 61, :_reduce_4, - 0, 62, :_reduce_5, - 5, 60, :_reduce_6, + 5, 59, :_reduce_none, + 0, 60, :_reduce_none, 2, 60, :_reduce_none, - 0, 57, :_reduce_8, - 2, 57, :_reduce_none, - 1, 63, :_reduce_none, - 1, 63, :_reduce_none, - 1, 63, :_reduce_none, - 2, 63, :_reduce_13, - 3, 63, :_reduce_none, - 2, 63, :_reduce_none, - 2, 63, :_reduce_16, - 2, 63, :_reduce_17, - 0, 70, :_reduce_18, - 0, 71, :_reduce_19, - 7, 63, :_reduce_20, - 0, 72, :_reduce_21, - 0, 73, :_reduce_22, - 6, 63, :_reduce_23, - 1, 63, :_reduce_24, - 1, 63, :_reduce_none, - 0, 76, :_reduce_26, - 0, 77, :_reduce_27, - 6, 64, :_reduce_28, - 1, 64, :_reduce_none, - 0, 78, :_reduce_30, - 0, 79, :_reduce_31, - 7, 64, :_reduce_32, - 0, 80, :_reduce_33, - 0, 81, :_reduce_34, - 7, 64, :_reduce_35, - 0, 82, :_reduce_36, - 0, 83, :_reduce_37, - 7, 64, :_reduce_38, - 2, 64, :_reduce_39, - 2, 64, :_reduce_40, - 2, 64, :_reduce_41, - 2, 64, :_reduce_42, - 2, 64, :_reduce_43, - 2, 74, :_reduce_none, - 2, 74, :_reduce_45, - 2, 74, :_reduce_46, - 2, 74, :_reduce_47, - 2, 74, :_reduce_48, - 2, 74, :_reduce_49, - 1, 84, :_reduce_50, - 2, 84, :_reduce_51, - 3, 84, :_reduce_52, - 1, 87, :_reduce_53, - 2, 87, :_reduce_54, - 3, 88, :_reduce_55, - 8, 65, :_reduce_56, - 5, 66, :_reduce_57, - 1, 92, :_reduce_58, - 3, 92, :_reduce_59, - 1, 94, :_reduce_60, - 3, 94, :_reduce_61, - 0, 96, :_reduce_62, - 1, 96, :_reduce_63, - 3, 96, :_reduce_64, - 3, 96, :_reduce_65, - 6, 96, :_reduce_66, - 0, 101, :_reduce_67, - 0, 102, :_reduce_68, - 7, 96, :_reduce_69, - 3, 96, :_reduce_70, - 0, 90, :_reduce_none, - 1, 90, :_reduce_none, - 0, 91, :_reduce_none, - 1, 91, :_reduce_none, - 1, 85, :_reduce_75, - 2, 85, :_reduce_76, - 3, 85, :_reduce_77, - 1, 103, :_reduce_78, - 2, 103, :_reduce_79, - 1, 97, :_reduce_none, - 1, 97, :_reduce_none, - 0, 105, :_reduce_82, - 0, 106, :_reduce_83, - 6, 69, :_reduce_84, - 0, 107, :_reduce_85, - 0, 108, :_reduce_86, - 5, 69, :_reduce_87, - 1, 86, :_reduce_88, - 2, 86, :_reduce_89, - 3, 86, :_reduce_90, - 1, 109, :_reduce_91, - 2, 109, :_reduce_92, - 1, 110, :_reduce_none, - 1, 89, :_reduce_94, - 1, 89, :_reduce_95, - 1, 58, :_reduce_none, - 2, 58, :_reduce_none, - 1, 111, :_reduce_none, - 2, 111, :_reduce_none, - 4, 112, :_reduce_100, - 1, 113, :_reduce_101, - 3, 113, :_reduce_102, - 2, 113, :_reduce_none, - 0, 114, :_reduce_104, - 1, 114, :_reduce_105, - 3, 114, :_reduce_106, - 4, 114, :_reduce_107, - 6, 114, :_reduce_108, - 0, 115, :_reduce_109, - 0, 116, :_reduce_110, - 8, 114, :_reduce_111, - 3, 114, :_reduce_112, - 1, 99, :_reduce_113, - 1, 99, :_reduce_114, - 1, 99, :_reduce_115, - 1, 100, :_reduce_116, - 3, 100, :_reduce_117, - 2, 100, :_reduce_118, - 4, 100, :_reduce_119, - 0, 98, :_reduce_none, - 3, 98, :_reduce_121, - 1, 95, :_reduce_none, - 0, 59, :_reduce_none, - 0, 117, :_reduce_124, - 3, 59, :_reduce_125, + 0, 65, :_reduce_4, + 0, 66, :_reduce_5, + 5, 64, :_reduce_6, + 2, 64, :_reduce_none, + 0, 61, :_reduce_8, + 2, 61, :_reduce_none, 1, 67, :_reduce_none, - 0, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, + 1, 67, :_reduce_none, + 1, 67, :_reduce_none, + 2, 67, :_reduce_13, + 3, 67, :_reduce_none, + 2, 67, :_reduce_none, + 2, 67, :_reduce_16, + 2, 67, :_reduce_17, + 0, 74, :_reduce_18, + 0, 75, :_reduce_19, + 7, 67, :_reduce_20, + 0, 76, :_reduce_21, + 0, 77, :_reduce_22, + 6, 67, :_reduce_23, + 1, 67, :_reduce_24, + 1, 67, :_reduce_none, + 0, 80, :_reduce_26, + 0, 81, :_reduce_27, + 6, 68, :_reduce_28, 1, 68, :_reduce_none, - 1, 75, :_reduce_131, - 2, 75, :_reduce_132, - 1, 118, :_reduce_none, - 1, 118, :_reduce_none, - 1, 104, :_reduce_135, - 0, 93, :_reduce_none, - 1, 93, :_reduce_none ] - -racc_reduce_n = 138 - -racc_shift_n = 233 + 0, 82, :_reduce_30, + 0, 83, :_reduce_31, + 7, 68, :_reduce_32, + 0, 84, :_reduce_33, + 0, 85, :_reduce_34, + 7, 68, :_reduce_35, + 0, 86, :_reduce_36, + 0, 87, :_reduce_37, + 7, 68, :_reduce_38, + 2, 68, :_reduce_39, + 2, 68, :_reduce_40, + 2, 68, :_reduce_41, + 2, 68, :_reduce_42, + 2, 68, :_reduce_43, + 2, 78, :_reduce_none, + 2, 78, :_reduce_45, + 2, 78, :_reduce_46, + 2, 78, :_reduce_47, + 2, 78, :_reduce_48, + 2, 78, :_reduce_49, + 1, 88, :_reduce_50, + 2, 88, :_reduce_51, + 3, 88, :_reduce_52, + 1, 91, :_reduce_53, + 2, 91, :_reduce_54, + 3, 92, :_reduce_55, + 8, 69, :_reduce_56, + 5, 70, :_reduce_57, + 1, 96, :_reduce_58, + 3, 96, :_reduce_59, + 1, 98, :_reduce_60, + 3, 98, :_reduce_61, + 0, 100, :_reduce_62, + 1, 100, :_reduce_63, + 3, 100, :_reduce_64, + 3, 100, :_reduce_65, + 6, 100, :_reduce_66, + 0, 105, :_reduce_67, + 0, 106, :_reduce_68, + 7, 100, :_reduce_69, + 3, 100, :_reduce_70, + 5, 100, :_reduce_71, + 2, 100, :_reduce_72, + 0, 94, :_reduce_none, + 1, 94, :_reduce_none, + 0, 95, :_reduce_none, + 1, 95, :_reduce_none, + 1, 89, :_reduce_77, + 2, 89, :_reduce_78, + 3, 89, :_reduce_79, + 1, 107, :_reduce_80, + 2, 107, :_reduce_81, + 1, 101, :_reduce_none, + 1, 101, :_reduce_none, + 0, 109, :_reduce_84, + 0, 110, :_reduce_85, + 6, 73, :_reduce_86, + 0, 111, :_reduce_87, + 0, 112, :_reduce_88, + 5, 73, :_reduce_89, + 1, 90, :_reduce_90, + 2, 90, :_reduce_91, + 3, 90, :_reduce_92, + 1, 113, :_reduce_93, + 2, 113, :_reduce_94, + 1, 114, :_reduce_none, + 1, 93, :_reduce_96, + 1, 93, :_reduce_97, + 1, 62, :_reduce_none, + 2, 62, :_reduce_none, + 1, 115, :_reduce_none, + 2, 115, :_reduce_none, + 4, 116, :_reduce_102, + 1, 117, :_reduce_103, + 3, 117, :_reduce_104, + 2, 117, :_reduce_none, + 0, 118, :_reduce_106, + 1, 118, :_reduce_107, + 3, 118, :_reduce_108, + 4, 118, :_reduce_109, + 6, 118, :_reduce_110, + 0, 120, :_reduce_111, + 0, 121, :_reduce_112, + 8, 118, :_reduce_113, + 3, 118, :_reduce_114, + 1, 103, :_reduce_115, + 1, 103, :_reduce_116, + 1, 103, :_reduce_117, + 1, 104, :_reduce_118, + 3, 104, :_reduce_119, + 2, 104, :_reduce_120, + 4, 104, :_reduce_121, + 1, 119, :_reduce_122, + 3, 119, :_reduce_123, + 2, 119, :_reduce_124, + 4, 119, :_reduce_125, + 1, 122, :_reduce_none, + 1, 122, :_reduce_none, + 1, 123, :_reduce_128, + 1, 123, :_reduce_129, + 0, 102, :_reduce_none, + 3, 102, :_reduce_131, + 1, 99, :_reduce_none, + 0, 63, :_reduce_none, + 0, 124, :_reduce_134, + 3, 63, :_reduce_135, + 1, 71, :_reduce_none, + 0, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 72, :_reduce_none, + 1, 79, :_reduce_141, + 2, 79, :_reduce_142, + 1, 125, :_reduce_none, + 1, 125, :_reduce_none, + 1, 108, :_reduce_145, + 0, 97, :_reduce_none, + 1, 97, :_reduce_none ] + +racc_reduce_n = 148 + +racc_shift_n = 252 racc_token_table = { false => 0, @@ -1098,14 +1124,18 @@ def raise_parse_error(error_message, location) "|" => 45, "%empty" => 46, "%prec" => 47, - "?" => 48, - "+" => 49, - "*" => 50, - "[" => 51, - "]" => 52, - "{...}" => 53 } - -racc_nt_base = 54 + "%if" => 48, + "%endif" => 49, + "?" => 50, + "+" => 51, + "*" => 52, + "%true" => 53, + "%false" => 54, + "[" => 55, + "]" => 56, + "{...}" => 57 } + +racc_nt_base = 58 racc_use_result_var = true @@ -1175,9 +1205,13 @@ def raise_parse_error(error_message, location) "\"|\"", "\"%empty\"", "\"%prec\"", + "\"%if\"", + "\"%endif\"", "\"?\"", "\"+\"", "\"*\"", + "\"%true\"", + "\"%false\"", "\"[\"", "\"]\"", "\"{...}\"", @@ -1227,7 +1261,7 @@ def raise_parse_error(error_message, location) "symbol", "named_ref_opt", "parameterizing_suffix", - "parameterizing_args", + "parameterizing_rule_args", "@15", "@16", "symbol_declaration_list", @@ -1242,8 +1276,11 @@ def raise_parse_error(error_message, location) "rules", "rhs_list", "rhs", + "parameterizing_args", "@21", "@22", + "symbol_or_bool", + "bool", "@23", "generic_symlist_item" ] Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) @@ -1677,26 +1714,27 @@ def _reduce_56(val, _values, result) def _reduce_57(val, _values, result) rule = Grammar::ParameterizingRule::Rule.new(val[2].s_value, [], val[4], is_inline: true) @grammar.add_parameterizing_rule(rule) + @grammar.initialize_if_count result end .,., -module_eval(<<'.,.,', 'parser.y', 246) +module_eval(<<'.,.,', 'parser.y', 247) def _reduce_58(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 247) +module_eval(<<'.,.,', 'parser.y', 248) def _reduce_59(val, _values, result) result = val[0].append(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 251) +module_eval(<<'.,.,', 'parser.y', 252) def _reduce_60(val, _values, result) builder = val[0] result = [builder] @@ -1705,7 +1743,7 @@ def _reduce_60(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 256) +module_eval(<<'.,.,', 'parser.y', 257) def _reduce_61(val, _values, result) builder = val[2] result = val[0].append(builder) @@ -1714,7 +1752,7 @@ def _reduce_61(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 262) +module_eval(<<'.,.,', 'parser.y', 263) def _reduce_62(val, _values, result) reset_precs result = Grammar::ParameterizingRule::Rhs.new @@ -1723,7 +1761,7 @@ def _reduce_62(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 267) +module_eval(<<'.,.,', 'parser.y', 268) def _reduce_63(val, _values, result) reset_precs result = Grammar::ParameterizingRule::Rhs.new @@ -1732,7 +1770,7 @@ def _reduce_63(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 272) +module_eval(<<'.,.,', 'parser.y', 273) def _reduce_64(val, _values, result) token = val[1] token.alias_name = val[2] @@ -1744,7 +1782,7 @@ def _reduce_64(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 280) +module_eval(<<'.,.,', 'parser.y', 281) def _reduce_65(val, _values, result) builder = val[0] builder.symbols << Lrama::Lexer::Token::InstantiateRule.new(s_value: val[2], location: @lexer.location, args: [val[1]]) @@ -1754,7 +1792,7 @@ def _reduce_65(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 286) +module_eval(<<'.,.,', 'parser.y', 287) def _reduce_66(val, _values, result) builder = val[0] builder.symbols << Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[3], lhs_tag: val[5]) @@ -1764,7 +1802,7 @@ def _reduce_66(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 292) +module_eval(<<'.,.,', 'parser.y', 293) def _reduce_67(val, _values, result) if @prec_seen on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec @@ -1776,7 +1814,7 @@ def _reduce_67(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 300) +module_eval(<<'.,.,', 'parser.y', 301) def _reduce_68(val, _values, result) end_c_declaration @@ -1784,7 +1822,7 @@ def _reduce_68(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 304) +module_eval(<<'.,.,', 'parser.y', 305) def _reduce_69(val, _values, result) user_code = val[3] user_code.alias_name = val[6] @@ -1796,7 +1834,7 @@ def _reduce_69(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 312) +module_eval(<<'.,.,', 'parser.y', 313) def _reduce_70(val, _values, result) sym = @grammar.find_symbol_by_id!(val[2]) @prec_seen = true @@ -1808,168 +1846,191 @@ def _reduce_70(val, _values, result) end .,., -# reduce 71 omitted +module_eval(<<'.,.,', 'parser.y', 321) + def _reduce_71(val, _values, result) + builder = val[0] + builder.symbols << Lrama::Lexer::Token::ControlSyntax.new(s_value: val[1], location: @lexer.location, condition: val[3]) + @grammar.if_count += 1 + result = builder -# reduce 72 omitted + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 328) + def _reduce_72(val, _values, result) + on_action_error("no %if before %endif", val[0]) if @grammar.if_count == 0 + builder = val[0] + builder.symbols << Lrama::Lexer::Token::ControlSyntax.new(s_value: val[1], location: @lexer.location) + @grammar.if_count -= 1 + result = builder + + result + end +.,., # reduce 73 omitted # reduce 74 omitted -module_eval(<<'.,.,', 'parser.y', 327) - def _reduce_75(val, _values, result) +# reduce 75 omitted + +# reduce 76 omitted + +module_eval(<<'.,.,', 'parser.y', 343) + def _reduce_77(val, _values, result) result = [{tag: nil, tokens: val[0]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 331) - def _reduce_76(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 347) + def _reduce_78(val, _values, result) result = [{tag: val[0], tokens: val[1]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 335) - def _reduce_77(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 351) + def _reduce_79(val, _values, result) result = val[0].append({tag: val[1], tokens: val[2]}) result end .,., -module_eval(<<'.,.,', 'parser.y', 338) - def _reduce_78(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 354) + def _reduce_80(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 339) - def _reduce_79(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 355) + def _reduce_81(val, _values, result) result = val[0].append(val[1]) result end .,., -# reduce 80 omitted +# reduce 82 omitted -# reduce 81 omitted +# reduce 83 omitted -module_eval(<<'.,.,', 'parser.y', 346) - def _reduce_82(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 362) + def _reduce_84(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 350) - def _reduce_83(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 366) + def _reduce_85(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 354) - def _reduce_84(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 370) + def _reduce_86(val, _values, result) result = val[0].append(val[3]) result end .,., -module_eval(<<'.,.,', 'parser.y', 358) - def _reduce_85(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 374) + def _reduce_87(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 362) - def _reduce_86(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 378) + def _reduce_88(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 366) - def _reduce_87(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 382) + def _reduce_89(val, _values, result) result = [val[2]] result end .,., -module_eval(<<'.,.,', 'parser.y', 371) - def _reduce_88(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 387) + def _reduce_90(val, _values, result) result = [{tag: nil, tokens: val[0]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 375) - def _reduce_89(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 391) + def _reduce_91(val, _values, result) result = [{tag: val[0], tokens: val[1]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 379) - def _reduce_90(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 395) + def _reduce_92(val, _values, result) result = val[0].append({tag: val[1], tokens: val[2]}) result end .,., -module_eval(<<'.,.,', 'parser.y', 382) - def _reduce_91(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 398) + def _reduce_93(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 383) - def _reduce_92(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 399) + def _reduce_94(val, _values, result) result = val[0].append(val[1]) result end .,., -# reduce 93 omitted +# reduce 95 omitted -module_eval(<<'.,.,', 'parser.y', 387) - def _reduce_94(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 403) + def _reduce_96(val, _values, result) on_action_error("ident after %prec", val[0]) if @prec_seen result end .,., -module_eval(<<'.,.,', 'parser.y', 388) - def _reduce_95(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 404) + def _reduce_97(val, _values, result) on_action_error("char after %prec", val[0]) if @prec_seen result end .,., -# reduce 96 omitted - -# reduce 97 omitted - # reduce 98 omitted # reduce 99 omitted -module_eval(<<'.,.,', 'parser.y', 398) - def _reduce_100(val, _values, result) +# reduce 100 omitted + +# reduce 101 omitted + +module_eval(<<'.,.,', 'parser.y', 414) + def _reduce_102(val, _values, result) lhs = val[0] lhs.alias_name = val[1] val[3].each do |builder| @@ -1982,8 +2043,8 @@ def _reduce_100(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 409) - def _reduce_101(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 425) + def _reduce_103(val, _values, result) builder = val[0] if !builder.line builder.line = @lexer.line - 1 @@ -1994,8 +2055,8 @@ def _reduce_101(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 417) - def _reduce_102(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 433) + def _reduce_104(val, _values, result) builder = val[2] if !builder.line builder.line = @lexer.line - 1 @@ -2006,10 +2067,10 @@ def _reduce_102(val, _values, result) end .,., -# reduce 103 omitted +# reduce 105 omitted -module_eval(<<'.,.,', 'parser.y', 427) - def _reduce_104(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 443) + def _reduce_106(val, _values, result) reset_precs result = @grammar.create_rule_builder(@rule_counter, @midrule_action_counter) @@ -2017,8 +2078,8 @@ def _reduce_104(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 432) - def _reduce_105(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 448) + def _reduce_107(val, _values, result) reset_precs result = @grammar.create_rule_builder(@rule_counter, @midrule_action_counter) @@ -2026,8 +2087,8 @@ def _reduce_105(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 437) - def _reduce_106(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 453) + def _reduce_108(val, _values, result) token = val[1] token.alias_name = val[2] builder = val[0] @@ -2038,8 +2099,8 @@ def _reduce_106(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 445) - def _reduce_107(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 461) + def _reduce_109(val, _values, result) token = Lrama::Lexer::Token::InstantiateRule.new(s_value: val[2], location: @lexer.location, args: [val[1]], lhs_tag: val[3]) builder = val[0] builder.add_rhs(token) @@ -2050,8 +2111,8 @@ def _reduce_107(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 453) - def _reduce_108(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 469) + def _reduce_110(val, _values, result) token = Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[3], lhs_tag: val[5]) builder = val[0] builder.add_rhs(token) @@ -2062,8 +2123,8 @@ def _reduce_108(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 461) - def _reduce_109(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 477) + def _reduce_111(val, _values, result) if @prec_seen on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec @code_after_prec = true @@ -2074,16 +2135,16 @@ def _reduce_109(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 469) - def _reduce_110(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 485) + def _reduce_112(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 473) - def _reduce_111(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 489) + def _reduce_113(val, _values, result) user_code = val[3] user_code.alias_name = val[6] user_code.tag = val[7] @@ -2095,8 +2156,8 @@ def _reduce_111(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 482) - def _reduce_112(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 498) + def _reduce_114(val, _values, result) sym = @grammar.find_symbol_by_id!(val[2]) @prec_seen = true builder = val[0] @@ -2107,70 +2168,116 @@ def _reduce_112(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 489) - def _reduce_113(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 505) + def _reduce_115(val, _values, result) result = "option" result end .,., -module_eval(<<'.,.,', 'parser.y', 490) - def _reduce_114(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 506) + def _reduce_116(val, _values, result) result = "nonempty_list" result end .,., -module_eval(<<'.,.,', 'parser.y', 491) - def _reduce_115(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 507) + def _reduce_117(val, _values, result) result = "list" result end .,., -module_eval(<<'.,.,', 'parser.y', 493) - def _reduce_116(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 509) + def _reduce_118(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 494) - def _reduce_117(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 510) + def _reduce_119(val, _values, result) result = val[0].append(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 495) - def _reduce_118(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 511) + def _reduce_120(val, _values, result) result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[0])] result end .,., -module_eval(<<'.,.,', 'parser.y', 496) - def _reduce_119(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 512) + def _reduce_121(val, _values, result) result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[0].s_value, location: @lexer.location, args: val[2])] result end .,., -# reduce 120 omitted +module_eval(<<'.,.,', 'parser.y', 514) + def _reduce_122(val, _values, result) + result = [val[0]] + result + end +.,., -module_eval(<<'.,.,', 'parser.y', 499) - def _reduce_121(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 515) + def _reduce_123(val, _values, result) + result = val[0].append(val[2]) + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 516) + def _reduce_124(val, _values, result) + result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[0])] + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 517) + def _reduce_125(val, _values, result) + result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[0].s_value, location: @lexer.location, args: val[2])] + result + end +.,., + +# reduce 126 omitted + +# reduce 127 omitted + +module_eval(<<'.,.,', 'parser.y', 522) + def _reduce_128(val, _values, result) + result = Lrama::Lexer::Token::Ident.new(s_value: true) + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 523) + def _reduce_129(val, _values, result) + result = Lrama::Lexer::Token::Ident.new(s_value: false) + result + end +.,., + +# reduce 130 omitted + +module_eval(<<'.,.,', 'parser.y', 526) + def _reduce_131(val, _values, result) result = val[1].s_value result end .,., -# reduce 122 omitted +# reduce 132 omitted -# reduce 123 omitted +# reduce 133 omitted -module_eval(<<'.,.,', 'parser.y', 506) - def _reduce_124(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 533) + def _reduce_134(val, _values, result) begin_c_declaration('\Z') @grammar.epilogue_first_lineno = @lexer.line + 1 @@ -2178,8 +2285,8 @@ def _reduce_124(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 511) - def _reduce_125(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 538) + def _reduce_135(val, _values, result) end_c_declaration @grammar.epilogue = val[2].s_value @@ -2187,44 +2294,44 @@ def _reduce_125(val, _values, result) end .,., -# reduce 126 omitted +# reduce 136 omitted -# reduce 127 omitted +# reduce 137 omitted -# reduce 128 omitted +# reduce 138 omitted -# reduce 129 omitted +# reduce 139 omitted -# reduce 130 omitted +# reduce 140 omitted -module_eval(<<'.,.,', 'parser.y', 522) - def _reduce_131(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 549) + def _reduce_141(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 523) - def _reduce_132(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 550) + def _reduce_142(val, _values, result) result = val[0].append(val[1]) result end .,., -# reduce 133 omitted +# reduce 143 omitted -# reduce 134 omitted +# reduce 144 omitted -module_eval(<<'.,.,', 'parser.y', 528) - def _reduce_135(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 555) + def _reduce_145(val, _values, result) result = Lrama::Lexer::Token::Ident.new(s_value: val[0]) result end .,., -# reduce 136 omitted +# reduce 146 omitted -# reduce 137 omitted +# reduce 147 omitted def _reduce_none(val, _values, result) val[0] diff --git a/parser.y b/parser.y index 59bc00af..25e7f646 100644 --- a/parser.y +++ b/parser.y @@ -242,6 +242,7 @@ rule { rule = Grammar::ParameterizingRule::Rule.new(val[2].s_value, [], val[4], is_inline: true) @grammar.add_parameterizing_rule(rule) + @grammar.initialize_if_count } rule_args: IDENTIFIER { result = [val[0]] } @@ -282,7 +283,7 @@ rule builder.symbols << Lrama::Lexer::Token::InstantiateRule.new(s_value: val[2], location: @lexer.location, args: [val[1]]) result = builder } - | rule_rhs IDENTIFIER "(" parameterizing_args ")" tag_opt + | rule_rhs IDENTIFIER "(" parameterizing_rule_args ")" tag_opt { builder = val[0] builder.symbols << Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[3], lhs_tag: val[5]) @@ -316,6 +317,21 @@ rule builder.precedence_sym = sym result = builder } + | rule_rhs "%if" "(" IDENTIFIER ")" + { + builder = val[0] + builder.symbols << Lrama::Lexer::Token::ControlSyntax.new(s_value: val[1], location: @lexer.location, condition: val[3]) + @grammar.if_count += 1 + result = builder + } + | rule_rhs "%endif" + { + on_action_error("no %if before %endif", val[0]) if @grammar.if_count == 0 + builder = val[0] + builder.symbols << Lrama::Lexer::Token::ControlSyntax.new(s_value: val[1], location: @lexer.location) + @grammar.if_count -= 1 + result = builder + } int_opt: # empty | INTEGER @@ -491,11 +507,22 @@ rule | "+" { result = "nonempty_list" } | "*" { result = "list" } - parameterizing_args: symbol { result = [val[0]] } - | parameterizing_args ',' symbol { result = val[0].append(val[2]) } + parameterizing_rule_args: symbol { result = [val[0]] } + | parameterizing_args ',' symbol { result = val[0].append(val[2]) } + | symbol parameterizing_suffix { result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[0])] } + | IDENTIFIER "(" parameterizing_args ")" { result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[0].s_value, location: @lexer.location, args: val[2])] } + + parameterizing_args: symbol_or_bool { result = [val[0]] } + | parameterizing_args ',' symbol_or_bool { result = val[0].append(val[2]) } | symbol parameterizing_suffix { result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[0])] } | IDENTIFIER "(" parameterizing_args ")" { result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[0].s_value, location: @lexer.location, args: val[2])] } + symbol_or_bool: symbol + | bool + + bool: "%true" { result = Lrama::Lexer::Token::Ident.new(s_value: true) } + | "%false" { result = Lrama::Lexer::Token::Ident.new(s_value: false) } + named_ref_opt: # empty | '[' IDENTIFIER ']' { result = val[1].s_value } diff --git a/sig/lrama/grammar/parameterizing_rule/rhs.rbs b/sig/lrama/grammar/parameterizing_rule/rhs.rbs index a9da56e3..3d2f0758 100644 --- a/sig/lrama/grammar/parameterizing_rule/rhs.rbs +++ b/sig/lrama/grammar/parameterizing_rule/rhs.rbs @@ -7,6 +7,8 @@ module Lrama attr_reader precedence_sym: Lexer::Token? def initialize: () -> void + def skip?: (Grammar::Binding bindings) -> bool + def resolve_symbols: (Grammar::Binding bindings) -> Array[untyped] def resolve_user_code: (Grammar::Binding bindings) -> Lexer::Token::UserCode? end end diff --git a/sig/lrama/lexer/token/control_syntax.rbs b/sig/lrama/lexer/token/control_syntax.rbs new file mode 100644 index 00000000..9701c685 --- /dev/null +++ b/sig/lrama/lexer/token/control_syntax.rbs @@ -0,0 +1,16 @@ +module Lrama + class Lexer + class Token + class ControlSyntax < Token + attr_accessor condition: Lexer::Token::Ident? + + def initialize: (s_value: String, location: Location, ?condition: Lexer::Token::Ident?) -> void + def if?: () -> bool + def endif?: () -> bool + def true?: () -> bool + def false?: () -> bool + def condition_value: () -> String? + end + end + end +end diff --git a/spec/fixtures/parameterizing_rules/user_defined/if.y b/spec/fixtures/parameterizing_rules/user_defined/if.y new file mode 100644 index 00000000..97c6de2a --- /dev/null +++ b/spec/fixtures/parameterizing_rules/user_defined/if.y @@ -0,0 +1,44 @@ +/* + * This is comment for this file. + */ + +%{ +// Prologue +static int yylex(YYSTYPE *val, YYLTYPE *loc); +static int yyerror(YYLTYPE *loc, const char *str); +%} + +%union { + int i; +} + +%token number + +%rule defined_rule(X, condition): /* empty */ + | X { $$ = $1; } %if(condition) + | %if(condition) X %endif X { $$ = $1; } + ; + +%% + +r_true : defined_rule(number, %true) + ; + +r_false : defined_rule(number, %false) + ; + +%% + +static int yylex(YYSTYPE *yylval, YYLTYPE *loc) +{ + return 0; +} + +static int yyerror(YYLTYPE *loc, const char *str) +{ + return 0; +} + +int main(int argc, char *argv[]) +{ +} diff --git a/spec/lrama/parser_spec.rb b/spec/lrama/parser_spec.rb index 2fddc68b..b50bd6f5 100644 --- a/spec/lrama/parser_spec.rb +++ b/spec/lrama/parser_spec.rb @@ -2278,6 +2278,109 @@ ]) end end + + context "when if" do + let(:path) { "parameterizing_rules/user_defined/if.y" } + + it "expands parameterizing rules" do + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ + Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 4, tag: nil, term: false, token_id: 0, nullable: false), + Sym.new(id: T::Ident.new(s_value: "defined_rule_number_true"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 1, nullable: true), + Sym.new(id: T::Ident.new(s_value: "r_true"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 2, nullable: true), + Sym.new(id: T::Ident.new(s_value: "defined_rule_number_false"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 3, nullable: true), + Sym.new(id: T::Ident.new(s_value: "r_false"), alias_name: nil, number: 8, tag: nil, term: false, token_id: 4, nullable: true), + ]) + + expect(grammar.rules).to eq([ + Rule.new( + id: 0, + lhs: grammar.find_symbol_by_s_value!("$accept"), + rhs: [ + grammar.find_symbol_by_s_value!("r_true"), + grammar.find_symbol_by_s_value!("YYEOF"), + ], + token_code: nil, + nullable: false, + precedence_sym: grammar.find_symbol_by_s_value!("YYEOF"), + lineno: 24, + ), + Rule.new( + id: 1, + lhs: grammar.find_symbol_by_s_value!("defined_rule_number_true"), + rhs: [], + token_code: nil, + nullable: true, + precedence_sym: nil, + lineno: 24, + ), + Rule.new( + id: 2, + lhs: grammar.find_symbol_by_s_value!("defined_rule_number_true"), + rhs: [ + grammar.find_symbol_by_s_value!("number"), + ], + token_code: T::UserCode.new(s_value: " $$ = $1; "), + nullable: false, + precedence_sym: grammar.find_symbol_by_s_value!("number"), + lineno: 24, + ), + Rule.new( + id: 3, + lhs: grammar.find_symbol_by_s_value!("defined_rule_number_true"), + rhs: [ + grammar.find_symbol_by_s_value!("number"), + grammar.find_symbol_by_s_value!("number"), + ], + token_code: T::UserCode.new(s_value: " $$ = $1; "), + nullable: false, + precedence_sym: grammar.find_symbol_by_s_value!("number"), + lineno: 24, + ), + Rule.new( + id: 4, + lhs: grammar.find_symbol_by_s_value!("r_true"), + rhs: [ + grammar.find_symbol_by_s_value!("defined_rule_number_true"), + ], + token_code: nil, + nullable: true, + precedence_sym: nil, + lineno: 24, + ), + Rule.new( + id: 5, + lhs: grammar.find_symbol_by_s_value!("defined_rule_number_false"), + rhs: [], + token_code: nil, + nullable: true, + precedence_sym: nil, + lineno: 27, + ), + Rule.new( + id: 6, + lhs: grammar.find_symbol_by_s_value!("defined_rule_number_false"), + rhs: [ + grammar.find_symbol_by_s_value!("number"), + ], + token_code: T::UserCode.new(s_value: " $$ = $1; "), + nullable: false, + precedence_sym: grammar.find_symbol_by_s_value!("number"), + lineno: 27, + ), + Rule.new( + id: 7, + lhs: grammar.find_symbol_by_s_value!("r_false"), + rhs: [ + grammar.find_symbol_by_s_value!("defined_rule_number_false"), + ], + token_code: nil, + nullable: true, + precedence_sym: nil, + lineno: 27, + ), + ]) + end + end end context 'when error case' do