depager 0.2.3 → 0.3.0.b20250423

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +44 -0
  3. data/.simplecov +5 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE.gpl +339 -0
  6. data/Manifest.txt +73 -0
  7. data/README.en +7 -21
  8. data/README.ja +19 -99
  9. data/Rakefile +31 -0
  10. data/bin/depager +7 -45
  11. data/examples/action_pl0d/pl0d.action.dr +421 -0
  12. data/examples/action_pl0d/test.pl0ds +48 -0
  13. data/examples/c89/c89.dr +493 -496
  14. data/examples/c89/test.c89 +10 -10
  15. data/examples/extension/astdf.rb +9 -0
  16. data/examples/extension/atree.dr +55 -0
  17. data/examples/{sample_calc → extension}/calc.atree.dr +42 -43
  18. data/examples/{sample_calc/calc.action.dr → extension/calc.simple_action.dr} +33 -33
  19. data/examples/extension/paction.dr +16 -15
  20. data/examples/extension/pactiontest.dr +14 -14
  21. data/examples/extension/simple_action.rb +46 -0
  22. data/examples/pl0d/pl0ds.dr +337 -334
  23. data/examples/pl0d/test.pl0ds +33 -33
  24. data/examples/rie_calc/calc.rie.dr +57 -0
  25. data/examples/rie_calc/test.calc +4 -0
  26. data/examples/rie_dcuse/dcuse.rie.dr +71 -0
  27. data/examples/rie_dcuse/test.dcuse +1 -0
  28. data/examples/rie_pl0/orig_ex/exerrdg.pl0 +44 -0
  29. data/examples/rie_pl0/orig_ex/exerrm.pl0 +19 -0
  30. data/examples/rie_pl0/orig_ex/exerrmre.pl0 +20 -0
  31. data/examples/rie_pl0/orig_ex/exerrtok.pl0 +18 -0
  32. data/examples/rie_pl0/orig_ex/exmdg.pl0 +40 -0
  33. data/examples/rie_pl0/orig_ex/exmdgwwl.pl0 +43 -0
  34. data/examples/rie_pl0/orig_ex/exmrw.pl0 +22 -0
  35. data/examples/rie_pl0/orig_ex/exmwwl.pl0 +18 -0
  36. data/examples/rie_pl0/orig_ex/exnorw.pl0 +17 -0
  37. data/examples/rie_pl0/pl0.rie.dr +450 -0
  38. data/examples/rie_pl0/test.pl0 +10 -0
  39. data/examples/slex_test/divreg.slex.dr +29 -29
  40. data/examples/slex_test/ljoin.slex.dr +36 -36
  41. data/examples/slex_test/test.divreg +1 -1
  42. data/examples/slex_test/test.ljoin +3 -3
  43. data/examples/{sample_calc/calc.nvaction.dr → tiny_calc/calc.action.dr} +33 -33
  44. data/examples/{sample_calc → tiny_calc}/calc.ast.action.dr +76 -66
  45. data/examples/{sample_calc → tiny_calc}/calc.ast.dr +67 -55
  46. data/examples/tiny_calc/calc.cst.dr +50 -0
  47. data/examples/{sample_calc → tiny_calc}/calc.dr +43 -43
  48. data/examples/{sample_calc → tiny_calc}/calc.lex.dr +29 -29
  49. data/examples/{sample_calc/calc_prec.nvaction.dr → tiny_calc/calc_prec.action.dr} +31 -31
  50. data/lib/depager/cli.rb +44 -0
  51. data/lib/depager/grammar.rb +253 -291
  52. data/lib/depager/lr.rb +589 -579
  53. data/lib/depager/parser.rb +269 -277
  54. data/lib/depager/plugins/_rie_debug.rb +63 -0
  55. data/lib/depager/plugins/action.rb +47 -0
  56. data/lib/depager/plugins/ast.dr +367 -0
  57. data/lib/depager/plugins/ast.rb +1329 -0
  58. data/lib/depager/{ruby/plugins → plugins}/cst.dr +174 -180
  59. data/lib/depager/plugins/cst.rb +591 -0
  60. data/lib/depager/{ruby/plugins → plugins}/lex.dr +85 -89
  61. data/lib/depager/plugins/lex.rb +313 -0
  62. data/lib/depager/plugins/rie.dr +725 -0
  63. data/lib/depager/plugins/rie.rb +1614 -0
  64. data/lib/depager/{ruby/plugins → plugins}/slex.dr +201 -200
  65. data/lib/depager/plugins/slex.rb +769 -0
  66. data/lib/depager/plugins/srp.rb +46 -0
  67. data/lib/depager/ruby/templates/extension_lalr_master.erb +40 -51
  68. data/lib/depager/ruby/templates/extension_lalr_slave.erb +113 -107
  69. data/lib/depager/ruby/templates/single_lalr_parser.erb +124 -117
  70. data/lib/depager/utils.rb +158 -318
  71. data/lib/depager/version.rb +3 -3
  72. data/lib/depager.rb +572 -670
  73. metadata +77 -80
  74. data/ChangeLog +0 -16
  75. data/data/depager/pre-setup.rb +0 -3
  76. data/examples/c89/c89.tab.rb +0 -7127
  77. data/examples/pl0d/pl0ds.tab.rb +0 -2698
  78. data/examples/sample_calc/calc.action.tab.rb +0 -457
  79. data/examples/sample_calc/calc.ast.action.tab.rb +0 -749
  80. data/examples/sample_calc/calc.ast.tab.rb +0 -665
  81. data/examples/sample_calc/calc.astdf.dr +0 -54
  82. data/examples/sample_calc/calc.astdf.tab.rb +0 -672
  83. data/examples/sample_calc/calc.atree.tab.rb +0 -451
  84. data/examples/sample_calc/calc.cst.dr +0 -45
  85. data/examples/sample_calc/calc.cst.tab.rb +0 -644
  86. data/examples/sample_calc/calc.lex.tab.rb +0 -374
  87. data/examples/sample_calc/calc.nvaction.tab.rb +0 -465
  88. data/examples/sample_calc/calc.tab.rb +0 -365
  89. data/examples/sample_calc/calc_prec.nvaction.tab.rb +0 -431
  90. data/examples/slex_test/divreg.slex.tab.rb +0 -303
  91. data/examples/slex_test/ljoin.slex.tab.rb +0 -370
  92. data/lib/depager/ruby/plugins/_ast_tmpl.rb +0 -73
  93. data/lib/depager/ruby/plugins/action.rb +0 -43
  94. data/lib/depager/ruby/plugins/ast.dr +0 -269
  95. data/lib/depager/ruby/plugins/ast.rb +0 -1308
  96. data/lib/depager/ruby/plugins/astdf.rb +0 -6
  97. data/lib/depager/ruby/plugins/atree.dr +0 -55
  98. data/lib/depager/ruby/plugins/atree.rb +0 -347
  99. data/lib/depager/ruby/plugins/cst.rb +0 -626
  100. data/lib/depager/ruby/plugins/lex.rb +0 -336
  101. data/lib/depager/ruby/plugins/nvaction.rb +0 -19
  102. data/lib/depager/ruby/plugins/slex.rb +0 -817
  103. data/lib/depager/ruby/plugins/srp.rb +0 -51
  104. data/lib/depager/ruby/templates/simple.erb +0 -23
  105. data/setup.rb +0 -1585
  106. /data/examples/{sample_calc → tiny_calc}/test.calc +0 -0
