diff --git a/Steepfile b/Steepfile index 5627c45a..64438489 100644 --- a/Steepfile +++ b/Steepfile @@ -8,6 +8,9 @@ target :lib do check "lib/lrama/grammar/code.rb" check "lib/lrama/grammar/counter.rb" check "lib/lrama/grammar/error_token.rb" + check "lib/lrama/grammar/parameterizing_rule_builder.rb" + check "lib/lrama/grammar/parameterizing_rule_resolver.rb" + check "lib/lrama/grammar/parameterizing_rule_rhs_builder.rb" check "lib/lrama/grammar/parameterizing_rules" check "lib/lrama/grammar/percent_code.rb" check "lib/lrama/grammar/precedence.rb" diff --git a/lib/lrama/grammar.rb b/lib/lrama/grammar.rb index c6bdc8a6..f1bd402b 100644 --- a/lib/lrama/grammar.rb +++ b/lib/lrama/grammar.rb @@ -8,6 +8,9 @@ require "lrama/grammar/reference" require "lrama/grammar/rule" require "lrama/grammar/rule_builder" +require "lrama/grammar/parameterizing_rule_builder" +require "lrama/grammar/parameterizing_rule_resolver" +require "lrama/grammar/parameterizing_rule_rhs_builder" require "lrama/grammar/symbol" require "lrama/grammar/type" require "lrama/grammar/union" @@ -36,6 +39,7 @@ def initialize(rule_counter) @rule_builders = [] @rules = [] @sym_to_rules = {} + @parameterizing_resolver = ParameterizingRuleResolver.new @empty_symbol = nil @eof_symbol = nil @error_symbol = nil @@ -129,6 +133,10 @@ def add_rule_builder(builder) @rule_builders << builder end + def add_parameterizing_rule_builder(builder) + @parameterizing_resolver.add_parameterizing_rule_builder(builder) + end + def prologue_first_lineno=(prologue_first_lineno) @aux.prologue_first_lineno = prologue_first_lineno end @@ -310,7 +318,7 @@ def compute_first_set def setup_rules @rule_builders.each do |builder| - builder.setup_rules + builder.setup_rules(@parameterizing_resolver) end end @@ -400,6 +408,10 @@ def normalize_rules add_nterm(id: rule._lhs) end end + + if @parameterizing_resolver.term + add_term(id: @parameterizing_resolver.term) + end end # Collect symbols from rules diff --git a/lib/lrama/grammar/parameterizing_rule_builder.rb b/lib/lrama/grammar/parameterizing_rule_builder.rb new file mode 100644 index 00000000..82940c40 --- /dev/null +++ b/lib/lrama/grammar/parameterizing_rule_builder.rb @@ -0,0 +1,47 @@ +module Lrama + class Grammar + class ParameterizingRuleBuilder + attr_reader :name, :args, :rhs, :term + + def initialize(name, args, rhs) + @name = name + @args = args + @rhs = rhs + @term = nil + @required_args_count = args.count + end + + def build_rules(token, build_token, rule_counter, lhs_tag, user_code, precedence_sym, line) + validate_argument_number!(token) + rules = [] + @rhs.each do |rhs| + @term = rhs_term(token, rhs) + rules << Rule.new(id: rule_counter.increment, _lhs: build_token, _rhs: [@term].compact, lhs_tag: lhs_tag, token_code: rhs.user_code, precedence_sym: rhs.precedence_sym, lineno: line) + end + rules + end + + def build_token(token) + validate_argument_number!(token) + Lrama::Lexer::Token::Ident.new(s_value: "#{name}_#{token.args.first&.s_value}") + end + + private + + def validate_argument_number!(token) + unless @required_args_count == token.args.count + raise "Invalid number of arguments. expect: #{@required_args_count} actual: #{token.args.count}" + end + end + + def rhs_term(token, rhs) + return nil unless rhs.symbol + term = rhs.symbol + @args.each_with_index do |arg, index| + term = token.args[index] if arg.s_value == rhs.symbol.s_value + end + term + end + end + end +end diff --git a/lib/lrama/grammar/parameterizing_rule_resolver.rb b/lib/lrama/grammar/parameterizing_rule_resolver.rb new file mode 100644 index 00000000..3392768b --- /dev/null +++ b/lib/lrama/grammar/parameterizing_rule_resolver.rb @@ -0,0 +1,31 @@ +module Lrama + class Grammar + class ParameterizingRuleResolver + attr_reader :rules, :tokens, :term + + def initialize + @rules = [] + @tokens = [] + @term = nil + @parameterizing_rule_builders = [] + end + + def add_parameterizing_rule_builder(builder) + @parameterizing_rule_builders << builder + end + + def defined?(name) + @parameterizing_rule_builders.any? { |builder| builder.name == name } + end + + def build_rules(token, rule_counter, lhs_tag, user_code, precedence_sym, line) + @parameterizing_rule_builders.each do |builder| + build_token = builder.build_token(token) + @rules = @rules + builder.build_rules(token, build_token, rule_counter, lhs_tag, user_code, precedence_sym, line) + @tokens << build_token + @term = builder.term + end + end + end + end +end diff --git a/lib/lrama/grammar/parameterizing_rule_rhs_builder.rb b/lib/lrama/grammar/parameterizing_rule_rhs_builder.rb new file mode 100644 index 00000000..e0ab231a --- /dev/null +++ b/lib/lrama/grammar/parameterizing_rule_rhs_builder.rb @@ -0,0 +1,13 @@ +module Lrama + class Grammar + class ParameterizingRuleRhsBuilder + attr_accessor :symbol, :user_code, :precedence_sym + + def initialize + @symbol = nil + @user_code = nil + @precedence_sym = nil + end + end + end +end diff --git a/lib/lrama/grammar/rule_builder.rb b/lib/lrama/grammar/rule_builder.rb index 94a744dc..e362c792 100644 --- a/lib/lrama/grammar/rule_builder.rb +++ b/lib/lrama/grammar/rule_builder.rb @@ -51,9 +51,9 @@ def complete_input freeze_rhs end - def setup_rules + def setup_rules(parameterizing_resolver) preprocess_references unless @skip_preprocess_references - process_rhs + process_rhs(parameterizing_resolver) build_rules end @@ -97,7 +97,7 @@ def build_rules # rhs is a mixture of variety type of tokens like `Ident`, `Parameterizing`, `UserCode` and so on. # `#process_rhs` replaces some kind of tokens to `Ident` so that all `@replaced_rhs` are `Ident` or `Char`. - def process_rhs + def process_rhs(parameterizing_resolver) return if @replaced_rhs @replaced_rhs = [] @@ -110,11 +110,15 @@ def process_rhs when Lrama::Lexer::Token::Ident @replaced_rhs << token when Lrama::Lexer::Token::Parameterizing - parameterizing = ParameterizingRules::Builder.new(token, @rule_counter, @lhs_tag, user_code, precedence_sym, line) - parameterizing.build.each do |r| - @parameterizing_rules << r + if parameterizing_resolver.defined?(token.s_value) + parameterizing_resolver.build_rules(token, @rule_counter, @lhs_tag, user_code, precedence_sym, line) + @parameterizing_rules = @parameterizing_rules + parameterizing_resolver.rules + @replaced_rhs = @replaced_rhs + parameterizing_resolver.tokens + else + parameterizing = ParameterizingRules::Builder.new(token, @rule_counter, @lhs_tag, user_code, precedence_sym, line) + @parameterizing_rules = @parameterizing_rules + parameterizing.build + @replaced_rhs << parameterizing.build_token end - @replaced_rhs << parameterizing.build_token when Lrama::Lexer::Token::UserCode prefix = token.referred ? "@" : "$@" new_token = Lrama::Lexer::Token::Ident.new(s_value: prefix + @midrule_action_counter.increment.to_s) @@ -124,7 +128,7 @@ def process_rhs rule_builder.lhs = new_token rule_builder.user_code = token rule_builder.complete_input - rule_builder.setup_rules + rule_builder.setup_rules(parameterizing_resolver) @rule_builders_for_derived_rules << rule_builder else diff --git a/lib/lrama/lexer.rb b/lib/lrama/lexer.rb index 8aab19be..63a1a0a0 100644 --- a/lib/lrama/lexer.rb +++ b/lib/lrama/lexer.rb @@ -28,6 +28,7 @@ class Lexer %error-token %empty %code + %rule ) def initialize(text) diff --git a/lib/lrama/parser.rb b/lib/lrama/parser.rb index bde7179a..f6d27371 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', 420) +module_eval(<<'...end parser.y/module_eval...', 'parser.y', 489) include Lrama::Report::Duration @@ -749,261 +749,291 @@ def carrets(first_column, last_column) ##### State transition tables begin ### racc_action_table = [ - 82, 42, 83, 137, 42, 65, 137, 38, 65, 136, - 42, 6, 41, 7, 42, 56, 41, 139, 65, 61, - 139, 135, 42, 42, 41, 41, 20, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 140, 38, 3, 140, - 84, 42, 77, 41, 8, 42, 68, 41, 172, 42, - 68, 41, 32, 173, 68, 39, 20, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 9, 42, 45, 41, - 12, 13, 14, 15, 16, 17, 45, 45, 18, 19, - 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 42, 48, 41, 151, 49, 68, 152, 153, 154, 42, - 42, 41, 41, 65, 163, 42, 42, 41, 41, 65, - 163, 42, 42, 41, 41, 65, 163, 42, 42, 41, - 41, 65, 163, 42, 42, 41, 41, 65, 163, 42, - 42, 41, 41, 65, 163, 42, 42, 41, 41, 65, - 65, 42, 42, 41, 41, 65, 65, 42, 42, 41, - 41, 65, 65, 42, 42, 41, 41, 65, 65, 42, - 42, 41, 41, 50, 51, 52, 53, 74, 78, 80, - 85, 85, 85, 87, 93, 97, 98, 101, 101, 101, - 101, 106, 107, 109, 111, 112, 113, 114, 115, 118, - 121, 122, 125, 126, 127, 129, 142, 144, 145, 146, - 147, 148, 125, 80, 158, 159, 167, 170, 167, 177, - 80 ] + 85, 44, 86, 145, 144, 67, 44, 44, 145, 43, + 67, 67, 44, 186, 43, 3, 67, 147, 161, 44, + 143, 43, 147, 188, 58, 162, 163, 164, 188, 185, + 44, 40, 43, 8, 67, 63, 34, 6, 148, 7, + 41, 87, 40, 148, 189, 47, 44, 80, 43, 189, + 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 47, 21, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 9, 44, 47, 43, 13, 14, 15, 16, 17, + 18, 50, 51, 19, 20, 21, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 44, 44, 43, 43, + 52, 70, 70, 44, 44, 43, 43, 53, 70, 70, + 44, 44, 43, 43, 67, 173, 44, 44, 43, 43, + 67, 173, 44, 44, 43, 43, 67, 173, 44, 44, + 43, 43, 67, 173, 44, 44, 43, 43, 67, 173, + 44, 44, 43, 43, 67, 173, 44, 44, 43, 43, + 67, 67, 44, 44, 43, 43, 67, 67, 44, 44, + 43, 43, 67, 67, 44, 44, 43, 43, 67, 67, + 44, 44, 43, 43, 67, 44, 44, 43, 43, 141, + 190, 142, 191, 54, 55, 76, 77, 81, 83, 88, + 88, 88, 90, 96, 100, 101, 104, 104, 104, 104, + 107, 110, 111, 113, 115, 116, 117, 118, 119, 122, + 126, 127, 128, 131, 132, 133, 135, 150, 152, 153, + 154, 155, 156, 157, 158, 131, 83, 168, 169, 178, + 180, 183, 178, 83, 180, 199, 200, 83, 203, 83 ] racc_action_check = [ - 40, 124, 40, 124, 149, 124, 149, 9, 149, 123, - 25, 2, 25, 2, 26, 25, 26, 124, 26, 26, - 149, 123, 13, 55, 13, 55, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 124, 33, 1, 149, - 40, 27, 33, 27, 3, 28, 27, 28, 168, 29, - 28, 29, 7, 168, 29, 12, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 4, 56, 14, 56, - 4, 4, 4, 4, 4, 4, 15, 16, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 30, 17, 30, 137, 18, 30, 137, 137, 137, 146, - 67, 146, 67, 146, 146, 147, 68, 147, 68, 147, - 147, 148, 93, 148, 93, 148, 148, 160, 95, 160, - 95, 160, 160, 164, 101, 164, 101, 164, 164, 165, - 103, 165, 103, 165, 165, 60, 61, 60, 61, 60, - 61, 98, 100, 98, 100, 98, 100, 119, 140, 119, - 140, 119, 140, 151, 173, 151, 173, 151, 173, 116, - 120, 116, 120, 20, 22, 23, 24, 31, 36, 37, - 44, 46, 47, 48, 54, 58, 59, 66, 71, 72, - 73, 79, 80, 86, 88, 89, 90, 91, 92, 96, - 104, 105, 106, 107, 108, 110, 128, 130, 131, 132, - 133, 134, 135, 138, 141, 143, 150, 156, 172, 174, - 177 ] + 42, 130, 42, 130, 129, 130, 159, 177, 159, 177, + 159, 177, 193, 176, 193, 1, 193, 130, 145, 26, + 129, 26, 159, 177, 26, 145, 145, 145, 193, 176, + 27, 9, 27, 3, 27, 27, 7, 2, 130, 2, + 13, 42, 35, 159, 177, 15, 14, 35, 14, 193, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 16, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 4, 57, 17, 57, 4, 4, 4, 4, 4, + 4, 18, 19, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 28, 29, 28, 29, + 21, 28, 29, 30, 31, 30, 31, 23, 30, 31, + 154, 58, 154, 58, 154, 154, 155, 69, 155, 69, + 155, 155, 156, 70, 156, 70, 156, 156, 170, 96, + 170, 96, 170, 170, 174, 98, 174, 98, 174, 174, + 175, 104, 175, 104, 175, 175, 62, 63, 62, 63, + 62, 63, 101, 103, 101, 103, 101, 103, 123, 148, + 123, 148, 123, 148, 161, 189, 161, 189, 161, 189, + 191, 106, 191, 106, 191, 120, 124, 120, 124, 125, + 181, 125, 181, 24, 25, 32, 33, 38, 39, 46, + 48, 49, 50, 56, 60, 61, 68, 73, 74, 75, + 76, 82, 83, 89, 91, 92, 93, 94, 95, 99, + 107, 108, 109, 110, 111, 112, 114, 134, 136, 137, + 138, 139, 140, 141, 142, 143, 146, 149, 151, 157, + 160, 166, 185, 187, 190, 192, 195, 199, 202, 203 ] racc_action_pointer = [ - nil, 38, 1, 44, 57, nil, nil, 45, nil, 3, - nil, nil, 49, 19, 49, 57, 58, 86, 75, nil, - 144, nil, 145, 146, 147, 7, 11, 38, 42, 46, - 87, 165, nil, 33, nil, nil, 146, 126, nil, nil, - -5, nil, nil, nil, 151, nil, 152, 153, 154, nil, - nil, nil, nil, nil, 166, 20, 64, nil, 169, 168, - 132, 133, nil, nil, nil, nil, 169, 97, 103, nil, - nil, 170, 171, 172, nil, nil, nil, nil, nil, 148, - 177, nil, nil, nil, nil, nil, 181, nil, 182, 183, - 184, 185, 186, 109, nil, 115, 182, nil, 138, nil, - 139, 121, nil, 127, 179, 189, 157, 149, 192, nil, - 193, nil, nil, nil, nil, nil, 156, nil, nil, 144, - 157, nil, nil, -13, -2, nil, nil, nil, 176, nil, - 177, 178, 179, 180, 181, 167, nil, 57, 160, nil, - 145, 184, nil, 185, nil, nil, 96, 102, 108, 1, - 198, 150, nil, nil, nil, nil, 205, nil, nil, nil, - 114, nil, nil, nil, 120, 126, nil, nil, 11, nil, - nil, nil, 200, 151, 189, nil, nil, 167, nil ] + nil, 15, 27, 33, 62, nil, nil, 29, nil, 27, + nil, nil, nil, 34, 43, 26, 41, 54, 76, 63, + nil, 81, nil, 88, 164, 165, 16, 27, 93, 94, + 100, 101, 180, 184, nil, 38, nil, nil, 165, 144, + nil, nil, -5, nil, nil, nil, 170, nil, 171, 172, + 173, nil, nil, nil, nil, nil, 185, 69, 108, nil, + 188, 187, 143, 144, nil, nil, nil, nil, 188, 114, + 120, nil, nil, 189, 190, 191, 166, nil, nil, nil, + nil, nil, 165, 197, nil, nil, nil, nil, nil, 201, + nil, 202, 203, 204, 205, 206, 126, nil, 132, 202, + nil, 149, nil, 150, 138, nil, 168, 205, 200, 210, + 174, 169, 213, nil, 214, nil, nil, nil, nil, nil, + 172, nil, nil, 155, 173, 144, nil, nil, nil, -18, + -2, nil, nil, nil, 197, nil, 198, 199, 200, 201, + 202, 187, 219, 186, nil, -16, 182, nil, 156, 207, + nil, 208, nil, nil, 107, 113, 119, 190, nil, 3, + 222, 161, nil, nil, nil, nil, 229, nil, nil, nil, + 125, nil, nil, nil, 131, 137, -9, 4, nil, nil, + nil, 145, nil, nil, nil, 193, nil, 189, nil, 162, + 226, 167, 215, 9, nil, 234, nil, nil, nil, 193, + nil, nil, 218, 195, nil ] racc_action_default = [ - -2, -113, -8, -113, -113, -3, -4, -113, 179, -113, - -9, -10, -113, -113, -113, -113, -113, -113, -113, -22, - -113, -26, -113, -113, -113, -113, -113, -113, -113, -113, - -113, -113, -7, -98, -73, -75, -113, -95, -97, -11, - -102, -71, -72, -101, -13, -62, -14, -15, -113, -19, - -23, -27, -30, -33, -36, -42, -113, -45, -48, -37, - -52, -113, -55, -57, -58, -110, -38, -65, -113, -68, - -70, -39, -40, -41, -5, -1, -74, -99, -76, -113, - -113, -12, -103, -104, -105, -59, -113, -16, -113, -113, - -113, -113, -113, -113, -46, -43, -50, -49, -113, -56, - -53, -113, -69, -66, -113, -113, -81, -113, -113, -63, - -113, -20, -24, -28, -31, -34, -44, -47, -51, -54, - -67, -6, -100, -77, -78, -82, -96, -60, -113, -17, - -113, -113, -113, -113, -113, -81, -80, -71, -95, -86, - -113, -113, -64, -113, -21, -25, -113, -113, -113, -79, - -111, -113, -90, -91, -92, -83, -113, -89, -61, -18, - -29, -106, -108, -109, -32, -35, -84, -112, -113, -93, - -87, -107, -111, -113, -113, -85, -94, -95, -88 ] + -2, -127, -8, -127, -127, -3, -4, -127, 205, -127, + -9, -10, -11, -127, -127, -127, -127, -127, -127, -127, + -23, -127, -27, -127, -127, -127, -127, -127, -127, -127, + -127, -127, -127, -127, -7, -112, -87, -89, -127, -109, + -111, -12, -116, -85, -86, -115, -14, -76, -15, -16, + -127, -20, -24, -28, -31, -34, -37, -43, -127, -46, + -62, -38, -66, -127, -69, -71, -72, -124, -39, -79, + -127, -82, -84, -40, -41, -42, -127, -5, -1, -88, + -113, -90, -127, -127, -13, -117, -118, -119, -73, -127, + -17, -127, -127, -127, -127, -127, -127, -47, -44, -64, + -63, -127, -70, -67, -127, -83, -80, -127, -127, -127, + -95, -127, -127, -77, -127, -21, -25, -29, -32, -35, + -45, -48, -65, -68, -81, -127, -50, -6, -114, -91, + -92, -96, -110, -74, -127, -18, -127, -127, -127, -127, + -127, -127, -127, -95, -94, -85, -109, -100, -127, -127, + -78, -127, -22, -26, -127, -127, -127, -55, -51, -93, + -125, -127, -104, -105, -106, -97, -127, -103, -75, -19, + -30, -120, -122, -123, -33, -36, -49, -52, -56, -98, + -126, -127, -107, -101, -121, -55, -54, -109, -58, -127, + -125, -127, -127, -53, -57, -127, -61, -99, -108, -109, + -59, -102, -127, -109, -60 ] racc_goto_table = [ - 62, 79, 43, 60, 103, 55, 94, 102, 34, 166, - 124, 44, 46, 47, 58, 1, 70, 70, 70, 70, - 171, 160, 164, 165, 171, 171, 66, 71, 72, 73, - 2, 175, 76, 4, 99, 62, 95, 120, 100, 149, - 33, 75, 5, 102, 58, 58, 94, 31, 104, 10, - 11, 40, 81, 110, 143, 88, 70, 70, 130, 89, - 102, 131, 90, 132, 91, 133, 92, 94, 134, 54, - 59, 96, 62, 116, 99, 119, 117, 108, 141, 86, - 128, 123, 58, 150, 58, 168, 156, 174, 105, nil, - 70, nil, 70, 99, nil, nil, nil, nil, 138, nil, - nil, nil, 155, nil, nil, 58, nil, nil, nil, 70, - nil, nil, nil, nil, 157, nil, nil, nil, nil, nil, - nil, nil, nil, 138, nil, 169, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, 178, nil, nil, nil, nil, nil, 176 ] + 64, 82, 57, 45, 62, 105, 130, 97, 179, 106, + 1, 36, 2, 177, 4, 60, 35, 72, 72, 72, + 72, 184, 46, 48, 49, 184, 184, 68, 73, 74, + 75, 170, 174, 175, 98, 102, 64, 79, 197, 159, + 103, 193, 105, 124, 78, 5, 60, 60, 97, 33, + 108, 10, 11, 12, 42, 84, 114, 151, 72, 72, + 105, 91, 136, 92, 137, 93, 138, 94, 139, 95, + 97, 140, 120, 56, 64, 61, 102, 99, 123, 121, + 125, 176, 195, 202, 112, 60, 149, 60, 89, 134, + 129, 160, 181, 72, 166, 72, 102, 192, 109, nil, + nil, nil, nil, 146, nil, nil, nil, nil, 165, 60, + nil, nil, nil, 72, nil, nil, nil, nil, nil, nil, + nil, 167, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 146, nil, 182, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 194, + 187, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 201, 196, nil, 198, 204, 187 ] racc_goto_check = [ - 37, 48, 33, 36, 43, 31, 32, 44, 45, 52, - 50, 13, 13, 13, 33, 1, 33, 33, 33, 33, - 57, 19, 19, 19, 57, 57, 30, 30, 30, 30, - 2, 52, 45, 3, 37, 37, 31, 43, 36, 50, - 4, 5, 6, 44, 33, 33, 32, 7, 8, 9, - 10, 11, 12, 14, 15, 16, 33, 33, 17, 20, - 44, 21, 22, 23, 24, 25, 26, 32, 27, 28, - 29, 34, 37, 31, 37, 36, 35, 39, 40, 41, - 42, 49, 33, 51, 33, 53, 54, 55, 56, nil, - 33, nil, 33, 37, nil, nil, nil, nil, 37, nil, - nil, nil, 48, nil, nil, 33, nil, nil, nil, 33, - nil, nil, nil, nil, 37, nil, nil, nil, nil, nil, - nil, nil, nil, 37, nil, 37, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, 48, nil, nil, nil, nil, nil, 37 ] + 40, 41, 32, 34, 44, 51, 56, 33, 58, 50, + 1, 52, 2, 39, 3, 34, 4, 34, 34, 34, + 34, 63, 14, 14, 14, 63, 63, 31, 31, 31, + 31, 20, 20, 20, 32, 40, 40, 52, 58, 56, + 44, 39, 51, 50, 5, 6, 34, 34, 33, 7, + 8, 9, 10, 11, 12, 13, 15, 16, 34, 34, + 51, 17, 18, 21, 22, 23, 24, 25, 26, 27, + 33, 28, 32, 29, 40, 30, 40, 35, 44, 36, + 37, 38, 42, 43, 46, 34, 47, 34, 48, 49, + 55, 57, 59, 34, 60, 34, 40, 61, 62, nil, + nil, nil, nil, 40, nil, nil, nil, nil, 41, 34, + nil, nil, nil, 34, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 40, nil, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + 40, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 41, 40, nil, 40, 41, 40 ] racc_goto_pointer = [ - nil, 15, 30, 31, 31, 8, 40, 41, -26, 45, - 46, 38, 12, -3, -34, -75, 6, -53, nil, -125, - 9, -51, 11, -50, 12, -49, 13, -47, 44, 44, - -1, -20, -49, -11, 13, -20, -23, -26, nil, -8, - -49, 34, -29, -64, -60, -1, nil, nil, -36, -25, - -96, -54, -141, -66, -53, -83, 11, -140 ] + nil, 10, 12, 12, 7, 9, 43, 43, -27, 47, + 48, 49, 40, 13, 7, -34, -78, 10, -53, nil, + -123, 11, -52, 12, -51, 13, -50, 14, -48, 47, + 48, -1, -24, -50, -11, 17, -20, -27, -76, -144, + -27, -38, -106, -117, -23, nil, -4, -47, 41, -24, + -61, -64, 2, nil, nil, -20, -104, -54, -152, -69, + -53, -86, 18, -149 ] racc_goto_default = [ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 36, nil, nil, nil, nil, nil, nil, nil, 21, nil, + 38, nil, nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 57, 63, nil, nil, nil, 162, 64, nil, - nil, nil, nil, 67, 69, nil, 35, 37, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 161 ] + nil, nil, nil, 59, 65, nil, nil, nil, nil, nil, + 172, nil, nil, nil, nil, 66, nil, nil, nil, nil, + 69, 71, nil, 37, 39, nil, nil, nil, nil, nil, + nil, nil, nil, 171 ] racc_reduce_table = [ 0, 0, :racc_error, - 5, 47, :_reduce_none, - 0, 48, :_reduce_none, - 2, 48, :_reduce_none, - 0, 53, :_reduce_4, - 0, 54, :_reduce_5, - 5, 52, :_reduce_6, - 2, 52, :_reduce_none, - 0, 49, :_reduce_8, + 5, 48, :_reduce_none, + 0, 49, :_reduce_none, 2, 49, :_reduce_none, - 1, 55, :_reduce_none, - 2, 55, :_reduce_11, - 3, 55, :_reduce_none, - 2, 55, :_reduce_none, - 2, 55, :_reduce_14, - 2, 55, :_reduce_15, - 0, 60, :_reduce_16, - 0, 61, :_reduce_17, - 7, 55, :_reduce_18, - 0, 62, :_reduce_19, - 0, 63, :_reduce_20, - 6, 55, :_reduce_21, - 1, 55, :_reduce_none, - 0, 66, :_reduce_23, - 0, 67, :_reduce_24, - 6, 56, :_reduce_25, - 1, 56, :_reduce_none, - 0, 68, :_reduce_27, - 0, 69, :_reduce_28, - 7, 56, :_reduce_none, - 0, 70, :_reduce_30, - 0, 71, :_reduce_31, - 7, 56, :_reduce_32, - 0, 72, :_reduce_33, - 0, 73, :_reduce_34, - 7, 56, :_reduce_35, - 2, 64, :_reduce_none, - 2, 64, :_reduce_37, - 2, 64, :_reduce_38, - 2, 64, :_reduce_39, - 2, 64, :_reduce_40, - 2, 64, :_reduce_41, - 1, 74, :_reduce_42, - 2, 74, :_reduce_43, - 3, 74, :_reduce_44, - 1, 77, :_reduce_45, - 2, 77, :_reduce_46, - 3, 78, :_reduce_47, - 0, 80, :_reduce_none, - 1, 80, :_reduce_none, - 0, 81, :_reduce_none, - 1, 81, :_reduce_none, - 1, 75, :_reduce_52, - 2, 75, :_reduce_53, - 3, 75, :_reduce_54, - 1, 82, :_reduce_55, - 2, 82, :_reduce_56, - 1, 83, :_reduce_none, - 1, 83, :_reduce_none, - 0, 85, :_reduce_59, - 0, 86, :_reduce_60, - 6, 59, :_reduce_61, - 0, 87, :_reduce_62, - 0, 88, :_reduce_63, - 5, 59, :_reduce_64, - 1, 76, :_reduce_65, - 2, 76, :_reduce_66, - 3, 76, :_reduce_67, - 1, 89, :_reduce_68, - 2, 89, :_reduce_69, - 1, 90, :_reduce_none, - 1, 79, :_reduce_71, - 1, 79, :_reduce_72, - 1, 50, :_reduce_none, + 0, 54, :_reduce_4, + 0, 55, :_reduce_5, + 5, 53, :_reduce_6, + 2, 53, :_reduce_none, + 0, 50, :_reduce_8, 2, 50, :_reduce_none, - 1, 91, :_reduce_none, - 2, 91, :_reduce_none, - 4, 92, :_reduce_77, - 1, 95, :_reduce_78, - 3, 95, :_reduce_79, - 2, 95, :_reduce_none, - 0, 96, :_reduce_81, - 1, 96, :_reduce_82, - 3, 96, :_reduce_83, - 4, 96, :_reduce_84, - 6, 96, :_reduce_85, - 0, 100, :_reduce_86, - 0, 101, :_reduce_87, - 7, 96, :_reduce_88, - 3, 96, :_reduce_89, - 1, 97, :_reduce_none, - 1, 97, :_reduce_none, - 1, 97, :_reduce_none, - 1, 99, :_reduce_93, - 3, 99, :_reduce_94, - 0, 94, :_reduce_none, - 3, 94, :_reduce_96, - 1, 93, :_reduce_none, - 0, 51, :_reduce_none, - 0, 102, :_reduce_99, - 3, 51, :_reduce_100, + 1, 56, :_reduce_none, + 1, 56, :_reduce_none, + 2, 56, :_reduce_12, + 3, 56, :_reduce_none, + 2, 56, :_reduce_none, + 2, 56, :_reduce_15, + 2, 56, :_reduce_16, + 0, 62, :_reduce_17, + 0, 63, :_reduce_18, + 7, 56, :_reduce_19, + 0, 64, :_reduce_20, + 0, 65, :_reduce_21, + 6, 56, :_reduce_22, + 1, 56, :_reduce_none, + 0, 68, :_reduce_24, + 0, 69, :_reduce_25, + 6, 57, :_reduce_26, 1, 57, :_reduce_none, - 0, 58, :_reduce_none, - 1, 58, :_reduce_none, - 1, 58, :_reduce_none, - 1, 58, :_reduce_none, - 1, 65, :_reduce_106, - 2, 65, :_reduce_107, - 1, 103, :_reduce_none, - 1, 103, :_reduce_none, - 1, 84, :_reduce_110, - 0, 98, :_reduce_none, - 1, 98, :_reduce_none ] - -racc_reduce_n = 113 - -racc_shift_n = 179 + 0, 70, :_reduce_28, + 0, 71, :_reduce_29, + 7, 57, :_reduce_none, + 0, 72, :_reduce_31, + 0, 73, :_reduce_32, + 7, 57, :_reduce_33, + 0, 74, :_reduce_34, + 0, 75, :_reduce_35, + 7, 57, :_reduce_36, + 2, 66, :_reduce_none, + 2, 66, :_reduce_38, + 2, 66, :_reduce_39, + 2, 66, :_reduce_40, + 2, 66, :_reduce_41, + 2, 66, :_reduce_42, + 1, 76, :_reduce_43, + 2, 76, :_reduce_44, + 3, 76, :_reduce_45, + 1, 79, :_reduce_46, + 2, 79, :_reduce_47, + 3, 80, :_reduce_48, + 7, 58, :_reduce_49, + 1, 84, :_reduce_50, + 3, 84, :_reduce_51, + 1, 85, :_reduce_52, + 3, 85, :_reduce_53, + 2, 85, :_reduce_none, + 0, 86, :_reduce_55, + 1, 86, :_reduce_56, + 3, 86, :_reduce_57, + 0, 89, :_reduce_58, + 0, 90, :_reduce_59, + 7, 86, :_reduce_60, + 3, 86, :_reduce_61, + 0, 82, :_reduce_none, + 1, 82, :_reduce_none, + 0, 83, :_reduce_none, + 1, 83, :_reduce_none, + 1, 77, :_reduce_66, + 2, 77, :_reduce_67, + 3, 77, :_reduce_68, + 1, 91, :_reduce_69, + 2, 91, :_reduce_70, + 1, 87, :_reduce_none, + 1, 87, :_reduce_none, + 0, 93, :_reduce_73, + 0, 94, :_reduce_74, + 6, 61, :_reduce_75, + 0, 95, :_reduce_76, + 0, 96, :_reduce_77, + 5, 61, :_reduce_78, + 1, 78, :_reduce_79, + 2, 78, :_reduce_80, + 3, 78, :_reduce_81, + 1, 97, :_reduce_82, + 2, 97, :_reduce_83, + 1, 98, :_reduce_none, + 1, 81, :_reduce_85, + 1, 81, :_reduce_86, + 1, 51, :_reduce_none, + 2, 51, :_reduce_none, + 1, 99, :_reduce_none, + 2, 99, :_reduce_none, + 4, 100, :_reduce_91, + 1, 102, :_reduce_92, + 3, 102, :_reduce_93, + 2, 102, :_reduce_none, + 0, 103, :_reduce_95, + 1, 103, :_reduce_96, + 3, 103, :_reduce_97, + 4, 103, :_reduce_98, + 6, 103, :_reduce_99, + 0, 107, :_reduce_100, + 0, 108, :_reduce_101, + 7, 103, :_reduce_102, + 3, 103, :_reduce_103, + 1, 104, :_reduce_none, + 1, 104, :_reduce_none, + 1, 104, :_reduce_none, + 1, 106, :_reduce_107, + 3, 106, :_reduce_108, + 0, 88, :_reduce_none, + 3, 88, :_reduce_110, + 1, 101, :_reduce_none, + 0, 52, :_reduce_none, + 0, 109, :_reduce_113, + 3, 52, :_reduce_114, + 1, 59, :_reduce_none, + 0, 60, :_reduce_none, + 1, 60, :_reduce_none, + 1, 60, :_reduce_none, + 1, 60, :_reduce_none, + 1, 67, :_reduce_120, + 2, 67, :_reduce_121, + 1, 110, :_reduce_none, + 1, 110, :_reduce_none, + 1, 92, :_reduce_124, + 0, 105, :_reduce_none, + 1, 105, :_reduce_none ] + +racc_reduce_n = 127 + +racc_shift_n = 205 racc_token_table = { false => 0, @@ -1039,21 +1069,22 @@ def carrets(first_column, last_column) "%right" => 30, "%precedence" => 31, "%nonassoc" => 32, - ":" => 33, - "|" => 34, - "%empty" => 35, - "(" => 36, - ")" => 37, - "%prec" => 38, - "?" => 39, - "+" => 40, - "*" => 41, - "," => 42, - "[" => 43, - "]" => 44, - "{...}" => 45 } - -racc_nt_base = 46 + "%rule" => 33, + "(" => 34, + ")" => 35, + ":" => 36, + "," => 37, + "|" => 38, + "%empty" => 39, + "%prec" => 40, + "?" => 41, + "+" => 42, + "*" => 43, + "[" => 44, + "]" => 45, + "{...}" => 46 } + +racc_nt_base = 47 racc_use_result_var = true @@ -1108,16 +1139,17 @@ def carrets(first_column, last_column) "\"%right\"", "\"%precedence\"", "\"%nonassoc\"", + "\"%rule\"", + "\"(\"", + "\")\"", "\":\"", + "\",\"", "\"|\"", "\"%empty\"", - "\"(\"", - "\")\"", "\"%prec\"", "\"?\"", "\"+\"", "\"*\"", - "\",\"", "\"[\"", "\"]\"", "\"{...}\"", @@ -1132,6 +1164,7 @@ def carrets(first_column, last_column) "@2", "bison_declaration", "grammar_declaration", + "rule_declaration", "variable", "value", "params", @@ -1157,27 +1190,32 @@ def carrets(first_column, last_column) "id", "int_opt", "alias", - "symbol_declaration_list", + "rule_args", + "rule_rhs_list", + "rule_rhs", "symbol", - "string_as_id", + "named_ref_opt", "@15", "@16", + "symbol_declaration_list", + "string_as_id", "@17", "@18", + "@19", + "@20", "token_declaration_list_for_precedence", "token_declaration_for_precedence", "rules_or_grammar_declaration", "rules", "id_colon", - "named_ref_opt", "rhs_list", "rhs", "parameterizing_suffix", "tag_opt", "parameterizing_args", - "@19", - "@20", "@21", + "@22", + "@23", "generic_symlist_item" ] Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) @@ -1231,19 +1269,21 @@ def _reduce_8(val, _values, result) # reduce 10 omitted -module_eval(<<'.,.,', 'parser.y', 31) - def _reduce_11(val, _values, result) +# reduce 11 omitted + +module_eval(<<'.,.,', 'parser.y', 32) + def _reduce_12(val, _values, result) @grammar.expect = val[1] result end .,., -# reduce 12 omitted - # reduce 13 omitted -module_eval(<<'.,.,', 'parser.y', 36) - def _reduce_14(val, _values, result) +# reduce 14 omitted + +module_eval(<<'.,.,', 'parser.y', 37) + def _reduce_15(val, _values, result) val[1].each {|token| @grammar.lex_param = Grammar::Code::NoReferenceCode.new(type: :lex_param, token_code: token).token_code.s_value } @@ -1252,8 +1292,8 @@ def _reduce_14(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 42) - def _reduce_15(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 43) + def _reduce_16(val, _values, result) val[1].each {|token| @grammar.parse_param = Grammar::Code::NoReferenceCode.new(type: :parse_param, token_code: token).token_code.s_value } @@ -1262,74 +1302,74 @@ def _reduce_15(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 48) - def _reduce_16(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 49) + def _reduce_17(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 52) - def _reduce_17(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 53) + def _reduce_18(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 56) - def _reduce_18(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 57) + def _reduce_19(val, _values, result) @grammar.add_percent_code(id: val[1], code: val[4]) result end .,., -module_eval(<<'.,.,', 'parser.y', 60) - def _reduce_19(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 61) + def _reduce_20(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 64) - def _reduce_20(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 65) + def _reduce_21(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 68) - def _reduce_21(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 69) + def _reduce_22(val, _values, result) @grammar.initial_action = Grammar::Code::InitialActionCode.new(type: :initial_action, token_code: val[3]) result end .,., -# reduce 22 omitted +# reduce 23 omitted -module_eval(<<'.,.,', 'parser.y', 74) - def _reduce_23(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 75) + def _reduce_24(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 78) - def _reduce_24(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 79) + def _reduce_25(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 82) - def _reduce_25(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 83) + def _reduce_26(val, _values, result) @grammar.set_union( Grammar::Code::NoReferenceCode.new(type: :union, token_code: val[3]), val[3].line @@ -1339,44 +1379,44 @@ def _reduce_25(val, _values, result) end .,., -# reduce 26 omitted +# reduce 27 omitted -module_eval(<<'.,.,', 'parser.y', 90) - def _reduce_27(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 91) + def _reduce_28(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 94) - def _reduce_28(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 95) + def _reduce_29(val, _values, result) end_c_declaration result end .,., -# reduce 29 omitted +# reduce 30 omitted -module_eval(<<'.,.,', 'parser.y', 99) - def _reduce_30(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 100) + def _reduce_31(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 103) - def _reduce_31(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 104) + def _reduce_32(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 107) - def _reduce_32(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 108) + def _reduce_33(val, _values, result) @grammar.add_printer( ident_or_tags: val[6], token_code: val[3], @@ -1387,24 +1427,24 @@ def _reduce_32(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 115) - def _reduce_33(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 116) + def _reduce_34(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 119) - def _reduce_34(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 120) + def _reduce_35(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 123) - def _reduce_35(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 124) + def _reduce_36(val, _values, result) @grammar.add_error_token( ident_or_tags: val[6], token_code: val[3], @@ -1415,10 +1455,10 @@ def _reduce_35(val, _values, result) end .,., -# reduce 36 omitted +# reduce 37 omitted -module_eval(<<'.,.,', 'parser.y', 133) - def _reduce_37(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 134) + def _reduce_38(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| @grammar.add_type(id: id, tag: hash[:tag]) @@ -1429,8 +1469,8 @@ def _reduce_37(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 141) - def _reduce_38(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 142) + def _reduce_39(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1443,8 +1483,8 @@ def _reduce_38(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 151) - def _reduce_39(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 152) + def _reduce_40(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1457,8 +1497,8 @@ def _reduce_39(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 161) - def _reduce_40(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 162) + def _reduce_41(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1471,8 +1511,8 @@ def _reduce_40(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 171) - def _reduce_41(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 172) + def _reduce_42(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1485,8 +1525,8 @@ def _reduce_41(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 182) - def _reduce_42(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 183) + def _reduce_43(val, _values, result) val[0].each {|token_declaration| @grammar.add_term(id: token_declaration[0], alias_name: token_declaration[2], token_id: token_declaration[1], tag: nil, replace: true) } @@ -1495,8 +1535,8 @@ def _reduce_42(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 188) - def _reduce_43(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 189) + def _reduce_44(val, _values, result) val[1].each {|token_declaration| @grammar.add_term(id: token_declaration[0], alias_name: token_declaration[2], token_id: token_declaration[1], tag: val[0], replace: true) } @@ -1505,8 +1545,8 @@ def _reduce_43(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 194) - def _reduce_44(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 195) + def _reduce_45(val, _values, result) val[2].each {|token_declaration| @grammar.add_term(id: token_declaration[0], alias_name: token_declaration[2], token_id: token_declaration[1], tag: val[1], replace: true) } @@ -1515,189 +1555,306 @@ def _reduce_44(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 199) - def _reduce_45(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 200) + def _reduce_46(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 200) - def _reduce_46(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 201) + def _reduce_47(val, _values, result) result = val[0].append(val[1]) result end .,., -module_eval(<<'.,.,', 'parser.y', 202) - def _reduce_47(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 203) + def _reduce_48(val, _values, result) result = val result end .,., -# reduce 48 omitted - -# reduce 49 omitted +module_eval(<<'.,.,', 'parser.y', 207) + def _reduce_49(val, _values, result) + builder = Grammar::ParameterizingRuleBuilder.new(val[1].s_value, val[3], val[6]) + @grammar.add_parameterizing_rule_builder(builder) -# reduce 50 omitted + result + end +.,., -# reduce 51 omitted +module_eval(<<'.,.,', 'parser.y', 211) + def _reduce_50(val, _values, result) + result = [val[0]] + result + end +.,., module_eval(<<'.,.,', 'parser.y', 212) + def _reduce_51(val, _values, result) + result = val[0].append(val[2]) + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 216) def _reduce_52(val, _values, result) - result = [{tag: nil, tokens: val[0]}] + builder = val[0] + result = [builder] result end .,., -module_eval(<<'.,.,', 'parser.y', 216) +module_eval(<<'.,.,', 'parser.y', 221) def _reduce_53(val, _values, result) + builder = val[2] + result = val[0].append(builder) + + result + end +.,., + +# reduce 54 omitted + +module_eval(<<'.,.,', 'parser.y', 228) + def _reduce_55(val, _values, result) + reset_precs + result = Grammar::ParameterizingRuleRhsBuilder.new + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 233) + def _reduce_56(val, _values, result) + reset_precs + result = Grammar::ParameterizingRuleRhsBuilder.new + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 238) + def _reduce_57(val, _values, result) + token = val[1] + token.alias_name = val[2] + builder = val[0] + builder.symbol = token + result = builder + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 246) + def _reduce_58(val, _values, result) + if @prec_seen + on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec + @code_after_prec = true + end + begin_c_declaration("}") + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 254) + def _reduce_59(val, _values, result) + end_c_declaration + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 258) + def _reduce_60(val, _values, result) + user_code = val[3] + user_code.alias_name = val[6] + builder = val[0] + builder.user_code = user_code + result = builder + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 266) + def _reduce_61(val, _values, result) + sym = @grammar.find_symbol_by_id!(val[2]) + @prec_seen = true + builder = val[0] + builder.precedence_sym = sym + result = builder + + result + end +.,., + +# reduce 62 omitted + +# reduce 63 omitted + +# reduce 64 omitted + +# reduce 65 omitted + +module_eval(<<'.,.,', 'parser.y', 281) + def _reduce_66(val, _values, result) + result = [{tag: nil, tokens: val[0]}] + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 285) + def _reduce_67(val, _values, result) result = [{tag: val[0], tokens: val[1]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 220) - def _reduce_54(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 289) + def _reduce_68(val, _values, result) result = val[0].append({tag: val[1], tokens: val[2]}) result end .,., -module_eval(<<'.,.,', 'parser.y', 223) - def _reduce_55(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 292) + def _reduce_69(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 224) - def _reduce_56(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 293) + def _reduce_70(val, _values, result) result = val[0].append(val[1]) result end .,., -# reduce 57 omitted +# reduce 71 omitted -# reduce 58 omitted +# reduce 72 omitted -module_eval(<<'.,.,', 'parser.y', 231) - def _reduce_59(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 300) + def _reduce_73(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 235) - def _reduce_60(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 304) + def _reduce_74(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 239) - def _reduce_61(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 308) + def _reduce_75(val, _values, result) result = val[0].append(val[3]) result end .,., -module_eval(<<'.,.,', 'parser.y', 243) - def _reduce_62(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 312) + def _reduce_76(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 247) - def _reduce_63(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 316) + def _reduce_77(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 251) - def _reduce_64(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 320) + def _reduce_78(val, _values, result) result = [val[2]] result end .,., -module_eval(<<'.,.,', 'parser.y', 256) - def _reduce_65(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 325) + def _reduce_79(val, _values, result) result = [{tag: nil, tokens: val[0]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 260) - def _reduce_66(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 329) + def _reduce_80(val, _values, result) result = [{tag: val[0], tokens: val[1]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 264) - def _reduce_67(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 333) + def _reduce_81(val, _values, result) result = val[0].append({tag: val[1], tokens: val[2]}) result end .,., -module_eval(<<'.,.,', 'parser.y', 267) - def _reduce_68(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 336) + def _reduce_82(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 268) - def _reduce_69(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 337) + def _reduce_83(val, _values, result) result = val[0].append(val[1]) result end .,., -# reduce 70 omitted +# reduce 84 omitted -module_eval(<<'.,.,', 'parser.y', 272) - def _reduce_71(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 341) + def _reduce_85(val, _values, result) on_action_error("ident after %prec", val[0]) if @prec_seen result end .,., -module_eval(<<'.,.,', 'parser.y', 273) - def _reduce_72(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 342) + def _reduce_86(val, _values, result) on_action_error("char after %prec", val[0]) if @prec_seen result end .,., -# reduce 73 omitted +# reduce 87 omitted -# reduce 74 omitted +# reduce 88 omitted -# reduce 75 omitted +# reduce 89 omitted -# reduce 76 omitted +# reduce 90 omitted -module_eval(<<'.,.,', 'parser.y', 283) - def _reduce_77(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 352) + def _reduce_91(val, _values, result) lhs = val[0] lhs.alias_name = val[1] val[3].each do |builder| @@ -1710,8 +1867,8 @@ def _reduce_77(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 294) - def _reduce_78(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 363) + def _reduce_92(val, _values, result) builder = val[0] if !builder.line builder.line = @lexer.line - 1 @@ -1722,8 +1879,8 @@ def _reduce_78(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 302) - def _reduce_79(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 371) + def _reduce_93(val, _values, result) builder = val[2] if !builder.line builder.line = @lexer.line - 1 @@ -1734,10 +1891,10 @@ def _reduce_79(val, _values, result) end .,., -# reduce 80 omitted +# reduce 94 omitted -module_eval(<<'.,.,', 'parser.y', 312) - def _reduce_81(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 381) + def _reduce_95(val, _values, result) reset_precs result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter) @@ -1745,8 +1902,8 @@ def _reduce_81(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 317) - def _reduce_82(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 386) + def _reduce_96(val, _values, result) reset_precs result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter) @@ -1754,8 +1911,8 @@ def _reduce_82(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 322) - def _reduce_83(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 391) + def _reduce_97(val, _values, result) token = val[1] token.alias_name = val[2] builder = val[0] @@ -1766,8 +1923,8 @@ def _reduce_83(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 330) - def _reduce_84(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 399) + def _reduce_98(val, _values, result) token = Lrama::Lexer::Token::Parameterizing.new(s_value: val[2], location: @lexer.location, args: [val[1]]) builder = val[0] builder.add_rhs(token) @@ -1779,8 +1936,8 @@ def _reduce_84(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 339) - def _reduce_85(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 408) + def _reduce_99(val, _values, result) token = Lrama::Lexer::Token::Parameterizing.new(s_value: val[1].s_value, location: @lexer.location, args: val[3]) builder = val[0] builder.add_rhs(token) @@ -1792,8 +1949,8 @@ def _reduce_85(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 348) - def _reduce_86(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 417) + def _reduce_100(val, _values, result) if @prec_seen on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec @code_after_prec = true @@ -1804,16 +1961,16 @@ def _reduce_86(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 356) - def _reduce_87(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 425) + def _reduce_101(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 360) - def _reduce_88(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 429) + def _reduce_102(val, _values, result) user_code = val[3] user_code.alias_name = val[6] builder = val[0] @@ -1824,8 +1981,8 @@ def _reduce_88(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 368) - def _reduce_89(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 437) + def _reduce_103(val, _values, result) sym = @grammar.find_symbol_by_id!(val[2]) @prec_seen = true builder = val[0] @@ -1836,41 +1993,41 @@ def _reduce_89(val, _values, result) end .,., -# reduce 90 omitted +# reduce 104 omitted -# reduce 91 omitted +# reduce 105 omitted -# reduce 92 omitted +# reduce 106 omitted -module_eval(<<'.,.,', 'parser.y', 379) - def _reduce_93(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 448) + def _reduce_107(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 380) - def _reduce_94(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 449) + def _reduce_108(val, _values, result) result = val[0].append(val[2]) result end .,., -# reduce 95 omitted +# reduce 109 omitted -module_eval(<<'.,.,', 'parser.y', 383) - def _reduce_96(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 452) + def _reduce_110(val, _values, result) result = val[1].s_value result end .,., -# reduce 97 omitted +# reduce 111 omitted -# reduce 98 omitted +# reduce 112 omitted -module_eval(<<'.,.,', 'parser.y', 390) - def _reduce_99(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 459) + def _reduce_113(val, _values, result) begin_c_declaration('\Z') @grammar.epilogue_first_lineno = @lexer.line + 1 @@ -1878,8 +2035,8 @@ def _reduce_99(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 395) - def _reduce_100(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 464) + def _reduce_114(val, _values, result) end_c_declaration @grammar.epilogue = val[2].s_value @@ -1887,44 +2044,44 @@ def _reduce_100(val, _values, result) end .,., -# reduce 101 omitted +# reduce 115 omitted -# reduce 102 omitted +# reduce 116 omitted -# reduce 103 omitted +# reduce 117 omitted -# reduce 104 omitted +# reduce 118 omitted -# reduce 105 omitted +# reduce 119 omitted -module_eval(<<'.,.,', 'parser.y', 406) - def _reduce_106(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 475) + def _reduce_120(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 407) - def _reduce_107(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 476) + def _reduce_121(val, _values, result) result = val[0].append(val[1]) result end .,., -# reduce 108 omitted +# reduce 122 omitted -# reduce 109 omitted +# reduce 123 omitted -module_eval(<<'.,.,', 'parser.y', 412) - def _reduce_110(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 481) + def _reduce_124(val, _values, result) result = Lrama::Lexer::Token::Ident.new(s_value: val[0]) result end .,., -# reduce 111 omitted +# reduce 125 omitted -# reduce 112 omitted +# reduce 126 omitted def _reduce_none(val, _values, result) val[0] diff --git a/parser.y b/parser.y index b2c3009f..8483cafa 100644 --- a/parser.y +++ b/parser.y @@ -29,6 +29,7 @@ rule | bison_declarations bison_declaration bison_declaration: grammar_declaration + | rule_declaration | "%expect" INTEGER { @grammar.expect = val[1] } | "%define" variable value | "%param" params @@ -202,6 +203,74 @@ rule token_declaration: id int_opt alias { result = val } + rule_declaration: "%rule" IDENTIFIER "(" rule_args ")" ":" rule_rhs_list + { + builder = Grammar::ParameterizingRuleBuilder.new(val[1].s_value, val[3], val[6]) + @grammar.add_parameterizing_rule_builder(builder) + } + + rule_args: IDENTIFIER { result = [val[0]] } + | rule_args "," IDENTIFIER { result = val[0].append(val[2]) } + + rule_rhs_list: rule_rhs + { + builder = val[0] + result = [builder] + } + | rule_rhs_list "|" rule_rhs + { + builder = val[2] + result = val[0].append(builder) + } + | rule_rhs_list ";" + + rule_rhs: /* empty */ + { + reset_precs + result = Grammar::ParameterizingRuleRhsBuilder.new + } + | "%empty" + { + reset_precs + result = Grammar::ParameterizingRuleRhsBuilder.new + } + | rule_rhs symbol named_ref_opt + { + token = val[1] + token.alias_name = val[2] + builder = val[0] + builder.symbol = token + result = builder + } + | rule_rhs "{" + { + if @prec_seen + on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec + @code_after_prec = true + end + begin_c_declaration("}") + } + C_DECLARATION + { + end_c_declaration + } + "}" named_ref_opt + { + user_code = val[3] + user_code.alias_name = val[6] + builder = val[0] + builder.user_code = user_code + result = builder + } + | rule_rhs "%prec" symbol + { + sym = @grammar.find_symbol_by_id!(val[2]) + @prec_seen = true + builder = val[0] + builder.precedence_sym = sym + result = builder + } + int_opt: # empty | INTEGER diff --git a/sig/lrama/grammar/parameterizing_rule_builder.rbs b/sig/lrama/grammar/parameterizing_rule_builder.rbs new file mode 100644 index 00000000..4b96c87e --- /dev/null +++ b/sig/lrama/grammar/parameterizing_rule_builder.rbs @@ -0,0 +1,21 @@ +module Lrama + class Grammar + class ParameterizingRuleBuilder + attr_reader name: String + attr_reader args: Array[Lexer::Token] + attr_reader rhs: Array[Grammar::ParameterizingRuleRhsBuilder] + attr_reader term: Lexer::Token? + + @required_args_count: Integer + + def initialize: (String name, Array[Lexer::Token] args, Array[Grammar::ParameterizingRuleRhsBuilder]) -> void + def build_rules: (Lexer::Token::Parameterizing token, Lexer::Token build_token, Counter rule_counter, untyped lhs_tag, Lexer::Token::UserCode? user_code, Lexer::Token? precedence_sym, Integer? line) -> Array[Rule] + def build_token: (Lexer::Token::Parameterizing token) -> Lexer::Token + + private + + def validate_argument_number!: (Lexer::Token::Parameterizing token) -> void + def rhs_term: (Lexer::Token::Parameterizing token, Grammar::ParameterizingRuleRhsBuilder rh) -> Lexer::Token? + end + end +end diff --git a/sig/lrama/grammar/parameterizing_rule_resolver.rbs b/sig/lrama/grammar/parameterizing_rule_resolver.rbs new file mode 100644 index 00000000..eb39bf00 --- /dev/null +++ b/sig/lrama/grammar/parameterizing_rule_resolver.rbs @@ -0,0 +1,16 @@ +module Lrama + class Grammar + class ParameterizingRuleResolver + attr_reader rules: Array[Rule] + attr_reader tokens: Array[Lexer::Token] + attr_reader term: Lexer::Token? + + @parameterizing_rule_builders: Array[Grammar::ParameterizingRuleBuilder] + + def initialize: () -> void + def add_parameterizing_rule_builder: (Grammar::ParameterizingRuleBuilder builder) -> void + def defined?: (String) -> bool + def build_rules: (Lexer::Token::Parameterizing token, Counter rule_counter, untyped lhs_tag, Lexer::Token::UserCode? user_code, Lexer::Token? precedence_sym, Integer? line) -> void + end + end +end diff --git a/sig/lrama/grammar/parameterizing_rule_rhs_builder.rbs b/sig/lrama/grammar/parameterizing_rule_rhs_builder.rbs new file mode 100644 index 00000000..4571a4aa --- /dev/null +++ b/sig/lrama/grammar/parameterizing_rule_rhs_builder.rbs @@ -0,0 +1,11 @@ +module Lrama + class Grammar + class ParameterizingRuleRhsBuilder + attr_reader symbol: Lexer::Token? + attr_reader user_code: Lexer::Token::UserCode? + attr_reader precedence_sym: Lexer::Token? + + def initialize: () -> void + end + end +end diff --git a/sig/lrama/grammar/rule_builder.rbs b/sig/lrama/grammar/rule_builder.rbs index d57cd486..7522c77f 100644 --- a/sig/lrama/grammar/rule_builder.rbs +++ b/sig/lrama/grammar/rule_builder.rbs @@ -24,7 +24,7 @@ module Lrama def user_code=: (Lexer::Token::UserCode user_code) -> void def precedence_sym=: (Lexer::Token user_code) -> void def complete_input: () -> void - def setup_rules: () -> void + def setup_rules: (Grammar::ParameterizingRuleResolver parameterizing_resolver) -> void def parameterizing_rules: () -> Array[Rule] def midrule_action_rules: () -> Array[Rule] def rules: () -> Array[Rule] @@ -34,7 +34,7 @@ module Lrama def freeze_rhs: () -> void def preprocess_references: () -> void def build_rules: () -> void - def process_rhs: () -> void + def process_rhs: (Grammar::ParameterizingRuleResolver parameterizing_resolver) -> void def numberize_references: () -> void def flush_user_code: () -> void end diff --git a/spec/fixtures/parameterizing_rules/user_defined.y b/spec/fixtures/parameterizing_rules/user_defined.y new file mode 100644 index 00000000..ae67a97a --- /dev/null +++ b/spec/fixtures/parameterizing_rules/user_defined.y @@ -0,0 +1,38 @@ +/* + * 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; +} + +%rule defined_option(X): /* empty */ + | X + ; + +%% + +program : defined_option(number) + ; + +%% + +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/grammar/rule_builder_spec.rb b/spec/lrama/grammar/rule_builder_spec.rb index cb31cdae..2e48ac75 100644 --- a/spec/lrama/grammar/rule_builder_spec.rb +++ b/spec/lrama/grammar/rule_builder_spec.rb @@ -321,7 +321,7 @@ rule_builder.add_rhs(token_6) rule_builder.user_code = token_7 rule_builder.complete_input - rule_builder.setup_rules + rule_builder.setup_rules(Lrama::Grammar::ParameterizingRuleResolver.new) rule = rule_builder.rules.first rules = rule_builder.midrule_action_rules @@ -356,7 +356,7 @@ rule_builder.add_rhs(token_6) rule_builder.user_code = token_7 rule_builder.complete_input - rule_builder.setup_rules + rule_builder.setup_rules(Lrama::Grammar::ParameterizingRuleResolver.new) tokens = rule_builder.instance_variable_get(:@replaced_rhs) diff --git a/spec/lrama/parser_spec.rb b/spec/lrama/parser_spec.rb index 29e9f0f9..ffffde8e 100644 --- a/spec/lrama/parser_spec.rb +++ b/spec/lrama/parser_spec.rb @@ -1216,6 +1216,66 @@ ]) end + it "user defined" do + path = "parameterizing_rules/user_defined.y" + y = File.read(fixture_path(path)) + grammar = Lrama::Parser.new(y, path).parse + + 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: "program"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 1, nullable: true), + Sym.new(id: T::Ident.new(s_value: "defined_option_number"), alias_name: nil, number: 6, tag: T::Tag.new(s_value: ""), term: false, token_id: 2, 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!("program"), + grammar.find_symbol_by_s_value!("YYEOF"), + ], + token_code: nil, + nullable: false, + precedence_sym: grammar.find_symbol_by_s_value!("YYEOF"), + lineno: 21, + ), + Rule.new( + id: 1, + lhs: grammar.find_symbol_by_s_value!("program"), + rhs: [ + grammar.find_symbol_by_s_value!("defined_option_number"), + ], + token_code: nil, + nullable: true, + precedence_sym: nil, + lineno: 21, + ), + Rule.new( + id: 2, + lhs: grammar.find_symbol_by_s_value!("defined_option_number"), + rhs: [], + lhs_tag: T::Tag.new(s_value: ""), + token_code: nil, + nullable: true, + precedence_sym: nil, + lineno: 21, + ), + Rule.new( + id: 3, + lhs: grammar.find_symbol_by_s_value!("defined_option_number"), + rhs: [ + grammar.find_symbol_by_s_value!("number"), + ], + lhs_tag: T::Tag.new(s_value: ""), + token_code: nil, + nullable: false, + precedence_sym: grammar.find_symbol_by_s_value!("number"), + lineno: 21, + ), + ]) + end + context 'when error case' do context "when invalid argument number" do it "raise an error" do