diff --git a/NEWS.md b/NEWS.md index 12244326..4b9f40e1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,39 @@ # NEWS for Lrama +## Lrama 0.6.3 (2024-02-xx) + +### Bring Your Own Stack + +Provide functionalities for Bring Your Own Stack. + +Ruby’s Ripper library requires their own semantic value stack to manage Ruby Objects returned by user defined callback method. Currently Ripper uses semantic value stack (`yyvsa`) which is used by parser to manage Node. This hack introduces some limitation on Ripper. For example, Ripper can not execute semantic analysis depending on Node structure. + +Lrama introduces two features to support another semantic value stack by parser generator users. + +1. Callback entry points + +User can emulate semantic value stack by these callbacks. +Lrama provides these five callbacks. Registered functions are called when each event happen. For example %after-shift function is called when shift happens on original semantic value stack. + +* `%after-shift` function_name +* `%before-reduce` function_name +* `%after-reduce` function_name +* `%after-shift-error-token` function_name +* `%after-pop-stack` function_name + +2. `$:n` variable to access index of each grammar symbols + +User also needs to access semantic value of their stack in grammar action. `$:n` provides the way to access to it. `$:n` is translated to the minus index from the top of the stack. +For example + +``` +primary: k_if expr_value then compstmt if_tail k_end + { + /*% ripper: if!($:2, $:4, $:5) %*/ + /* $:2 = -5, $:4 = -3, $:5 = -2. */ + } +``` + ## Lrama 0.6.2 (2024-01-27) ### %no-stdlib directive diff --git a/lib/lrama/grammar.rb b/lib/lrama/grammar.rb index 008cdfb1..7ccde1aa 100644 --- a/lib/lrama/grammar.rb +++ b/lib/lrama/grammar.rb @@ -26,6 +26,7 @@ class Grammar attr_accessor :union, :expect, :printers, :error_tokens, :lex_param, :parse_param, :initial_action, + :after_shift, :before_reduce, :after_reduce, :after_shift_error_token, :after_pop_stack, :symbols_resolver, :types, :rules, :rule_builders, :sym_to_rules, :no_stdlib diff --git a/lib/lrama/grammar/code/initial_action_code.rb b/lib/lrama/grammar/code/initial_action_code.rb index 2b064f27..a694f193 100644 --- a/lib/lrama/grammar/code/initial_action_code.rb +++ b/lib/lrama/grammar/code/initial_action_code.rb @@ -6,18 +6,24 @@ class InitialActionCode < Code # * ($$) yylval # * (@$) yylloc + # * ($:$) error # * ($1) error # * (@1) error + # * ($:1) error def reference_to_c(ref) case when ref.type == :dollar && ref.name == "$" # $$ "yylval" when ref.type == :at && ref.name == "$" # @$ "yylloc" + when ref.type == :index && ref.name == "$" # $:$ + raise "$:#{ref.value} can not be used in initial_action." when ref.type == :dollar # $n raise "$#{ref.value} can not be used in initial_action." when ref.type == :at # @n raise "@#{ref.value} can not be used in initial_action." + when ref.type == :index # $:n + raise "$:#{ref.value} can not be used in initial_action." else raise "Unexpected. #{self}, #{ref}" end diff --git a/lib/lrama/grammar/code/no_reference_code.rb b/lib/lrama/grammar/code/no_reference_code.rb index ac6cdb8f..6e614cc6 100644 --- a/lib/lrama/grammar/code/no_reference_code.rb +++ b/lib/lrama/grammar/code/no_reference_code.rb @@ -6,14 +6,18 @@ class NoReferenceCode < Code # * ($$) error # * (@$) error + # * ($:$) error # * ($1) error # * (@1) error + # * ($:1) error def reference_to_c(ref) case when ref.type == :dollar # $$, $n raise "$#{ref.value} can not be used in #{type}." when ref.type == :at # @$, @n raise "@#{ref.value} can not be used in #{type}." + when ref.type == :index # $:$, $:n + raise "$:#{ref.value} can not be used in #{type}." else raise "Unexpected. #{self}, #{ref}" end diff --git a/lib/lrama/grammar/code/printer_code.rb b/lib/lrama/grammar/code/printer_code.rb index 2b1f127f..ffccd893 100644 --- a/lib/lrama/grammar/code/printer_code.rb +++ b/lib/lrama/grammar/code/printer_code.rb @@ -11,8 +11,10 @@ def initialize(type:, token_code:, tag:) # * ($$) *yyvaluep # * (@$) *yylocationp + # * ($:$) error # * ($1) error # * (@1) error + # * ($:1) error def reference_to_c(ref) case when ref.type == :dollar && ref.name == "$" # $$ @@ -20,10 +22,14 @@ def reference_to_c(ref) "((*yyvaluep).#{member})" when ref.type == :at && ref.name == "$" # @$ "(*yylocationp)" + when ref.type == :index && ref.name == "$" # $:$ + raise "$:#{ref.value} can not be used in #{type}." when ref.type == :dollar # $n raise "$#{ref.value} can not be used in #{type}." when ref.type == :at # @n raise "@#{ref.value} can not be used in #{type}." + when ref.type == :index # $:n + raise "$:#{ref.value} can not be used in #{type}." else raise "Unexpected. #{self}, #{ref}" end diff --git a/lib/lrama/grammar/code/rule_action.rb b/lib/lrama/grammar/code/rule_action.rb index 44194db0..d3c0eab6 100644 --- a/lib/lrama/grammar/code/rule_action.rb +++ b/lib/lrama/grammar/code/rule_action.rb @@ -11,8 +11,10 @@ def initialize(type:, token_code:, rule:) # * ($$) yyval # * (@$) yyloc + # * ($:$) error # * ($1) yyvsp[i] # * (@1) yylsp[i] + # * ($:1) i - 1 # # # Consider a rule like @@ -24,6 +26,8 @@ def initialize(type:, token_code:, rule:) # "Rule" class: keyword_class { $1 } tSTRING { $2 + $3 } keyword_end { $class = $1 + $keyword_end } # "Position in grammar" $1 $2 $3 $4 $5 # "Index for yyvsp" -4 -3 -2 -1 0 + # "$:n" $:1 $:2 $:3 $:4 $:5 + # "index of $:n" -5 -4 -3 -2 -1 # # # For the first midrule action: @@ -31,6 +35,7 @@ def initialize(type:, token_code:, rule:) # "Rule" class: keyword_class { $1 } tSTRING { $2 + $3 } keyword_end { $class = $1 + $keyword_end } # "Position in grammar" $1 # "Index for yyvsp" 0 + # "$:n" $:1 def reference_to_c(ref) case when ref.type == :dollar && ref.name == "$" # $$ @@ -39,6 +44,8 @@ def reference_to_c(ref) "(yyval.#{tag.member})" when ref.type == :at && ref.name == "$" # @$ "(yyloc)" + when ref.type == :index && ref.name == "$" # $:$ + raise "$:$ is not supported" when ref.type == :dollar # $n i = -position_in_rhs + ref.index tag = ref.ex_tag || rhs[ref.index - 1].tag @@ -47,6 +54,9 @@ def reference_to_c(ref) when ref.type == :at # @n i = -position_in_rhs + ref.index "(yylsp[#{i}])" + when ref.type == :index # $:n + i = -position_in_rhs + ref.index + "(#{i} - 1)" else raise "Unexpected. #{self}, #{ref}" end diff --git a/lib/lrama/lexer.rb b/lib/lrama/lexer.rb index b94fad57..33f37eb6 100644 --- a/lib/lrama/lexer.rb +++ b/lib/lrama/lexer.rb @@ -27,6 +27,11 @@ class Lexer %precedence %prec %error-token + %before-reduce + %after-reduce + %after-shift-error-token + %after-shift + %after-pop-stack %empty %code %rule diff --git a/lib/lrama/lexer/token/user_code.rb b/lib/lrama/lexer/token/user_code.rb index 1c0376c8..5836f6ee 100644 --- a/lib/lrama/lexer/token/user_code.rb +++ b/lib/lrama/lexer/token/user_code.rb @@ -56,6 +56,17 @@ def scan_reference(scanner) return Lrama::Grammar::Reference.new(type: :at, name: scanner[1], first_column: start, last_column: scanner.pos) when scanner.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @[expr.right], @[expr-right] (named reference with brackets) return Lrama::Grammar::Reference.new(type: :at, name: scanner[1], first_column: start, last_column: scanner.pos) + + # $: references + when scanner.scan(/\$:\$/) # $:$ + return Lrama::Grammar::Reference.new(type: :index, name: "$", first_column: start, last_column: scanner.pos) + when scanner.scan(/\$:(\d+)/) # $:1 + return Lrama::Grammar::Reference.new(type: :index, index: Integer(scanner[1]), first_column: start, last_column: scanner.pos) + when scanner.scan(/\$:([a-zA-Z_][a-zA-Z0-9_]*)/) # $:foo, $:expr (named reference without brackets) + return Lrama::Grammar::Reference.new(type: :index, name: scanner[1], first_column: start, last_column: scanner.pos) + when scanner.scan(/\$:\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $:[expr.right], $:[expr-right] (named reference with brackets) + return Lrama::Grammar::Reference.new(type: :index, name: scanner[1], first_column: start, last_column: scanner.pos) + end end end diff --git a/lib/lrama/output.rb b/lib/lrama/output.rb index c4c7c0bb..29bf1e69 100644 --- a/lib/lrama/output.rb +++ b/lib/lrama/output.rb @@ -161,6 +161,61 @@ def user_initial_action(comment = "") STR end + def after_shift_function(comment = "") + return "" unless @grammar.after_shift + + <<-STR + #{comment} +#line #{@grammar.after_shift.line} "#{@grammar_file_path}" + {#{@grammar.after_shift.s_value}(#{parse_param_name});} +#line [@oline@] [@ofile@] + STR + end + + def before_reduce_function(comment = "") + return "" unless @grammar.before_reduce + + <<-STR + #{comment} +#line #{@grammar.before_reduce.line} "#{@grammar_file_path}" + {#{@grammar.before_reduce.s_value}(yylen#{user_args});} +#line [@oline@] [@ofile@] + STR + end + + def after_reduce_function(comment = "") + return "" unless @grammar.after_reduce + + <<-STR + #{comment} +#line #{@grammar.after_reduce.line} "#{@grammar_file_path}" + {#{@grammar.after_reduce.s_value}(yylen#{user_args});} +#line [@oline@] [@ofile@] + STR + end + + def after_shift_error_token_function(comment = "") + return "" unless @grammar.after_shift_error_token + + <<-STR + #{comment} +#line #{@grammar.after_shift_error_token.line} "#{@grammar_file_path}" + {#{@grammar.after_shift_error_token.s_value}(#{parse_param_name});} +#line [@oline@] [@ofile@] + STR + end + + def after_pop_stack_function(len, comment = "") + return "" unless @grammar.after_pop_stack + + <<-STR + #{comment} +#line #{@grammar.after_pop_stack.line} "#{@grammar_file_path}" + {#{@grammar.after_pop_stack.s_value}(#{len}#{user_args});} +#line [@oline@] [@ofile@] + STR + end + def symbol_actions_for_error_token str = "" diff --git a/lib/lrama/parser.rb b/lib/lrama/parser.rb index e5f2384e..148457f1 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', 501) +module_eval(<<'...end parser.y/module_eval...', 'parser.y', 521) include Lrama::Report::Duration @@ -732,303 +732,316 @@ def raise_parse_error(error_message, location) ##### State transition tables begin ### racc_action_table = [ - 86, 45, 87, 146, 145, 68, 45, 45, 146, 189, - 68, 68, 45, 6, 189, 7, 68, 148, 200, 45, - 144, 44, 148, 190, 59, 164, 165, 166, 190, 3, - 45, 41, 44, 8, 68, 64, 35, 42, 45, 149, - 44, 41, 88, 71, 149, 191, 81, 45, 48, 44, - 191, 22, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 22, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 9, 45, 48, 44, 13, 14, 15, 16, 17, - 18, 48, 51, 19, 20, 21, 22, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 45, 45, 44, - 44, 52, 71, 71, 45, 45, 44, 44, 45, 71, - 44, 53, 68, 174, 45, 45, 44, 44, 68, 174, - 45, 45, 44, 44, 68, 174, 45, 45, 44, 44, - 68, 174, 45, 45, 44, 44, 68, 174, 45, 45, - 44, 44, 68, 174, 45, 45, 44, 44, 68, 68, - 45, 45, 44, 44, 68, 68, 45, 45, 44, 44, - 68, 68, 45, 45, 180, 44, 68, 68, 45, 45, - 180, 44, 68, 68, 45, 45, 180, 44, 68, 164, - 165, 166, 84, 45, 45, 44, 44, 142, 193, 143, - 194, 164, 165, 166, 209, 211, 194, 194, 54, 55, - 56, 77, 78, 82, 84, 89, 89, 89, 91, 97, - 101, 102, 105, 105, 105, 105, 108, 111, 112, 114, - 116, 117, 118, 119, 120, 123, 127, 128, 129, 132, - 133, 134, 136, 151, 153, 154, 155, 156, 157, 158, - 159, 132, 161, 169, 170, 179, 184, 185, 187, 192, - 179, 84, 184, 206, 208, 84, 213, 84 ] + 96, 50, 97, 156, 155, 78, 50, 50, 156, 199, + 78, 78, 50, 50, 199, 49, 78, 158, 69, 6, + 3, 7, 158, 200, 210, 154, 8, 50, 200, 49, + 40, 174, 175, 176, 47, 50, 46, 49, 53, 78, + 74, 50, 53, 49, 159, 53, 81, 98, 56, 159, + 201, 174, 175, 176, 94, 201, 22, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 46, 50, 50, 49, 49, 91, 81, 81, 50, + 50, 49, 49, 50, 81, 49, 57, 78, 184, 58, + 59, 22, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 9, 50, 60, 49, + 13, 14, 15, 16, 17, 18, 61, 62, 19, 20, + 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 50, 50, 49, + 49, 78, 184, 50, 50, 49, 49, 78, 184, 50, + 50, 49, 49, 78, 184, 50, 50, 49, 49, 78, + 184, 50, 50, 49, 49, 78, 184, 50, 50, 49, + 49, 78, 78, 50, 50, 49, 49, 78, 78, 50, + 50, 49, 49, 78, 78, 50, 50, 190, 49, 78, + 78, 50, 50, 190, 49, 78, 78, 50, 50, 190, + 49, 78, 50, 50, 49, 49, 152, 203, 153, 204, + 174, 175, 176, 219, 221, 204, 204, 63, 64, 65, + 66, 87, 88, 92, 94, 99, 99, 99, 101, 107, + 111, 112, 115, 115, 115, 115, 118, 121, 122, 124, + 126, 127, 128, 129, 130, 133, 137, 138, 139, 142, + 143, 144, 146, 161, 163, 164, 165, 166, 167, 168, + 169, 142, 171, 179, 180, 189, 194, 195, 197, 202, + 189, 94, 194, 216, 218, 94, 223, 94 ] racc_action_check = [ - 43, 131, 43, 131, 130, 131, 160, 178, 160, 178, - 160, 178, 197, 2, 197, 2, 197, 131, 189, 27, - 130, 27, 160, 178, 27, 189, 189, 189, 197, 1, - 28, 9, 28, 3, 28, 28, 7, 13, 29, 131, - 29, 36, 43, 29, 160, 178, 36, 14, 15, 14, - 197, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 4, 58, 16, 58, 4, 4, 4, 4, 4, - 4, 17, 18, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 30, 31, 30, - 31, 19, 30, 31, 32, 59, 32, 59, 155, 32, - 155, 22, 155, 155, 156, 70, 156, 70, 156, 156, - 157, 71, 157, 71, 157, 157, 171, 97, 171, 97, - 171, 171, 175, 99, 175, 99, 175, 175, 176, 105, - 176, 105, 176, 176, 63, 64, 63, 64, 63, 64, - 102, 104, 102, 104, 102, 104, 124, 149, 124, 149, - 124, 149, 161, 191, 161, 191, 161, 191, 192, 194, - 192, 194, 192, 194, 200, 107, 200, 107, 200, 147, - 147, 147, 147, 121, 125, 121, 125, 126, 181, 126, - 181, 182, 182, 182, 203, 207, 203, 207, 24, 25, - 26, 33, 34, 39, 40, 47, 49, 50, 51, 57, - 61, 62, 69, 74, 75, 76, 77, 83, 84, 90, - 92, 93, 94, 95, 96, 100, 108, 109, 110, 111, - 112, 113, 115, 135, 137, 138, 139, 140, 141, 142, - 143, 144, 146, 150, 152, 158, 163, 167, 177, 180, - 187, 188, 193, 196, 201, 206, 212, 213 ] + 48, 141, 48, 141, 140, 141, 170, 188, 170, 188, + 170, 188, 207, 32, 207, 32, 207, 141, 32, 2, + 1, 2, 170, 188, 199, 140, 3, 14, 207, 14, + 7, 199, 199, 199, 13, 33, 9, 33, 15, 33, + 33, 34, 16, 34, 141, 17, 34, 48, 18, 170, + 188, 157, 157, 157, 157, 207, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 41, 35, 36, 35, 36, 41, 35, 36, 37, + 68, 37, 68, 165, 37, 165, 19, 165, 165, 22, + 24, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 4, 69, 25, 69, + 4, 4, 4, 4, 4, 4, 26, 27, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 166, 80, 166, + 80, 166, 166, 167, 81, 167, 81, 167, 167, 181, + 107, 181, 107, 181, 181, 185, 109, 185, 109, 185, + 185, 186, 115, 186, 115, 186, 186, 73, 74, 73, + 74, 73, 74, 112, 114, 112, 114, 112, 114, 134, + 159, 134, 159, 134, 159, 171, 201, 171, 201, 171, + 201, 202, 204, 202, 204, 202, 204, 210, 117, 210, + 117, 210, 131, 135, 131, 135, 136, 191, 136, 191, + 192, 192, 192, 213, 217, 213, 217, 28, 29, 30, + 31, 38, 39, 44, 45, 52, 54, 55, 56, 67, + 71, 72, 79, 84, 85, 86, 87, 93, 94, 100, + 102, 103, 104, 105, 106, 110, 118, 119, 120, 121, + 122, 123, 125, 145, 147, 148, 149, 150, 151, 152, + 153, 154, 156, 160, 162, 168, 173, 177, 187, 190, + 197, 198, 203, 206, 211, 216, 222, 223 ] racc_action_pointer = [ - nil, 29, 3, 33, 62, nil, nil, 29, nil, 27, - nil, nil, nil, 31, 44, 29, 54, 62, 77, 82, - nil, nil, 92, nil, 179, 180, 181, 16, 27, 35, - 94, 95, 101, 196, 200, nil, 37, nil, nil, 180, - 159, nil, nil, -5, nil, nil, nil, 186, nil, 187, - 188, 189, nil, nil, nil, nil, nil, 201, 69, 102, - nil, 204, 203, 141, 142, nil, nil, nil, nil, 204, - 112, 118, nil, nil, 205, 206, 207, 181, nil, nil, - nil, nil, nil, 180, 213, nil, nil, nil, nil, nil, - 217, nil, 218, 219, 220, 221, 222, 124, nil, 130, - 218, nil, 147, nil, 148, 136, nil, 172, 221, 216, - 226, 189, 184, 229, nil, 230, nil, nil, nil, nil, - nil, 180, nil, nil, 153, 181, 151, nil, nil, nil, - -19, -2, nil, nil, nil, 213, nil, 214, 215, 216, - 217, 218, 202, 235, 201, nil, 207, 137, nil, 154, - 223, nil, 224, nil, nil, 105, 111, 117, 205, nil, - 3, 159, nil, 238, nil, nil, nil, 245, nil, nil, - nil, 123, nil, nil, nil, 129, 135, 209, 4, nil, - 214, 152, 149, nil, nil, nil, nil, 210, 206, -17, - nil, 160, 165, 244, 166, nil, 233, 9, nil, nil, - 171, 252, nil, 158, nil, nil, 210, 159, nil, nil, - nil, nil, 236, 212, nil ] + nil, 20, 9, 26, 97, nil, nil, 23, nil, 32, + nil, nil, nil, 28, 24, 19, 23, 26, 43, 67, + nil, nil, 70, nil, 71, 89, 97, 112, 212, 213, + 214, 215, 10, 32, 38, 69, 70, 76, 216, 220, + nil, 67, nil, nil, 200, 174, nil, nil, -5, nil, + nil, nil, 206, nil, 207, 208, 209, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 221, 77, 104, + nil, 224, 223, 164, 165, nil, nil, nil, nil, 224, + 135, 141, nil, nil, 225, 226, 227, 196, nil, nil, + nil, nil, nil, 195, 233, nil, nil, nil, nil, nil, + 237, nil, 238, 239, 240, 241, 242, 147, nil, 153, + 238, nil, 170, nil, 171, 159, nil, 195, 241, 236, + 246, 204, 199, 249, nil, 250, nil, nil, nil, nil, + nil, 199, nil, nil, 176, 200, 165, nil, nil, nil, + -19, -2, nil, nil, nil, 233, nil, 234, 235, 236, + 237, 238, 217, 255, 216, nil, 222, 4, nil, 177, + 243, nil, 244, nil, nil, 80, 134, 140, 220, nil, + 3, 182, nil, 258, nil, nil, nil, 265, nil, nil, + nil, 146, nil, nil, nil, 152, 158, 224, 4, nil, + 229, 166, 163, nil, nil, nil, nil, 225, 221, -16, + nil, 183, 188, 264, 189, nil, 253, 9, nil, nil, + 194, 272, nil, 172, nil, nil, 225, 173, nil, nil, + nil, nil, 256, 227, nil ] racc_action_default = [ - -2, -131, -8, -131, -131, -3, -4, -131, 215, -131, - -9, -10, -11, -131, -131, -131, -131, -131, -131, -131, - -23, -24, -131, -28, -131, -131, -131, -131, -131, -131, - -131, -131, -131, -131, -131, -7, -116, -89, -91, -131, - -113, -115, -12, -120, -87, -88, -119, -14, -78, -15, - -16, -131, -20, -25, -29, -32, -35, -38, -44, -131, - -47, -64, -39, -68, -131, -71, -73, -74, -128, -40, - -81, -131, -84, -86, -41, -42, -43, -131, -5, -1, - -90, -117, -92, -131, -131, -13, -121, -122, -123, -75, - -131, -17, -131, -131, -131, -131, -131, -131, -48, -45, - -66, -65, -131, -72, -69, -131, -85, -82, -131, -131, - -131, -97, -131, -131, -79, -131, -21, -26, -30, -33, - -36, -46, -49, -67, -70, -83, -131, -51, -6, -118, - -93, -94, -98, -114, -76, -131, -18, -131, -131, -131, - -131, -131, -131, -131, -97, -96, -87, -113, -102, -131, - -131, -80, -131, -22, -27, -131, -131, -131, -55, -52, - -95, -131, -99, -129, -106, -107, -108, -131, -105, -77, - -19, -31, -124, -126, -127, -34, -37, -50, -53, -56, - -87, -131, -109, -100, -130, -103, -125, -55, -113, -87, - -60, -131, -131, -129, -131, -111, -131, -54, -57, -58, - -131, -131, -63, -131, -101, -110, -113, -131, -61, -112, - -104, -59, -131, -113, -62 ] + -2, -136, -8, -136, -136, -3, -4, -136, 225, -136, + -9, -10, -11, -136, -136, -136, -136, -136, -136, -136, + -23, -24, -136, -28, -136, -136, -136, -136, -136, -136, + -136, -136, -136, -136, -136, -136, -136, -136, -136, -136, + -7, -121, -94, -96, -136, -118, -120, -12, -125, -92, + -93, -124, -14, -83, -15, -16, -136, -20, -25, -29, + -32, -35, -38, -39, -40, -41, -42, -43, -49, -136, + -52, -69, -44, -73, -136, -76, -78, -79, -133, -45, + -86, -136, -89, -91, -46, -47, -48, -136, -5, -1, + -95, -122, -97, -136, -136, -13, -126, -127, -128, -80, + -136, -17, -136, -136, -136, -136, -136, -136, -53, -50, + -71, -70, -136, -77, -74, -136, -90, -87, -136, -136, + -136, -102, -136, -136, -84, -136, -21, -26, -30, -33, + -36, -51, -54, -72, -75, -88, -136, -56, -6, -123, + -98, -99, -103, -119, -81, -136, -18, -136, -136, -136, + -136, -136, -136, -136, -102, -101, -92, -118, -107, -136, + -136, -85, -136, -22, -27, -136, -136, -136, -60, -57, + -100, -136, -104, -134, -111, -112, -113, -136, -110, -82, + -19, -31, -129, -131, -132, -34, -37, -55, -58, -61, + -92, -136, -114, -105, -135, -108, -130, -60, -118, -92, + -65, -136, -136, -134, -136, -116, -136, -59, -62, -63, + -136, -136, -68, -136, -106, -115, -118, -136, -66, -117, + -109, -64, -136, -118, -67 ] racc_goto_table = [ - 83, 63, 46, 58, 98, 65, 106, 163, 183, 37, - 178, 1, 2, 181, 107, 61, 4, 73, 73, 73, - 73, 131, 186, 47, 49, 50, 186, 186, 69, 74, - 75, 76, 171, 175, 176, 99, 80, 104, 204, 197, - 103, 65, 195, 106, 203, 98, 61, 61, 125, 199, - 36, 79, 207, 5, 160, 34, 109, 10, 73, 73, - 11, 106, 12, 43, 85, 115, 152, 98, 92, 137, - 93, 138, 94, 121, 139, 124, 95, 140, 96, 65, - 141, 103, 57, 62, 100, 61, 122, 61, 126, 177, - 201, 212, 113, 73, 150, 73, 90, 135, 130, 167, - 196, 103, 110, nil, nil, nil, nil, 162, 147, 61, - nil, nil, nil, 73, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 168, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 147, 182, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 198, nil, - nil, nil, nil, nil, nil, 188, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 210, nil, 202, 182, - nil, 205, nil, 214, 188, nil, nil, 182 ] + 93, 51, 73, 68, 116, 75, 108, 173, 193, 1, + 188, 196, 2, 191, 117, 196, 196, 141, 4, 71, + 41, 83, 83, 83, 83, 42, 79, 84, 85, 86, + 52, 54, 55, 181, 185, 186, 89, 5, 214, 207, + 109, 116, 205, 114, 213, 113, 75, 108, 135, 209, + 170, 39, 217, 119, 10, 71, 71, 90, 11, 116, + 12, 48, 95, 125, 162, 102, 147, 83, 83, 108, + 103, 148, 104, 149, 105, 150, 106, 151, 131, 67, + 72, 134, 110, 132, 75, 136, 113, 187, 211, 222, + 123, 160, 100, 145, 71, 140, 71, 177, 206, 120, + nil, nil, 83, nil, 83, nil, 113, nil, nil, nil, + nil, nil, 172, 157, nil, nil, nil, nil, 71, nil, + nil, nil, 83, nil, nil, nil, nil, nil, nil, nil, + nil, 178, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 157, 192, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 208, nil, nil, nil, nil, nil, nil, + 198, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 220, nil, 212, 192, nil, 215, nil, 224, 198, + nil, nil, 192 ] racc_goto_check = [ - 41, 46, 34, 32, 33, 40, 53, 42, 59, 54, - 39, 1, 2, 43, 52, 34, 3, 34, 34, 34, - 34, 58, 63, 14, 14, 14, 63, 63, 31, 31, - 31, 31, 20, 20, 20, 32, 54, 46, 59, 39, - 40, 40, 42, 53, 43, 33, 34, 34, 52, 42, - 4, 5, 43, 6, 58, 7, 8, 9, 34, 34, - 10, 53, 11, 12, 13, 15, 16, 33, 17, 18, - 21, 22, 23, 32, 24, 46, 25, 26, 27, 40, - 28, 40, 29, 30, 35, 34, 36, 34, 37, 38, - 44, 45, 48, 34, 49, 34, 50, 51, 57, 60, - 61, 40, 62, nil, nil, nil, nil, 41, 40, 34, - nil, nil, nil, 34, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 40, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 40, 40, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 41, nil, - nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 41, nil, 40, 40, - nil, 40, nil, 41, 40, nil, nil, 40 ] + 41, 34, 46, 32, 53, 40, 33, 42, 59, 1, + 39, 63, 2, 43, 52, 63, 63, 58, 3, 34, + 4, 34, 34, 34, 34, 54, 31, 31, 31, 31, + 14, 14, 14, 20, 20, 20, 5, 6, 59, 39, + 32, 53, 42, 46, 43, 40, 40, 33, 52, 42, + 58, 7, 43, 8, 9, 34, 34, 54, 10, 53, + 11, 12, 13, 15, 16, 17, 18, 34, 34, 33, + 21, 22, 23, 24, 25, 26, 27, 28, 32, 29, + 30, 46, 35, 36, 40, 37, 40, 38, 44, 45, + 48, 49, 50, 51, 34, 57, 34, 60, 61, 62, + nil, nil, 34, nil, 34, nil, 40, nil, nil, nil, + nil, nil, 41, 40, nil, nil, nil, nil, 34, nil, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 40, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 41, nil, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 41, nil, 40, 40, nil, 40, nil, 41, 40, + nil, nil, 40 ] racc_goto_pointer = [ - nil, 11, 12, 14, 41, 15, 51, 49, -22, 53, - 56, 58, 49, 21, 8, -26, -70, 16, -47, nil, - -123, 17, -46, 18, -44, 21, -42, 22, -40, 55, - 55, -1, -24, -54, -12, 23, -14, -20, -69, -148, - -23, -40, -140, -148, -100, -117, -27, nil, 3, -40, - 48, -17, -57, -64, 0, nil, nil, -13, -90, -155, - -49, -85, 21, -149 ] + nil, 9, 12, 16, 11, -5, 35, 45, -35, 50, + 54, 56, 47, 14, 15, -38, -82, 8, -60, nil, + -132, 12, -56, 13, -55, 14, -54, 15, -53, 47, + 47, -8, -29, -62, -13, 11, -27, -33, -81, -158, + -28, -45, -150, -158, -112, -129, -31, nil, -9, -53, + 39, -31, -67, -76, 16, nil, nil, -26, -104, -165, + -61, -97, 8, -170 ] racc_goto_default = [ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 39, nil, nil, nil, nil, nil, nil, nil, nil, 23, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 23, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, 60, 66, nil, nil, nil, nil, nil, - 173, nil, nil, nil, nil, nil, nil, 67, nil, nil, - nil, nil, 70, 72, nil, 38, 40, nil, nil, nil, - nil, nil, nil, 172 ] + nil, nil, nil, 70, 76, nil, nil, nil, nil, nil, + 183, nil, nil, nil, nil, nil, nil, 77, nil, nil, + nil, nil, 80, 82, nil, 43, 45, nil, nil, nil, + nil, nil, nil, 182 ] racc_reduce_table = [ 0, 0, :racc_error, - 5, 49, :_reduce_none, - 0, 50, :_reduce_none, - 2, 50, :_reduce_none, - 0, 55, :_reduce_4, - 0, 56, :_reduce_5, - 5, 54, :_reduce_6, - 2, 54, :_reduce_none, - 0, 51, :_reduce_8, - 2, 51, :_reduce_none, - 1, 57, :_reduce_none, - 1, 57, :_reduce_none, - 2, 57, :_reduce_12, - 3, 57, :_reduce_none, - 2, 57, :_reduce_none, - 2, 57, :_reduce_15, - 2, 57, :_reduce_16, - 0, 63, :_reduce_17, - 0, 64, :_reduce_18, - 7, 57, :_reduce_19, - 0, 65, :_reduce_20, - 0, 66, :_reduce_21, - 6, 57, :_reduce_22, - 1, 57, :_reduce_23, - 1, 57, :_reduce_none, - 0, 69, :_reduce_25, - 0, 70, :_reduce_26, - 6, 58, :_reduce_27, - 1, 58, :_reduce_none, - 0, 71, :_reduce_29, - 0, 72, :_reduce_30, - 7, 58, :_reduce_none, - 0, 73, :_reduce_32, - 0, 74, :_reduce_33, - 7, 58, :_reduce_34, - 0, 75, :_reduce_35, - 0, 76, :_reduce_36, - 7, 58, :_reduce_37, - 2, 67, :_reduce_none, - 2, 67, :_reduce_39, - 2, 67, :_reduce_40, - 2, 67, :_reduce_41, - 2, 67, :_reduce_42, - 2, 67, :_reduce_43, - 1, 77, :_reduce_44, - 2, 77, :_reduce_45, - 3, 77, :_reduce_46, - 1, 80, :_reduce_47, - 2, 80, :_reduce_48, - 3, 81, :_reduce_49, - 7, 59, :_reduce_50, - 1, 85, :_reduce_51, - 3, 85, :_reduce_52, - 1, 86, :_reduce_53, + 5, 54, :_reduce_none, + 0, 55, :_reduce_none, + 2, 55, :_reduce_none, + 0, 60, :_reduce_4, + 0, 61, :_reduce_5, + 5, 59, :_reduce_6, + 2, 59, :_reduce_none, + 0, 56, :_reduce_8, + 2, 56, :_reduce_none, + 1, 62, :_reduce_none, + 1, 62, :_reduce_none, + 2, 62, :_reduce_12, + 3, 62, :_reduce_none, + 2, 62, :_reduce_none, + 2, 62, :_reduce_15, + 2, 62, :_reduce_16, + 0, 68, :_reduce_17, + 0, 69, :_reduce_18, + 7, 62, :_reduce_19, + 0, 70, :_reduce_20, + 0, 71, :_reduce_21, + 6, 62, :_reduce_22, + 1, 62, :_reduce_23, + 1, 62, :_reduce_none, + 0, 74, :_reduce_25, + 0, 75, :_reduce_26, + 6, 63, :_reduce_27, + 1, 63, :_reduce_none, + 0, 76, :_reduce_29, + 0, 77, :_reduce_30, + 7, 63, :_reduce_none, + 0, 78, :_reduce_32, + 0, 79, :_reduce_33, + 7, 63, :_reduce_34, + 0, 80, :_reduce_35, + 0, 81, :_reduce_36, + 7, 63, :_reduce_37, + 2, 63, :_reduce_38, + 2, 63, :_reduce_39, + 2, 63, :_reduce_40, + 2, 63, :_reduce_41, + 2, 63, :_reduce_42, + 2, 72, :_reduce_none, + 2, 72, :_reduce_44, + 2, 72, :_reduce_45, + 2, 72, :_reduce_46, + 2, 72, :_reduce_47, + 2, 72, :_reduce_48, + 1, 82, :_reduce_49, + 2, 82, :_reduce_50, + 3, 82, :_reduce_51, + 1, 85, :_reduce_52, + 2, 85, :_reduce_53, 3, 86, :_reduce_54, - 0, 87, :_reduce_55, - 1, 87, :_reduce_56, - 3, 87, :_reduce_57, - 3, 87, :_reduce_58, - 5, 87, :_reduce_59, + 7, 64, :_reduce_55, + 1, 90, :_reduce_56, + 3, 90, :_reduce_57, + 1, 91, :_reduce_58, + 3, 91, :_reduce_59, 0, 92, :_reduce_60, - 0, 93, :_reduce_61, - 7, 87, :_reduce_62, - 3, 87, :_reduce_63, - 0, 83, :_reduce_none, - 1, 83, :_reduce_none, - 0, 84, :_reduce_none, - 1, 84, :_reduce_none, - 1, 78, :_reduce_68, - 2, 78, :_reduce_69, - 3, 78, :_reduce_70, - 1, 94, :_reduce_71, - 2, 94, :_reduce_72, - 1, 88, :_reduce_none, + 1, 92, :_reduce_61, + 3, 92, :_reduce_62, + 3, 92, :_reduce_63, + 5, 92, :_reduce_64, + 0, 97, :_reduce_65, + 0, 98, :_reduce_66, + 7, 92, :_reduce_67, + 3, 92, :_reduce_68, + 0, 88, :_reduce_none, 1, 88, :_reduce_none, - 0, 96, :_reduce_75, - 0, 97, :_reduce_76, - 6, 62, :_reduce_77, - 0, 98, :_reduce_78, - 0, 99, :_reduce_79, - 5, 62, :_reduce_80, - 1, 79, :_reduce_81, - 2, 79, :_reduce_82, - 3, 79, :_reduce_83, - 1, 100, :_reduce_84, - 2, 100, :_reduce_85, - 1, 101, :_reduce_none, - 1, 82, :_reduce_87, - 1, 82, :_reduce_88, - 1, 52, :_reduce_none, - 2, 52, :_reduce_none, - 1, 102, :_reduce_none, - 2, 102, :_reduce_none, - 4, 103, :_reduce_93, - 1, 105, :_reduce_94, - 3, 105, :_reduce_95, - 2, 105, :_reduce_none, - 0, 106, :_reduce_97, - 1, 106, :_reduce_98, - 3, 106, :_reduce_99, - 4, 106, :_reduce_100, - 6, 106, :_reduce_101, - 0, 108, :_reduce_102, - 0, 109, :_reduce_103, - 7, 106, :_reduce_104, - 3, 106, :_reduce_105, - 1, 90, :_reduce_106, - 1, 90, :_reduce_107, - 1, 90, :_reduce_108, - 1, 91, :_reduce_109, - 3, 91, :_reduce_110, - 2, 91, :_reduce_111, - 4, 91, :_reduce_112, 0, 89, :_reduce_none, - 3, 89, :_reduce_114, - 1, 104, :_reduce_none, - 0, 53, :_reduce_none, - 0, 110, :_reduce_117, - 3, 53, :_reduce_118, - 1, 60, :_reduce_none, - 0, 61, :_reduce_none, - 1, 61, :_reduce_none, - 1, 61, :_reduce_none, - 1, 61, :_reduce_none, - 1, 68, :_reduce_124, - 2, 68, :_reduce_125, - 1, 111, :_reduce_none, - 1, 111, :_reduce_none, - 1, 95, :_reduce_128, - 0, 107, :_reduce_none, - 1, 107, :_reduce_none ] - -racc_reduce_n = 131 - -racc_shift_n = 215 + 1, 89, :_reduce_none, + 1, 83, :_reduce_73, + 2, 83, :_reduce_74, + 3, 83, :_reduce_75, + 1, 99, :_reduce_76, + 2, 99, :_reduce_77, + 1, 93, :_reduce_none, + 1, 93, :_reduce_none, + 0, 101, :_reduce_80, + 0, 102, :_reduce_81, + 6, 67, :_reduce_82, + 0, 103, :_reduce_83, + 0, 104, :_reduce_84, + 5, 67, :_reduce_85, + 1, 84, :_reduce_86, + 2, 84, :_reduce_87, + 3, 84, :_reduce_88, + 1, 105, :_reduce_89, + 2, 105, :_reduce_90, + 1, 106, :_reduce_none, + 1, 87, :_reduce_92, + 1, 87, :_reduce_93, + 1, 57, :_reduce_none, + 2, 57, :_reduce_none, + 1, 107, :_reduce_none, + 2, 107, :_reduce_none, + 4, 108, :_reduce_98, + 1, 110, :_reduce_99, + 3, 110, :_reduce_100, + 2, 110, :_reduce_none, + 0, 111, :_reduce_102, + 1, 111, :_reduce_103, + 3, 111, :_reduce_104, + 4, 111, :_reduce_105, + 6, 111, :_reduce_106, + 0, 113, :_reduce_107, + 0, 114, :_reduce_108, + 7, 111, :_reduce_109, + 3, 111, :_reduce_110, + 1, 95, :_reduce_111, + 1, 95, :_reduce_112, + 1, 95, :_reduce_113, + 1, 96, :_reduce_114, + 3, 96, :_reduce_115, + 2, 96, :_reduce_116, + 4, 96, :_reduce_117, + 0, 94, :_reduce_none, + 3, 94, :_reduce_119, + 1, 109, :_reduce_none, + 0, 58, :_reduce_none, + 0, 115, :_reduce_122, + 3, 58, :_reduce_123, + 1, 65, :_reduce_none, + 0, 66, :_reduce_none, + 1, 66, :_reduce_none, + 1, 66, :_reduce_none, + 1, 66, :_reduce_none, + 1, 73, :_reduce_129, + 2, 73, :_reduce_130, + 1, 116, :_reduce_none, + 1, 116, :_reduce_none, + 1, 100, :_reduce_133, + 0, 112, :_reduce_none, + 1, 112, :_reduce_none ] + +racc_reduce_n = 136 + +racc_shift_n = 225 racc_token_table = { false => 0, @@ -1059,28 +1072,33 @@ def raise_parse_error(error_message, location) "%destructor" => 25, "%printer" => 26, "%error-token" => 27, - "%token" => 28, - "%type" => 29, - "%left" => 30, - "%right" => 31, - "%precedence" => 32, - "%nonassoc" => 33, - "%rule" => 34, - "(" => 35, - ")" => 36, - ":" => 37, - "," => 38, - "|" => 39, - "%empty" => 40, - "%prec" => 41, - "?" => 42, - "+" => 43, - "*" => 44, - "[" => 45, - "]" => 46, - "{...}" => 47 } - -racc_nt_base = 48 + "%after-shift" => 28, + "%before-reduce" => 29, + "%after-reduce" => 30, + "%after-shift-error-token" => 31, + "%after-pop-stack" => 32, + "%token" => 33, + "%type" => 34, + "%left" => 35, + "%right" => 36, + "%precedence" => 37, + "%nonassoc" => 38, + "%rule" => 39, + "(" => 40, + ")" => 41, + ":" => 42, + "," => 43, + "|" => 44, + "%empty" => 45, + "%prec" => 46, + "?" => 47, + "+" => 48, + "*" => 49, + "[" => 50, + "]" => 51, + "{...}" => 52 } + +racc_nt_base = 53 racc_use_result_var = true @@ -1130,6 +1148,11 @@ def raise_parse_error(error_message, location) "\"%destructor\"", "\"%printer\"", "\"%error-token\"", + "\"%after-shift\"", + "\"%before-reduce\"", + "\"%after-reduce\"", + "\"%after-shift-error-token\"", + "\"%after-pop-stack\"", "\"%token\"", "\"%type\"", "\"%left\"", @@ -1459,10 +1482,50 @@ def _reduce_37(val, _values, result) end .,., -# reduce 38 omitted +module_eval(<<'.,.,', 'parser.y', 133) + def _reduce_38(val, _values, result) + @grammar.after_shift = val[1] + + result + end +.,., -module_eval(<<'.,.,', 'parser.y', 135) +module_eval(<<'.,.,', 'parser.y', 137) def _reduce_39(val, _values, result) + @grammar.before_reduce = val[1] + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 141) + def _reduce_40(val, _values, result) + @grammar.after_reduce = val[1] + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 145) + def _reduce_41(val, _values, result) + @grammar.after_shift_error_token = val[1] + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 149) + def _reduce_42(val, _values, result) + @grammar.after_pop_stack = val[1] + + result + end +.,., + +# reduce 43 omitted + +module_eval(<<'.,.,', 'parser.y', 155) + def _reduce_44(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| @grammar.add_type(id: id, tag: hash[:tag]) @@ -1473,8 +1536,8 @@ def _reduce_39(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 143) - def _reduce_40(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 163) + def _reduce_45(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1487,8 +1550,8 @@ def _reduce_40(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 153) - def _reduce_41(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 173) + def _reduce_46(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1501,8 +1564,8 @@ def _reduce_41(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 163) - def _reduce_42(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 183) + def _reduce_47(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1515,8 +1578,8 @@ def _reduce_42(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 173) - def _reduce_43(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 193) + def _reduce_48(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1529,8 +1592,8 @@ def _reduce_43(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 184) - def _reduce_44(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 204) + def _reduce_49(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) } @@ -1539,8 +1602,8 @@ def _reduce_44(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 190) - def _reduce_45(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 210) + def _reduce_50(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) } @@ -1549,8 +1612,8 @@ def _reduce_45(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 196) - def _reduce_46(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 216) + def _reduce_51(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) } @@ -1559,29 +1622,29 @@ def _reduce_46(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 201) - def _reduce_47(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 221) + def _reduce_52(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 202) - def _reduce_48(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 222) + def _reduce_53(val, _values, result) result = val[0].append(val[1]) result end .,., -module_eval(<<'.,.,', 'parser.y', 204) - def _reduce_49(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 224) + def _reduce_54(val, _values, result) result = val result end .,., -module_eval(<<'.,.,', 'parser.y', 208) - def _reduce_50(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 228) + def _reduce_55(val, _values, result) rule = Grammar::ParameterizingRule::Rule.new(val[1].s_value, val[3], val[6]) @grammar.add_parameterizing_rule(rule) @@ -1589,22 +1652,22 @@ def _reduce_50(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 212) - def _reduce_51(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 232) + def _reduce_56(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 213) - def _reduce_52(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 233) + def _reduce_57(val, _values, result) result = val[0].append(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 217) - def _reduce_53(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 237) + def _reduce_58(val, _values, result) builder = val[0] result = [builder] @@ -1612,8 +1675,8 @@ def _reduce_53(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 222) - def _reduce_54(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 242) + def _reduce_59(val, _values, result) builder = val[2] result = val[0].append(builder) @@ -1621,8 +1684,8 @@ def _reduce_54(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 228) - def _reduce_55(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 248) + def _reduce_60(val, _values, result) reset_precs result = Grammar::ParameterizingRule::Rhs.new @@ -1630,8 +1693,8 @@ def _reduce_55(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 233) - def _reduce_56(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 253) + def _reduce_61(val, _values, result) reset_precs result = Grammar::ParameterizingRule::Rhs.new @@ -1639,8 +1702,8 @@ def _reduce_56(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 238) - def _reduce_57(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 258) + def _reduce_62(val, _values, result) token = val[1] token.alias_name = val[2] builder = val[0] @@ -1651,8 +1714,8 @@ def _reduce_57(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 246) - def _reduce_58(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 266) + def _reduce_63(val, _values, result) builder = val[0] builder.symbols << Lrama::Lexer::Token::InstantiateRule.new(s_value: val[2], location: @lexer.location, args: [val[1]]) result = builder @@ -1661,8 +1724,8 @@ def _reduce_58(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 252) - def _reduce_59(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 272) + def _reduce_64(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]) result = builder @@ -1671,8 +1734,8 @@ def _reduce_59(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 258) - def _reduce_60(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 278) + def _reduce_65(val, _values, result) if @prec_seen on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec @code_after_prec = true @@ -1683,16 +1746,16 @@ def _reduce_60(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 266) - def _reduce_61(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 286) + def _reduce_66(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 270) - def _reduce_62(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 290) + def _reduce_67(val, _values, result) user_code = val[3] user_code.alias_name = val[6] builder = val[0] @@ -1703,8 +1766,8 @@ def _reduce_62(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 278) - def _reduce_63(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 298) + def _reduce_68(val, _values, result) sym = @grammar.find_symbol_by_id!(val[2]) @prec_seen = true builder = val[0] @@ -1715,168 +1778,168 @@ def _reduce_63(val, _values, result) end .,., -# reduce 64 omitted +# reduce 69 omitted -# reduce 65 omitted +# reduce 70 omitted -# reduce 66 omitted +# reduce 71 omitted -# reduce 67 omitted +# reduce 72 omitted -module_eval(<<'.,.,', 'parser.y', 293) - def _reduce_68(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 313) + def _reduce_73(val, _values, result) result = [{tag: nil, tokens: val[0]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 297) - def _reduce_69(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 317) + def _reduce_74(val, _values, result) result = [{tag: val[0], tokens: val[1]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 301) - def _reduce_70(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 321) + def _reduce_75(val, _values, result) result = val[0].append({tag: val[1], tokens: val[2]}) result end .,., -module_eval(<<'.,.,', 'parser.y', 304) - def _reduce_71(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 324) + def _reduce_76(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 305) - def _reduce_72(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 325) + def _reduce_77(val, _values, result) result = val[0].append(val[1]) result end .,., -# reduce 73 omitted +# reduce 78 omitted -# reduce 74 omitted +# reduce 79 omitted -module_eval(<<'.,.,', 'parser.y', 312) - def _reduce_75(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 332) + def _reduce_80(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 316) - def _reduce_76(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 336) + def _reduce_81(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 320) - def _reduce_77(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 340) + def _reduce_82(val, _values, result) result = val[0].append(val[3]) result end .,., -module_eval(<<'.,.,', 'parser.y', 324) - def _reduce_78(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 344) + def _reduce_83(val, _values, result) begin_c_declaration("}") result end .,., -module_eval(<<'.,.,', 'parser.y', 328) - def _reduce_79(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 348) + def _reduce_84(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 332) - def _reduce_80(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 352) + def _reduce_85(val, _values, result) result = [val[2]] result end .,., -module_eval(<<'.,.,', 'parser.y', 337) - def _reduce_81(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 357) + def _reduce_86(val, _values, result) result = [{tag: nil, tokens: val[0]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 341) - def _reduce_82(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 361) + def _reduce_87(val, _values, result) result = [{tag: val[0], tokens: val[1]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 345) - def _reduce_83(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 365) + def _reduce_88(val, _values, result) result = val[0].append({tag: val[1], tokens: val[2]}) result end .,., -module_eval(<<'.,.,', 'parser.y', 348) - def _reduce_84(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 368) + def _reduce_89(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 349) - def _reduce_85(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 369) + def _reduce_90(val, _values, result) result = val[0].append(val[1]) result end .,., -# reduce 86 omitted +# reduce 91 omitted -module_eval(<<'.,.,', 'parser.y', 353) - def _reduce_87(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 373) + def _reduce_92(val, _values, result) on_action_error("ident after %prec", val[0]) if @prec_seen result end .,., -module_eval(<<'.,.,', 'parser.y', 354) - def _reduce_88(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 374) + def _reduce_93(val, _values, result) on_action_error("char after %prec", val[0]) if @prec_seen result end .,., -# reduce 89 omitted +# reduce 94 omitted -# reduce 90 omitted +# reduce 95 omitted -# reduce 91 omitted +# reduce 96 omitted -# reduce 92 omitted +# reduce 97 omitted -module_eval(<<'.,.,', 'parser.y', 364) - def _reduce_93(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 384) + def _reduce_98(val, _values, result) lhs = val[0] lhs.alias_name = val[1] val[3].each do |builder| @@ -1889,8 +1952,8 @@ def _reduce_93(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 375) - def _reduce_94(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 395) + def _reduce_99(val, _values, result) builder = val[0] if !builder.line builder.line = @lexer.line - 1 @@ -1901,8 +1964,8 @@ def _reduce_94(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 383) - def _reduce_95(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 403) + def _reduce_100(val, _values, result) builder = val[2] if !builder.line builder.line = @lexer.line - 1 @@ -1913,10 +1976,10 @@ def _reduce_95(val, _values, result) end .,., -# reduce 96 omitted +# reduce 101 omitted -module_eval(<<'.,.,', 'parser.y', 393) - def _reduce_97(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 413) + def _reduce_102(val, _values, result) reset_precs result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter) @@ -1924,8 +1987,8 @@ def _reduce_97(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 398) - def _reduce_98(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 418) + def _reduce_103(val, _values, result) reset_precs result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter) @@ -1933,8 +1996,8 @@ def _reduce_98(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 403) - def _reduce_99(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 423) + def _reduce_104(val, _values, result) token = val[1] token.alias_name = val[2] builder = val[0] @@ -1945,8 +2008,8 @@ def _reduce_99(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 411) - def _reduce_100(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 431) + def _reduce_105(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) @@ -1957,8 +2020,8 @@ def _reduce_100(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 419) - def _reduce_101(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 439) + def _reduce_106(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) @@ -1969,8 +2032,8 @@ def _reduce_101(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 427) - def _reduce_102(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 447) + def _reduce_107(val, _values, result) if @prec_seen on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec @code_after_prec = true @@ -1981,16 +2044,16 @@ def _reduce_102(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 435) - def _reduce_103(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 455) + def _reduce_108(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 439) - def _reduce_104(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 459) + def _reduce_109(val, _values, result) user_code = val[3] user_code.alias_name = val[6] builder = val[0] @@ -2001,8 +2064,8 @@ def _reduce_104(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 447) - def _reduce_105(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 467) + def _reduce_110(val, _values, result) sym = @grammar.find_symbol_by_id!(val[2]) @prec_seen = true builder = val[0] @@ -2013,70 +2076,70 @@ def _reduce_105(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 454) - def _reduce_106(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 474) + def _reduce_111(val, _values, result) result = "option" result end .,., -module_eval(<<'.,.,', 'parser.y', 455) - def _reduce_107(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 475) + def _reduce_112(val, _values, result) result = "nonempty_list" result end .,., -module_eval(<<'.,.,', 'parser.y', 456) - def _reduce_108(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 476) + def _reduce_113(val, _values, result) result = "list" result end .,., -module_eval(<<'.,.,', 'parser.y', 458) - def _reduce_109(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 478) + def _reduce_114(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 459) - def _reduce_110(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 479) + def _reduce_115(val, _values, result) result = val[0].append(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 460) - def _reduce_111(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 480) + def _reduce_116(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', 461) - def _reduce_112(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 481) + def _reduce_117(val, _values, result) result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[0].s_value, location: @lexer.location, args: val[2])] result end .,., -# reduce 113 omitted +# reduce 118 omitted -module_eval(<<'.,.,', 'parser.y', 464) - def _reduce_114(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 484) + def _reduce_119(val, _values, result) result = val[1].s_value result end .,., -# reduce 115 omitted +# reduce 120 omitted -# reduce 116 omitted +# reduce 121 omitted -module_eval(<<'.,.,', 'parser.y', 471) - def _reduce_117(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 491) + def _reduce_122(val, _values, result) begin_c_declaration('\Z') @grammar.epilogue_first_lineno = @lexer.line + 1 @@ -2084,8 +2147,8 @@ def _reduce_117(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 476) - def _reduce_118(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 496) + def _reduce_123(val, _values, result) end_c_declaration @grammar.epilogue = val[2].s_value @@ -2093,44 +2156,44 @@ def _reduce_118(val, _values, result) end .,., -# reduce 119 omitted +# reduce 124 omitted -# reduce 120 omitted +# reduce 125 omitted -# reduce 121 omitted +# reduce 126 omitted -# reduce 122 omitted +# reduce 127 omitted -# reduce 123 omitted +# reduce 128 omitted -module_eval(<<'.,.,', 'parser.y', 487) - def _reduce_124(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 507) + def _reduce_129(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 488) - def _reduce_125(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 508) + def _reduce_130(val, _values, result) result = val[0].append(val[1]) result end .,., -# reduce 126 omitted +# reduce 131 omitted -# reduce 127 omitted +# reduce 132 omitted -module_eval(<<'.,.,', 'parser.y', 493) - def _reduce_128(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 513) + def _reduce_133(val, _values, result) result = Lrama::Lexer::Token::Ident.new(s_value: val[0]) result end .,., -# reduce 129 omitted +# reduce 134 omitted -# reduce 130 omitted +# reduce 135 omitted def _reduce_none(val, _values, result) val[0] diff --git a/parser.y b/parser.y index f5b9f402..1aedc75e 100644 --- a/parser.y +++ b/parser.y @@ -129,6 +129,26 @@ rule lineno: val[3].line ) } + | "%after-shift" IDENTIFIER + { + @grammar.after_shift = val[1] + } + | "%before-reduce" IDENTIFIER + { + @grammar.before_reduce = val[1] + } + | "%after-reduce" IDENTIFIER + { + @grammar.after_reduce = val[1] + } + | "%after-shift-error-token" IDENTIFIER + { + @grammar.after_shift_error_token = val[1] + } + | "%after-pop-stack" IDENTIFIER + { + @grammar.after_pop_stack = val[1] + } symbol_declaration: "%token" token_declarations | "%type" symbol_declarations diff --git a/spec/fixtures/integration/after_shift.l b/spec/fixtures/integration/after_shift.l new file mode 100644 index 00000000..0ab1cc95 --- /dev/null +++ b/spec/fixtures/integration/after_shift.l @@ -0,0 +1,40 @@ +%option noinput nounput noyywrap never-interactive bison-bridge bison-locations + +%{ + +#include +#include +#include "after_shift.h" + +%} + +NUMBER [0-9]+ + +%% + +{NUMBER} { + ((void) yylloc); + yylval->val = atoi(yytext); + return NUM; +} + +[+\-\*\/\(\)] { + return yytext[0]; +} + +[\n|\r\n] { + return(YYEOF); +} + +[[:space:]] {} + +<> { + return(YYEOF); +} + +. { + fprintf(stderr, "Illegal character '%s'\n", yytext); + return(YYEOF); +} + +%% diff --git a/spec/fixtures/integration/after_shift.y b/spec/fixtures/integration/after_shift.y new file mode 100644 index 00000000..56ba9055 --- /dev/null +++ b/spec/fixtures/integration/after_shift.y @@ -0,0 +1,111 @@ +%{ + +#include +#include "after_shift.h" +#include "after_shift-lexer.h" + +static int yyerror(YYLTYPE *loc, const char *str); + +static void +after_shift(void) +{ + printf("after-shift: %d\n", __LINE__); +} + +static void +before_reduce(int len) +{ + printf("before-reduce: %d, %d\n", __LINE__, len); +} + +static void +after_reduce(int len) +{ + printf("after-reduce: %d, %d\n", __LINE__, len); +} + +static void +after_shift_error_token(void) +{ + printf("after-shift-error-token: %d\n", __LINE__); +} + +static void +after_pop_stack(int len) +{ + printf("after-pop-stack: %d, %d\n", __LINE__, len); +} + +%} + +%union { + int val; +} + +%after-shift after_shift +%before-reduce before_reduce +%after-reduce after_reduce +%after-shift-error-token after_shift_error_token +%after-pop-stack after_pop_stack + +%token NUM +%type expr +%left '+' '-' +%left '*' '/' + +%% + +program : /* empty */ + | expr { printf("=> %d\n", $1); } + | error + { + printf("error (%d)\n", $:1); + } + ; + +expr : NUM + | expr '+' expr + { + $$ = $1 + $3; + printf("+ (%d, %d, %d)\n", $:1, $:2, $:3); + } + | expr '-' expr + { + $$ = $1 - $3; + printf("- (%d, %d, %d)\n", $:1, $:2, $:3); + } + | expr '*' expr + { + $$ = $1 * $3; + printf("* (%d, %d, %d)\n", $:1, $:2, $:3); + } + | expr '/' expr + { + $$ = $1 / $3; + printf("/ (%d, %d, %d)\n", $:1, $:2, $:3); + } + | '(' expr ')' + { + $$ = $2; + printf("(...) (%d, %d, %d)\n", $:1, $:2, $:3); + } + ; + +%% + +static int yyerror(YYLTYPE *loc, const char *str) { + fprintf(stderr, "parse error: %s\n", str); + return 0; +} + +int main(int argc, char *argv[]) { + if (argc == 2) { + yy_scan_string(argv[1]); + } + + if (yyparse()) { + fprintf(stderr, "syntax error\n"); + return 1; + } + return 0; +} diff --git a/spec/lrama/grammar/code_spec.rb b/spec/lrama/grammar/code_spec.rb index 550791b9..dfd35ba7 100644 --- a/spec/lrama/grammar/code_spec.rb +++ b/spec/lrama/grammar/code_spec.rb @@ -2,8 +2,10 @@ let(:token_class) { Lrama::Lexer::Token } let(:user_code_dollar_dollar) { token_class::UserCode.new(s_value: 'print($$);') } let(:user_code_at_dollar) { token_class::UserCode.new(s_value: 'print(@$);') } + let(:user_code_index_dollar) { token_class::UserCode.new(s_value: 'print($:$);') } let(:user_code_dollar_n) { token_class::UserCode.new(s_value: 'print($n);') } let(:user_code_at_n) { token_class::UserCode.new(s_value: 'print(@n);') } + let(:user_code_index_n) { token_class::UserCode.new(s_value: 'print($:1);') } describe Lrama::Grammar::Code::InitialActionCode do describe "#translated_code" do @@ -17,6 +19,11 @@ expect(code.translated_code).to eq("print(yylloc);") end + it "raises error for '$:$'" do + code = described_class.new(type: :initial_action, token_code: user_code_index_dollar) + expect { code.translated_code }.to raise_error("$:$ can not be used in initial_action.") + end + it "raises error for '$n'" do code = described_class.new(type: :initial_action, token_code: user_code_dollar_n) expect { code.translated_code }.to raise_error("$n can not be used in initial_action.") @@ -26,6 +33,11 @@ code = described_class.new(type: :initial_action, token_code: user_code_at_n) expect { code.translated_code }.to raise_error("@n can not be used in initial_action.") end + + it "raises error for '$:n'" do + code = described_class.new(type: :initial_action, token_code: user_code_index_n) + expect { code.translated_code }.to raise_error("$:1 can not be used in initial_action.") + end end end @@ -41,6 +53,11 @@ expect { code.translated_code }.to raise_error("@$ can not be used in union.") end + it "raises error for '$:$'" do + code = described_class.new(type: :union, token_code: user_code_index_dollar) + expect { code.translated_code }.to raise_error("$:$ can not be used in union.") + end + it "raises error for '$n'" do code = described_class.new(type: :union, token_code: user_code_dollar_n) expect { code.translated_code }.to raise_error("$n can not be used in union.") @@ -50,6 +67,11 @@ code = described_class.new(type: :union, token_code: user_code_at_n) expect { code.translated_code }.to raise_error("@n can not be used in union.") end + + it "raises error for '$:n'" do + code = described_class.new(type: :union, token_code: user_code_index_n) + expect { code.translated_code }.to raise_error("$:1 can not be used in union.") + end end end @@ -67,6 +89,11 @@ expect(code.translated_code).to eq("print((*yylocationp));") end + it "raises error for '$:$'" do + code = described_class.new(type: :printer, token_code: user_code_index_dollar, tag: tag) + expect { code.translated_code }.to raise_error("$:$ can not be used in printer.") + end + it "raises error for '$n'" do code = described_class.new(type: :printer, token_code: user_code_dollar_n, tag: tag) expect { code.translated_code }.to raise_error("$n can not be used in printer.") @@ -76,6 +103,11 @@ code = described_class.new(type: :printer, token_code: user_code_at_n, tag: tag) expect { code.translated_code }.to raise_error("@n can not be used in printer.") end + + it "raises error for '$:n'" do + code = described_class.new(type: :printer, token_code: user_code_index_n, tag: tag) + expect { code.translated_code }.to raise_error("$:1 can not be used in printer.") + end end end @@ -120,6 +152,10 @@ | rule6 | rule7 | rule8 + | rule9 + | rule10 + | rule11 + | rule12 ; rule1: expr '+' expr { $$ = 0; } @@ -146,6 +182,17 @@ rule8: expr { $$ = $1 } '+' expr { $2; } ; + rule9: expr '+' expr { $:1; $:2; $:3; } + ; + + rule10: expr '+' expr { $:$; } + ; + + rule11: expr { $:1; } '+' expr { $:1; $:2; $:3; $:4; } + ; + + rule12: expr '+' expr[expr-right] { $:1; $:2; $:[expr-right]; } + ; %% GRAMMAR end @@ -212,6 +259,26 @@ expect { code.translated_code }.to raise_error("Tag is not specified for '$2' in 'rule8 -> expr, @3, '+', expr'") end end + + context "$: is used" do + it "translats '$:$' to '-yylen' and '$:n' to index from the last of array" do + code = grammar.rules.find {|r| r.lhs.id.s_value == "rule9" } + expect(code.translated_code).to eq(" (-2 - 1); (-1 - 1); (0 - 1); ") + + code = grammar.rules.find {|r| r.lhs.id.s_value == "rule10" } + expect { code.translated_code }.to raise_error("$:$ is not supported") + + # midrule action in rule11 + code = grammar.rules.find {|r| r.lhs.id.s_value == "@4" } + expect(code.translated_code).to eq(" (0 - 1); ") + + code = grammar.rules.find {|r| r.lhs.id.s_value == "rule11" } + expect(code.translated_code).to eq(" (-3 - 1); (-2 - 1); (-1 - 1); (0 - 1); ") + + code = grammar.rules.find {|r| r.lhs.id.s_value == "rule12" } + expect(code.translated_code).to eq(" (-2 - 1); (-1 - 1); (0 - 1); ") + end + end end end end diff --git a/spec/lrama/integration_spec.rb b/spec/lrama/integration_spec.rb index c3d0a142..de1ead2a 100644 --- a/spec/lrama/integration_spec.rb +++ b/spec/lrama/integration_spec.rb @@ -143,6 +143,67 @@ def generate_object(grammar_file_path, c_path, obj_path, command_args: []) end end + describe "after_shift, before_reduce & after_reduce" do + it "returns 9 for '(1+2)*3'" do + expected = <<~STR + after-shift: 12 + after-shift: 12 + before-reduce: 18, 1 + after-reduce: 24, 1 + after-shift: 12 + after-shift: 12 + before-reduce: 18, 1 + after-reduce: 24, 1 + before-reduce: 18, 3 + + (-3, -2, -1) + after-reduce: 24, 3 + after-shift: 12 + before-reduce: 18, 3 + (...) (-3, -2, -1) + after-reduce: 24, 3 + after-shift: 12 + after-shift: 12 + before-reduce: 18, 1 + after-reduce: 24, 1 + before-reduce: 18, 3 + * (-3, -2, -1) + after-reduce: 24, 3 + before-reduce: 18, 1 + => 9 + after-reduce: 24, 1 + after-shift: 12 + STR + + test_parser("after_shift", "( 1 + 2 ) * 3", expected) + + expected = <<~STR + after-shift: 12 + before-reduce: 18, 1 + after-reduce: 24, 1 + after-shift: 12 + after-pop-stack: 36, 1 + after-pop-stack: 36, 1 + after-shift-error-token: 30 + before-reduce: 18, 1 + error (-1) + after-reduce: 24, 1 + after-pop-stack: 36, 1 + after-shift-error-token: 30 + before-reduce: 18, 1 + error (-1) + after-reduce: 24, 1 + after-pop-stack: 36, 1 + after-shift-error-token: 30 + before-reduce: 18, 1 + error (-1) + after-reduce: 24, 1 + after-shift: 12 + STR + + test_parser("after_shift", "1 * + 2", expected) + end + end + # TODO: Add test case for "(1+2" describe "error_recovery" do it "returns 101 for '(1+)'" do diff --git a/template/bison/yacc.c b/template/bison/yacc.c index f72d3461..6145a950 100644 --- a/template/bison/yacc.c +++ b/template/bison/yacc.c @@ -1752,6 +1752,7 @@ YYLTYPE yylloc = yyloc_default; *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END *++yylsp = yylloc; +<%= output.after_shift_function("/* %after-shift code. */") %> /* Discard the shifted token. */ yychar = YYEMPTY; @@ -1784,6 +1785,7 @@ YYLTYPE yylloc = yyloc_default; unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; +<%= output.before_reduce_function("/* %before-reduce function. */") %> /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); @@ -1809,6 +1811,7 @@ YYLTYPE yylloc = yyloc_default; YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc<%= output.user_args %>); YYPOPSTACK (yylen); +<%= output.after_reduce_function("/* %after-reduce function. */") %> yylen = 0; *++yyvsp = yyval; @@ -1910,6 +1913,7 @@ YYLTYPE yylloc = yyloc_default; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); +<%= output.after_pop_stack_function("yylen", "/* %after-pop-stack function. */") %> yylen = 0; YY_STACK_PRINT (yyss, yyssp<%= output.user_args %>); yystate = *yyssp; @@ -1969,6 +1973,7 @@ YYLTYPE yylloc = yyloc_default; yydestruct ("Error: popping", YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp<%= output.user_args %>); YYPOPSTACK (1); +<%= output.after_pop_stack_function(1, "/* %after-pop-stack function. */") %> yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp<%= output.user_args %>); } @@ -1983,6 +1988,7 @@ YYLTYPE yylloc = yyloc_default; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp<%= output.user_args %>); +<%= output.after_shift_error_token_function("/* %after-shift-error-token code. */") %> yystate = yyn; goto yynewstate;