@@ -1,277 +1,269 @@
1
- module Depager; end
2
- #
3
- # Token
4
- #
5
- class Depager::Token
6
- def self.[] *args
7
- self.new(*args)
8
- end
9
- attr_accessor :value, :lineno, :filename
10
- def initialize value, lineno=nil, filename=nil
11
- @value = value
12
- @lineno = lineno
13
- @filename = filename
14
- end
15
- def [](n)
16
- case n
17
- when 0 ; @value
18
- when 1 ; @lineno
19
- when 2 ; @filename
20
- else ; nil
21
- end
22
- end
23
- def to_s
24
- "#{@value.inspect}:#{@lineno}@#{@filename}"
25
- end
26
- def inspect
27
- "#<#{self.class.name}:0x#{object_id.to_s(16)}" <<
28
- " #{@value.inspect}:#{@lineno}@#{@filename}>"
29
- end
30
- end
31
-
32
- # LALR runtime
33
- module Depager::LALR
34
- # = Parser runtime
35
- # == Stack
36
- # s:: state
37
- # la:: look ahead
38
- # v:: value
39
- # stack top->
40
- # [0, [la0, v0], s0, [la1, v1], s1, .....]
41
- #
42
- class Parser
43
- ACC = 0x03ffffff
44
-
45
- # parse method
46
- def parse f
47
- @basis.file = f
48
- @basis.la = [0, nil]
49
- @basis.lex do |sym, val|
50
- @basis.la = [@basis.t2i[sym] || @basis.t2i[false], val]
51
- break if driver
52
- end
53
- @basis.stack[1][2..(@basis.params.size+1)]
54
- end
55
-
56
- protected
57
- # driver method
58
- def driver
59
- while true
60
- @basis.val = @basis.action_table[@basis.stack.last][@basis.la[0]]
61
- @basis.val ||= @basis.defred_table[@basis.stack.last]
62
-
63
- if @basis.val == nil
64
- #warn "#{@basis.stack}#{@basis.la[0]}"
65
- error
66
- exit 1
67
- elsif @basis.val == ACC
68
- if @i2t[@basis.la[0]] == nil
69
- accept
70
- else
71
- error
72
- end
73
- return true
74
- elsif @basis.val > 0
75
- shift
76
- while val = @basis.defred_after_shift_table[@basis.stack.last]
77
- @basis.val = val
78
- reduce
79
- end
80
- return false
81
- else
82
- reduce
83
- end
84
- end
85
- end
86
-
87
- def enable?(act, sym)
88
- case act
89
- when :shift
90
- la = @basis.t2i[sym] || @basis.t2i[false]
91
- val = @basis.action_table[@basis.stack.last][la]
92
- else
93
- end
94
- end
95
-
96
- def enables(act, sym)
97
- case act
98
- when :shift
99
- la = @basis.t2i[sym] || @basis.t2i[false]
100
- res = []
101
- @basis.action_table.each_with_index{|i, x|
102
- i[la] and res.push(x)
103
- }
104
- return res
105
- else
106
- end
107
- end
108
-
109
- # template methods
110
- def init_parser ; end
111
- def lex ; end
112
- def accept ; end
113
- def error ; end
114
- def shift ; end
115
- def reduce ; end
116
- end
117
-
118
- class Basis < Parser
119
- attr_accessor :state, :stack, :laq, :la, :val, :basis, :params
120
- attr_accessor :file, :oldline, :lineno, :line, :line0
121
- attr_reader :action_table, :defred_table, :defred_after_shift_table
122
- attr_reader :goto_table, :reduce_table
123
- attr_reader :i2t, :t2i, :nt2i, :i2nt
124
-
125
- private
126
- def __init_parser__
127
- @state = 0
128
- @stack = [@state]
129
- @laq = []
130
- @la = nil
131
- @val = nil
132
- @line0 = @line = ''
133
- end
134
-
135
- def initialize
136
- __init_parser__
137
- @file = nil
138
- @basis = self
139
- @reduce_table, @params, @action_table,
140
- @defred_table, @defred_after_shift_table, @goto_table,
141
- @t2i, @i2t, @nt2i, @i2nt = self.class::Tables
142
- end
143
-
144
- def token sym, val=nil, lineno=nil
145
- lineno ||= file.lineno
146
- return sym, Depager::Token[val, lineno, file.path]
147
- end
148
-
149
- public
150
- def banner
151
- self.class.name
152
- end
153
-
154
- def getline
155
- @file.gets unless @file.eof?
156
- end
157
-
158
- def accept
159
- #warn "acc."
160
- end
161
- def error
162
- fname = @file.respond_to?(:path) ? @file.path : '-'
163
- exp = []
164
- @action_table[@stack.last].each_with_index do |i, x|
165
- exp << @i2t[x] if i
166
- end
167
- la = @la[1].value rescue @la[1]
168
- la = (@i2t[@la[0]] || la).inspect
169
- exp = exp.map{|i| i ? i.inspect : '$' }.join(', ')
170
- warn "#{fname}:#{@file.lineno}: syntax error(#{self.banner}), " <<
171
- "unexpected #{la}, expecting #{exp}."
172
- warn @stack.pretty_inspect if $MP_DEBUG
173
- end
174
- def shift
175
- @stack.push(@la).push(@val)
176
- end
177
- def reduce
178
- (@reduce_table[-@val][1] * 2).times{@stack.pop}
179
- r = @reduce_table[-@val][0]
180
- cs = @goto_table[@stack.last][r]
181
- @stack.push([r, :NT]).push(cs)
182
- end
183
- end
184
-
185
- #
186
- # Decorator Base class
187
- #
188
- class AdvancedParser < Parser
189
- attr_reader :basis
190
- attr_reader :action_table, :goto_table, :reduce_table
191
- attr_reader :i2t, :t2i, :nt2i, :i2nt
192
- def initialize inside, paramkey = nil
193
- @inside = inside
194
- @basis = @inside.basis
195
- @reduce_table, @params, @action_table, @defred_table, @goto_table,
196
- @t2i, @i2t, @nt2i, @i2nt = @basis.class::Tables
197
- @nparam = @params[paramkey]
198
- end
199
-
200
- protected
201
- def _state
202
- @basis.state
203
- end
204
- def _stack
205
- @basis.stack
206
- end
207
- def _lookaheadque
208
- @basis.laq
209
- end
210
- def _lookahead
211
- @basis.la
212
- end
213
- def _actvalue
214
- @basis.val
215
- end
216
-
217
- def accept
218
- before_accept
219
- @inside.accept
220
- after_accept
221
- end
222
- def error
223
- before_error
224
- @inside.error
225
- after_error
226
- end
227
- def shift
228
- before_shift
229
- @inside.shift
230
- after_shift
231
- end
232
- def reduce
233
- before_reduce
234
- @inside.reduce
235
- after_reduce
236
- end
237
-
238
- # template methods
239
- def before_accept ; end
240
- def after_accept ; end
241
- def before_error ; end
242
- def after_error ; end
243
- def before_shift ; end
244
- def after_shift ; end
245
- def before_reduce ; end
246
- def after_reduce ; end
247
- end
248
-
249
- #
250
- # Action Decorator Base class
251
- #
252
- class Action < AdvancedParser
253
- def initialize inside, nparamkey=nil
254
- super inside, nparamkey
255
- @_yy_val_ = []
256
- end
257
- def before_reduce
258
- @_yy_val_ = []
259
- n = @reduce_table[-_actvalue][1]
260
- n.times do |i|
261
- x = _stack[_stack.size-2*(i+1)]
262
- @_yy_val_[n-i-1] = x[1] == :NT ? x[@nparam] : x[1]
263
- end
264
- end
265
- def after_reduce
266
- mes = @on_reduce[-_actvalue]
267
- r = mes ? self.send(mes, @_yy_val_) : nil
268
- _stack[_stack.size-2][@nparam] = r
269
- end
270
- end
271
- end
272
-
273
- class IO
274
- def path
275
- self.to_s
276
- end
277
- end
1
+ require "forwardable"
2
+
3
+ module Depager
4
+ def self.path_of(io)
5
+ return "-" if io == $stdin
6
+ return "<#{io.class}>" unless io.respond_to?(:path) # StringIO
7
+
8
+ io.path
9
+ end
10
+
11
+ class Token
12
+ attr_accessor :value, :lineno, :filename
13
+
14
+ def initialize(value, lineno = nil, filename = nil)
15
+ @value = value
16
+ @lineno = lineno
17
+ @filename = filename
18
+ end
19
+
20
+ def to_s
21
+ "#{@value.inspect}:#{@lineno}@#{@filename}"
22
+ end
23
+
24
+ def inspect
25
+ "<#{@value.inspect}:#{@lineno}>"
26
+ end
27
+ end
28
+
29
+ module LALR
30
+ # = Parser runtime
31
+ # == Stack
32
+ # s:: state
33
+ # la:: look ahead
34
+ # v:: value
35
+ # stack top->
36
+ # [0, [la0, v0], s0, [la1, v1], s1, .....]
37
+ #
38
+ class Parser
39
+ ACC = 0x03ffffff
40
+
41
+ def parse(f, line = "")
42
+ basis.__send__ :internal_initialize, f, line, [0, nil]
43
+
44
+ do_hook :before_parse
45
+ lex do |sym, val|
46
+ basis.lookahead = [term_to_int[sym] || term_to_int[false], val]
47
+ break if driver
48
+ end
49
+ do_hook :after_parse
50
+
51
+ stack[1][2..basis.parser_size]
52
+ end
53
+
54
+ def lex; end
55
+ def accept; end
56
+ def error; end
57
+ def shift; end
58
+ def reduce; end
59
+
60
+ def reduce_table; end
61
+ def action_table; end
62
+ def defred_table; end
63
+ def defred_after_shift_table; end
64
+ def goto_table; end
65
+ def term_to_int; end
66
+ def int_to_term; end
67
+ def nonterm_to_int; end
68
+ def int_to_nonterm; end
69
+
70
+ protected
71
+
72
+ def driver
73
+ loop do
74
+ basis.action_value = action_table[stack.last][lookahead[0]] || defred_table[stack.last]
75
+
76
+ if action_value.nil?
77
+ error
78
+ basis.do_abort_driver
79
+ elsif action_value == ACC
80
+ if int_to_term[lookahead[0]].nil?
81
+ accept
82
+ return true
83
+ else
84
+ error
85
+ basis.do_abort_driver
86
+ end
87
+ elsif action_value > 0
88
+ shift
89
+ while (v = defred_after_shift_table[stack.last])
90
+ basis.action_value = v
91
+ reduce
92
+ end
93
+ return false
94
+ else
95
+ reduce
96
+ end
97
+ end
98
+ end
99
+
100
+ def do_hook(hook)
101
+ if @basis == self
102
+ send hook
103
+ elsif /^before_/.match?(hook.to_s)
104
+ send hook
105
+ @inside.do_hook hook
106
+ else
107
+ @inside.do_hook hook
108
+ send hook
109
+ end
110
+ end
111
+
112
+ private
113
+
114
+ def before_parse; end
115
+ def after_parse; end
116
+ end
117
+
118
+ class Basis < Parser
119
+ attr_reader :basis, :file, :line, :parser_size
120
+ attr_accessor :lookahead, :action_value, :stack
121
+
122
+ def initialize
123
+ super
124
+
125
+ @basis = self
126
+ @parser_size = 1
127
+ end
128
+
129
+ def banner
130
+ self.class.name
131
+ end
132
+
133
+ def next_decorator_index
134
+ @parser_size += 1
135
+ end
136
+
137
+ def accept; end
138
+
139
+ def error
140
+ path = Depager.path_of(file)
141
+ exp = []
142
+ action_table[stack.last].each_with_index do |i, x|
143
+ exp << int_to_term[x] if i
144
+ end
145
+ la = begin
146
+ lookahead[1].value
147
+ rescue StandardError
148
+ lookahead[1]
149
+ end
150
+ la = (int_to_term[lookahead[0]] || la).inspect
151
+ exp = exp.map { |i| i ? i.inspect : "$" }.join(", ")
152
+ warn "#{path}:#{file.lineno}: syntax error(#{banner}), unexpected #{la}, expecting #{exp}."
153
+ warn @stack.pretty_inspect if Depager.respond_to?(:debug_mode?) && Depager.debug_mode?
154
+ end
155
+
156
+ def shift
157
+ stack << lookahead << action_value
158
+ end
159
+
160
+ def reduce
161
+ r, x = reduce_table[-action_value]
162
+ (x * 2).times { stack.pop }
163
+ v = goto_table[stack.last][r]
164
+ stack << [r, :NT] << v
165
+ end
166
+
167
+ def do_abort_driver
168
+ abort_driver
169
+ end
170
+
171
+ def abort_driver
172
+ exit 1
173
+ end
174
+
175
+ private
176
+
177
+ def internal_initialize(file, line, lookahead)
178
+ @stack = [0]
179
+ @action_value = nil
180
+ @file = file
181
+ @line = line
182
+ @lookahead = lookahead
183
+ end
184
+
185
+ def token(sym, value = nil, lineno = nil)
186
+ lineno ||= file.lineno
187
+ path = file.respond_to?(:path) ? file.path : "-"
188
+ [sym, Depager::Token.new(value, lineno, path)]
189
+ end
190
+ end
191
+
192
+ class AdvancedParser < Parser
193
+ extend Forwardable
194
+ delegate %i[
195
+ lookahead action_value stack lex abort_driver
196
+ reduce_table action_table defred_table defred_after_shift_table goto_table
197
+ term_to_int int_to_term nonterm_to_int int_to_nonterm
198
+ ] => :@basis
199
+
200
+ attr_reader :basis, :decorator_index
201
+
202
+ def initialize(inside)
203
+ @inside = inside
204
+ @basis = inside.basis
205
+ @decorator_index = @basis.next_decorator_index
206
+ super()
207
+ end
208
+
209
+ def accept
210
+ before_accept
211
+ @inside.accept
212
+ after_accept
213
+ end
214
+
215
+ def error
216
+ before_error
217
+ @inside.error
218
+ after_error
219
+ end
220
+
221
+ def shift
222
+ before_shift
223
+ @inside.shift
224
+ after_shift
225
+ end
226
+
227
+ def reduce
228
+ before_reduce
229
+ @inside.reduce
230
+ after_reduce
231
+ end
232
+
233
+ private
234
+
235
+ def before_accept; end
236
+ def after_accept; end
237
+ def before_error; end
238
+ def after_error; end
239
+ def before_shift; end
240
+ def after_shift; end
241
+ def before_reduce; end
242
+ def after_reduce; end
243
+ end
244
+
245
+ class Action < AdvancedParser
246
+ def on_reduce; end
247
+
248
+ def initialize(inside)
249
+ super
250
+ @_arguments = []
251
+ end
252
+
253
+ def before_reduce
254
+ @_arguments = []
255
+ n = reduce_table[-action_value][1]
256
+ n.times do |i|
257
+ v = stack[stack.size - (2 * (i + 1))]
258
+ @_arguments[n - i - 1] = v[1] == :NT ? v[decorator_index] : v[1]
259
+ end
260
+ end
261
+
262
+ def after_reduce
263
+ method = on_reduce[-action_value]
264
+ result = method ? send(method, @_arguments) : nil
265
+ stack[stack.size - 2][decorator_index] = result
266
+ end
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,63 @@
1
+ class Depager::RieExtension
2
+ module DebugHelper
3
+ def inspect
4
+ "<#{node_name}:#{node_values.inspect}>"
5
+ end
6
+
7
+ def pretty_print(q)
8
+ q.group(1, "<#{node_name}:", ">") { q.pp node_values }
9
+ end
10
+
11
+ def node_name
12
+ self.class.name.split("::").last
13
+ end
14
+
15
+ def node_values
16
+ to_h.tap { _1.delete(:lineno) }
17
+ end
18
+ end
19
+
20
+ module Nodes
21
+ N_THREAD.class_eval do
22
+ include DebugHelper
23
+ end
24
+
25
+ N_TRANSFER.class_eval do
26
+ include DebugHelper
27
+ end
28
+
29
+ N_EXCEPT.class_eval do
30
+ include DebugHelper
31
+ end
32
+
33
+ N_LET.class_eval do
34
+ include DebugHelper
35
+ end
36
+
37
+ N_ACTION.class_eval do
38
+ include DebugHelper
39
+ end
40
+
41
+ N_ATOC.class_eval do
42
+ include DebugHelper
43
+
44
+ def inspect
45
+ name = sym_name == "$" ? "$#{grammar.symname(grammar[rx].lhs)}" : sym_name
46
+ "<N_ATOC:#{[name, attr_name, rx].inspect}>"
47
+ end
48
+
49
+ def pretty_print(q)
50
+ name = begin
51
+ sym_name == "$" ? "$#{grammar.symname(grammar[rx].lhs)}" : sym_name
52
+ rescue StandardError
53
+ nil
54
+ end
55
+ q.group(1, "<N_ATOC:", ">") { q.pp [name, attr_name, rx] }
56
+ end
57
+
58
+ def grammar
59
+ $grammar # rubocop: disable Style/GlobalVars
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,47 @@
1
+ class Depager::ActionExtension < Depager::Extension
2
+ def init_extension
3
+ @action_code = ""
4
+ @on_reduce = []
5
+ end
6
+
7
+ def term_extension
8
+ g_parser.outer_code <<
9
+ generate_action_decorator_code(@on_reduce, @action_code)
10
+ end
11
+
12
+ def pre_rule_list
13
+ return unless /^%ACTION\{\s*$/.match?(g_parser.original_line)
14
+
15
+ while (line = file.gets)
16
+ break if /^%\}\s*$/.match?(line)
17
+
18
+ @action_code << line
19
+ end
20
+ g_parser.update_context ""
21
+ end
22
+
23
+ def post_rhs
24
+ return unless /\s*\{/.match?(g_parser.line)
25
+
26
+ @original_line = g_parser.original_line
27
+ @line = g_parser.line
28
+ lineno = g_parser.file.lineno
29
+ code = modify_action_code(parse_block)
30
+ n = g_parser.rules.size - 1
31
+ @action_code <<
32
+ expand_inline_code(code, lineno, wrap: "def _act_#{n} val", delta: 1)
33
+ g_parser.update_context @line
34
+ @on_reduce[n] = ":_act_#{n}"
35
+ end
36
+
37
+ def modify_action_code(code)
38
+ let_code = " # empty rule\n"
39
+ unless g_parser.rhs_names.empty?
40
+ vars = g_parser.rhs_names.map do |i|
41
+ /[a-zA-Z][a-zA-Z0-9_]*/.match?(i) ? "_#{i}" : "_"
42
+ end
43
+ let_code = " #{vars.join(', ')}, = *val\n"
44
+ end
45
+ let_code << code
46
+ end
47
+ end