From 2bc3e036ff4495ad4bc960037ceadf267a257549 Mon Sep 17 00:00:00 2001 From: ydah Date: Wed, 1 May 2024 15:27:25 +0900 Subject: [PATCH] Add support for the callee side tag specification of parameterizing rules --- lib/lrama/grammar/parameterizing_rule/rule.rb | 5 +- lib/lrama/grammar/rule_builder.rb | 2 +- lib/lrama/parser.rb | 244 +++++++++--------- parser.y | 4 +- .../grammar/parameterizing_rule/rule.rbs | 3 +- .../user_defined/with_tag.y | 42 +++ spec/lrama/parser_spec.rb | 74 ++++++ 7 files changed, 246 insertions(+), 128 deletions(-) create mode 100644 spec/fixtures/parameterizing_rules/user_defined/with_tag.y diff --git a/lib/lrama/grammar/parameterizing_rule/rule.rb b/lib/lrama/grammar/parameterizing_rule/rule.rb index eb119c00..38f0fca4 100644 --- a/lib/lrama/grammar/parameterizing_rule/rule.rb +++ b/lib/lrama/grammar/parameterizing_rule/rule.rb @@ -2,12 +2,13 @@ module Lrama class Grammar class ParameterizingRule class Rule - attr_reader :name, :parameters, :rhs_list, :required_parameters_count, :is_inline + attr_reader :name, :parameters, :rhs_list, :required_parameters_count, :tag, :is_inline - def initialize(name, parameters, rhs_list, is_inline: false) + def initialize(name, parameters, rhs_list, tag: nil, is_inline: false) @name = name @parameters = parameters @rhs_list = rhs_list + @tag = tag @is_inline = is_inline @required_parameters_count = parameters.count end diff --git a/lib/lrama/grammar/rule_builder.rb b/lib/lrama/grammar/rule_builder.rb index 4ba92bc8..71431682 100644 --- a/lib/lrama/grammar/rule_builder.rb +++ b/lib/lrama/grammar/rule_builder.rb @@ -130,7 +130,7 @@ def process_rhs(parameterizing_rule_resolver) @replaced_rhs << lhs_token parameterizing_rule_resolver.created_lhs_list << lhs_token parameterizing_rule.rhs_list.each do |r| - rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: token.lhs_tag) + rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, 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)) } rule_builder.line = line diff --git a/lib/lrama/parser.rb b/lib/lrama/parser.rb index ee4f0346..04603105 100644 --- a/lib/lrama/parser.rb +++ b/lib/lrama/parser.rb @@ -732,43 +732,43 @@ def raise_parse_error(error_message, location) ##### State transition tables begin ### racc_action_table = [ - 98, 51, 99, 163, 88, 79, 51, 51, 179, 163, - 79, 79, 51, 162, 179, 156, 79, 165, 157, 51, - 3, 50, 180, 165, 70, 51, 8, 50, 180, 79, + 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, - 181, 166, 82, 51, 48, 50, 181, 23, 25, 26, + 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, 196, - 51, 51, 50, 50, 79, 196, 51, 51, 50, 50, - 79, 196, 23, 25, 26, 27, 28, 29, 30, 31, + 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, 196, 51, 51, 50, 50, 79, 196, - 51, 51, 50, 50, 79, 196, 51, 51, 50, 50, + 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, 206, 79, 79, - 51, 51, 206, 206, 79, 79, 51, 51, 50, 50, - 79, 186, 187, 188, 96, 186, 187, 188, 96, 216, - 220, 228, 217, 217, 217, 51, 51, 50, 50, 186, - 187, 188, 57, 58, 59, 60, 61, 62, 63, 64, + 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, 175, 176, 177, 146, 183, 191, 192, - 160, 160, 203, 210, 211, 177, 214, 215, 210, 225, - 210, 227, 96, 96, 210 ] + 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 ] racc_action_check = [ - 49, 145, 49, 145, 39, 145, 159, 182, 159, 182, - 159, 182, 200, 144, 200, 139, 200, 145, 139, 33, - 1, 33, 159, 182, 33, 34, 3, 34, 200, 34, + 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, 182, 38, 15, 14, 15, 200, 9, 9, 9, + 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, @@ -776,22 +776,22 @@ def raise_parse_error(error_message, location) 42, 42, 42, 42, 42, 42, 42, 4, 82, 16, 82, 4, 4, 4, 4, 4, 4, 17, 18, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 193, 109, - 193, 109, 193, 193, 197, 111, 197, 111, 197, 197, - 198, 117, 198, 117, 198, 198, 74, 75, 74, 75, + 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, 181, 183, 181, 183, 181, 183, - 203, 215, 203, 215, 203, 215, 217, 119, 217, 119, - 217, 164, 164, 164, 164, 178, 178, 178, 178, 207, - 213, 222, 207, 213, 222, 134, 138, 134, 138, 208, - 208, 208, 19, 20, 23, 25, 26, 27, 28, 29, + 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, 177, 179, 185, 189, 199, 204, 206, 216, 219, - 220, 221, 225, 227, 229 ] + 175, 178, 180, 186, 190, 200, 205, 207, 213, 217, + 220, 221, 222, 226, 228, 230 ] racc_action_pointer = [ nil, 20, 22, 26, 98, nil, nil, 39, nil, 33, @@ -809,18 +809,18 @@ def raise_parse_error(error_message, location) 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, 221, 259, 220, 3, + 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, 224, nil, 225, 147, 232, - nil, 171, 4, 172, nil, 265, nil, nil, nil, 272, - nil, nil, nil, 135, nil, nil, nil, 141, 147, 230, - 9, nil, nil, 177, 274, nil, 237, 158, 161, nil, - nil, nil, nil, 159, nil, 178, 270, 183, nil, 259, - 272, 261, 160, nil, nil, 231, nil, 232, nil, 276, - nil, nil ] + 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 ] racc_action_default = [ - -2, -138, -8, -138, -138, -3, -4, -138, 232, -138, + -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, @@ -835,75 +835,75 @@ def raise_parse_error(error_message, location) -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, -138, -138, -57, -60, + -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, -62, -59, -62, -120, -94, - -67, -138, -102, -138, -106, -136, -113, -114, -115, -138, - -112, -84, -20, -32, -131, -133, -134, -35, -38, -56, - -61, -64, -65, -138, -138, -70, -94, -138, -116, -107, - -137, -110, -132, -138, -68, -138, -136, -138, -118, -138, - -136, -138, -138, -108, -117, -120, -66, -120, -119, -136, - -69, -111 ] + -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 ] racc_goto_table = [ - 76, 95, 69, 52, 74, 118, 110, 209, 185, 145, - 158, 1, 119, 212, 2, 4, 43, 212, 212, 42, - 91, 72, 202, 84, 84, 84, 84, 80, 85, 86, - 87, 5, 40, 207, 53, 55, 56, 122, 223, 111, - 115, 76, 226, 118, 199, 116, 182, 138, 110, 92, - 10, 231, 218, 213, 193, 197, 198, 72, 72, 11, - 12, 13, 118, 49, 97, 222, 128, 169, 104, 84, - 84, 110, 151, 105, 152, 106, 153, 107, 134, 154, - 76, 108, 115, 155, 137, 68, 73, 112, 135, 139, - 121, 200, 204, 221, 126, 167, 102, 72, 149, 72, - 144, 189, 219, 115, 123, 84, nil, 84, nil, nil, - nil, 164, nil, nil, nil, nil, nil, nil, nil, 184, - nil, nil, 72, nil, nil, 178, 84, nil, nil, nil, - nil, nil, 190, 201, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 205, 164, 208, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 178, nil, nil, 208, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 229, 208, 230, 224 ] + 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 ] racc_goto_check = [ - 42, 43, 33, 35, 49, 56, 34, 46, 44, 60, - 39, 1, 55, 64, 2, 3, 57, 64, 64, 4, - 5, 35, 44, 35, 35, 35, 35, 32, 32, 32, - 32, 6, 7, 45, 15, 15, 15, 8, 46, 33, - 42, 42, 46, 56, 39, 49, 60, 55, 34, 57, - 9, 46, 44, 45, 21, 21, 21, 35, 35, 10, - 11, 12, 56, 13, 14, 45, 16, 17, 18, 35, - 35, 34, 19, 22, 23, 24, 25, 26, 33, 27, - 42, 28, 42, 29, 49, 30, 31, 36, 37, 38, - 40, 41, 47, 48, 51, 52, 53, 35, 54, 35, - 59, 61, 62, 42, 63, 35, nil, 35, nil, nil, - nil, 42, nil, nil, nil, nil, nil, nil, nil, 43, - nil, nil, 35, nil, nil, 42, 35, nil, nil, nil, - nil, nil, 42, 43, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 42, 42, 42, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 42, nil, nil, 42, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 43, 42, 43, 42 ] + 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 ] racc_goto_pointer = [ - nil, 11, 14, 13, 10, -22, 29, 26, -53, 46, - 55, 56, 57, 48, 15, 18, -37, -83, 10, -57, - nil, -118, 14, -56, 15, -55, 16, -53, 19, -50, - 52, 52, -8, -31, -63, -12, 15, -24, -31, -131, - 1, -86, -34, -45, -156, -150, -178, -88, -121, -30, - nil, -7, -53, 42, -29, -70, -76, 7, nil, -24, - -115, -64, -109, 11, -180 ] + 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 ] 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, - 46, 159, 195, nil, nil, nil, nil, nil, nil, nil, + nil, 46, 159, 196, nil, nil, nil, nil, nil, nil, 78, nil, nil, nil, nil, 81, 83, nil, 44, nil, - nil, nil, nil, nil, 194 ] + nil, nil, nil, nil, 195 ] racc_reduce_table = [ 0, 0, :racc_error, @@ -962,21 +962,21 @@ def raise_parse_error(error_message, location) 1, 87, :_reduce_53, 2, 87, :_reduce_54, 3, 88, :_reduce_55, - 7, 65, :_reduce_56, + 8, 65, :_reduce_56, 5, 66, :_reduce_57, 1, 92, :_reduce_58, 3, 92, :_reduce_59, - 1, 93, :_reduce_60, - 3, 93, :_reduce_61, - 0, 95, :_reduce_62, - 1, 95, :_reduce_63, - 3, 95, :_reduce_64, - 3, 95, :_reduce_65, - 6, 95, :_reduce_66, + 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, 95, :_reduce_69, - 3, 95, :_reduce_70, + 7, 96, :_reduce_69, + 3, 96, :_reduce_70, 0, 90, :_reduce_none, 1, 90, :_reduce_none, 0, 91, :_reduce_none, @@ -986,8 +986,8 @@ def raise_parse_error(error_message, location) 3, 85, :_reduce_77, 1, 103, :_reduce_78, 2, 103, :_reduce_79, - 1, 96, :_reduce_none, - 1, 96, :_reduce_none, + 1, 97, :_reduce_none, + 1, 97, :_reduce_none, 0, 105, :_reduce_82, 0, 106, :_reduce_83, 6, 69, :_reduce_84, @@ -1019,16 +1019,16 @@ def raise_parse_error(error_message, location) 0, 116, :_reduce_110, 8, 114, :_reduce_111, 3, 114, :_reduce_112, - 1, 98, :_reduce_113, - 1, 98, :_reduce_114, - 1, 98, :_reduce_115, - 1, 99, :_reduce_116, - 3, 99, :_reduce_117, - 2, 99, :_reduce_118, - 4, 99, :_reduce_119, - 0, 97, :_reduce_none, - 3, 97, :_reduce_121, - 1, 94, :_reduce_none, + 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, @@ -1042,12 +1042,12 @@ def raise_parse_error(error_message, location) 1, 118, :_reduce_none, 1, 118, :_reduce_none, 1, 104, :_reduce_135, - 0, 100, :_reduce_none, - 1, 100, :_reduce_none ] + 0, 93, :_reduce_none, + 1, 93, :_reduce_none ] racc_reduce_n = 138 -racc_shift_n = 232 +racc_shift_n = 233 racc_token_table = { false => 0, @@ -1220,6 +1220,7 @@ def raise_parse_error(error_message, location) "int_opt", "alias", "rule_args", + "tag_opt", "rule_rhs_list", "id_colon", "rule_rhs", @@ -1227,7 +1228,6 @@ def raise_parse_error(error_message, location) "named_ref_opt", "parameterizing_suffix", "parameterizing_args", - "tag_opt", "@15", "@16", "symbol_declaration_list", @@ -1666,7 +1666,7 @@ def _reduce_55(val, _values, result) module_eval(<<'.,.,', 'parser.y', 236) def _reduce_56(val, _values, result) - rule = Grammar::ParameterizingRule::Rule.new(val[1].s_value, val[3], val[6]) + rule = Grammar::ParameterizingRule::Rule.new(val[1].s_value, val[3], val[7], tag: val[5]) @grammar.add_parameterizing_rule(rule) result diff --git a/parser.y b/parser.y index b13c819f..bc507084 100644 --- a/parser.y +++ b/parser.y @@ -232,9 +232,9 @@ rule token_declaration: id int_opt alias { result = val } - rule_declaration: "%rule" IDENTIFIER "(" rule_args ")" ":" rule_rhs_list + rule_declaration: "%rule" IDENTIFIER "(" rule_args ")" tag_opt ":" rule_rhs_list { - rule = Grammar::ParameterizingRule::Rule.new(val[1].s_value, val[3], val[6]) + rule = Grammar::ParameterizingRule::Rule.new(val[1].s_value, val[3], val[7], tag: val[5]) @grammar.add_parameterizing_rule(rule) } diff --git a/sig/lrama/grammar/parameterizing_rule/rule.rbs b/sig/lrama/grammar/parameterizing_rule/rule.rbs index fc5e6915..240ade27 100644 --- a/sig/lrama/grammar/parameterizing_rule/rule.rbs +++ b/sig/lrama/grammar/parameterizing_rule/rule.rbs @@ -6,9 +6,10 @@ module Lrama attr_reader parameters: Array[Lexer::Token] attr_reader rhs_list: Array[Grammar::ParameterizingRule::Rhs] attr_reader required_parameters_count: Integer + attr_reader tag: Lexer::Token::Tag? attr_reader is_inline: bool - def initialize: (String name, Array[Lexer::Token] parameters, Array[Grammar::ParameterizingRule::Rhs] rhs_list, ?is_inline: bool) -> void + def initialize: (String name, Array[Lexer::Token] parameters, Array[Grammar::ParameterizingRule::Rhs] rhs_list, ?tag: Lexer::Token::Tag, ?is_inline: bool) -> void end end end diff --git a/spec/fixtures/parameterizing_rules/user_defined/with_tag.y b/spec/fixtures/parameterizing_rules/user_defined/with_tag.y new file mode 100644 index 00000000..93834898 --- /dev/null +++ b/spec/fixtures/parameterizing_rules/user_defined/with_tag.y @@ -0,0 +1,42 @@ +/* + * 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; + char *s; +} + +%token number +%token string + +%rule with_tag(X) : X { $$ = $1; } + ; + +%% + +program : with_tag(number) + | with_tag(string) + ; + +%% + +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 2ffbde8b..3a17994f 100644 --- a/spec/lrama/parser_spec.rb +++ b/spec/lrama/parser_spec.rb @@ -1461,6 +1461,80 @@ end end + context "with tag" do + let(:path) { "parameterizing_rules/user_defined/with_tag.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: 5, tag: nil, term: false, token_id: 0, nullable: false), + Sym.new(id: T::Ident.new(s_value: "with_tag_number"), alias_name: nil, number: 6, tag: T::Tag.new(s_value: ""), term: false, token_id: 1, nullable: false), + Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: false), + Sym.new(id: T::Ident.new(s_value: "with_tag_string"), alias_name: nil, number: 8, tag: T::Tag.new(s_value: ""), term: false, token_id: 3, nullable: false), + ]) + + 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: 24, + ), + Rule.new( + id: 1, + lhs: grammar.find_symbol_by_s_value!("with_tag_number"), + rhs: [ + grammar.find_symbol_by_s_value!("number"), + ], + lhs_tag: T::Tag.new(s_value: ""), + token_code: T::UserCode.new(s_value: " $$ = $1; "), + nullable: false, + precedence_sym: grammar.find_symbol_by_s_value!("number"), + lineno: 24, + ), + Rule.new( + id: 2, + lhs: grammar.find_symbol_by_s_value!("program"), + rhs: [ + grammar.find_symbol_by_s_value!("with_tag_number"), + ], + token_code: nil, + nullable: false, + precedence_sym: nil, + lineno: 24, + ), + Rule.new( + id: 3, + lhs: grammar.find_symbol_by_s_value!("with_tag_string"), + rhs: [ + grammar.find_symbol_by_s_value!("string"), + ], + lhs_tag: T::Tag.new(s_value: ""), + token_code: T::UserCode.new(s_value: " $$ = $1; "), + nullable: false, + precedence_sym: grammar.find_symbol_by_s_value!("string"), + lineno: 25, + ), + Rule.new( + id: 4, + lhs: grammar.find_symbol_by_s_value!("program"), + rhs: [ + grammar.find_symbol_by_s_value!("with_tag_string"), + ], + token_code: nil, + nullable: false, + precedence_sym: nil, + lineno: 25, + ), + ]) + end + end + context "when multi arguments" do let(:path) { "parameterizing_rules/user_defined/multi_arguments.y" }