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
@@ -0,0 +1,367 @@
1
+ %defext Depager::ASTBuilderExtension
2
+ %extend Depager::Lexer ('depager/plugins/lex.rb')
3
+ %extend Depager::Action ('depager/plugins/action.rb')
4
+ %decorate @Action
5
+ #%decorate Depager::LALR::ShiftReducePrinter ('depager/plugins/srp.rb')
6
+ %inner{
7
+ attr_accessor :action_code, :on_reduce, :visitors
8
+ def init_extension
9
+ @visitors = Hash.new{|hash, key| hash[key] = []}
10
+ @action_code = ''
11
+ @on_reduce = []
12
+ @output_file_name = nil
13
+ end
14
+ def term_extension
15
+ g_parser.outer_code <<
16
+ generate_action_decorator_code(@on_reduce, @action_code)
17
+ end
18
+
19
+ def modify_action_code code, nodes=[]
20
+ code = code.gsub(/\$\.([a-z_])/, 'node.\1')
21
+ code << <<-CODE
22
+ rescue
23
+ warn "raise at src:\#{node.lineno}/\#{node.class.name}"
24
+ raise
25
+ CODE
26
+ end
27
+
28
+ def gen_accept_code sym
29
+ return ''
30
+ end
31
+
32
+ def node_name name
33
+ name = name == '@List' ? "NodeList" : "Node_#{name}"
34
+ "#{target_namespace}::#{name}"
35
+ end
36
+
37
+ attr_reader :output_file_name
38
+ def output_file_name= name
39
+ name = name.match(/'(.+)'/) ? $1 : name
40
+ @output_file_name = name
41
+ end
42
+ %}
43
+ %hook pre_rule_list /%AST\{\s*\Z/ skip
44
+ %banner '%AST{ ... }'
45
+ %%
46
+
47
+ %LEX{
48
+ /\s+/, /#.*/ { }
49
+ /%\}\s*\Z/ { @line = $'; yield nil,nil }
50
+ 'Node' { yield token(:NODE, $&) }
51
+ 'Visitor' { yield token(:VISITOR, $&) }
52
+ /[a-zA-Z][a-zA-Z0-9_]*/ { yield token(:ID, $&) }
53
+ '{' ! { lineno = file.lineno; yield token(:ACTION, parse_block, lineno) }
54
+ /./ { yield token($&, $&) }
55
+ %}
56
+
57
+ #begin-rule
58
+ start:
59
+ opt_defnode opt_defvis defnode_list
60
+ {
61
+ code = "module #{target_namespace}\n"
62
+ code << _opt_defnode
63
+ code << val[2]
64
+ master.visitors.each do |name, body|
65
+ code << ERB.new(master.class::VISITOR_TEMPLATE, nil, '-').result(binding)
66
+ end
67
+ code << "end\n"
68
+ if master.output_file_name
69
+ File.open(master.output_file_name, 'w') do |f|
70
+ f.write code
71
+ end
72
+ g_parser.outer_code << %!require '#{master.output_file_name}'\n!
73
+ else
74
+ g_parser.outer_code << code
75
+ end
76
+ }
77
+ ;
78
+ opt_defnode:
79
+ { "" }
80
+ | NODE opt_attr ACTION
81
+ {
82
+ ini = <<-CODE
83
+ def initialize
84
+ #{_ACTION.value}
85
+ end
86
+ CODE
87
+ ERB.new(master.class::BASE_NODE_TEMPLATE, nil, '-').result(binding)
88
+ }
89
+ ;
90
+ opt_defvis:
91
+ { [] }
92
+ | VISITOR opt_action
93
+ {
94
+ _opt_action[nil] ||= Token.new('', 0)
95
+ _opt_action.each do |pass, act|
96
+ master.visitors[pass].unshift(
97
+ master.expand_inline_code(act.value.to_s, act.lineno))
98
+ end
99
+ }
100
+ ;
101
+ defnode_list:
102
+ defnode { _defnode }
103
+ | defnode_list defnode { _defnode_list << _defnode}
104
+ ;
105
+ defnode:
106
+ defnode_header opt_attr opt_action
107
+ {
108
+ name, args = _defnode_header
109
+ nodes, accept, attrs = [], '', _opt_attr
110
+ args.each do |i|
111
+ if i =~ /\-(.*)/
112
+ nodes.push $1
113
+ attrs.push $1
114
+ else
115
+ nodes.push i
116
+ accept << master.gen_accept_code(i)
117
+ end
118
+ end
119
+ _opt_action[nil] = Token.new('', 0) unless _opt_action[nil]
120
+ _opt_action.each do |pass, act|
121
+ vis_code = master.modify_action_code(act.value, nodes - attrs)
122
+ master.visitors[pass] <<
123
+ master.expand_inline_code(vis_code, act.lineno, :wrap => "def visit_Node_#{name} node")
124
+ end
125
+ ERB.new(master.class::NODE_TEMPLATE, nil, '-').result(binding)
126
+ }
127
+ ;
128
+ defnode_header:
129
+ ID '(' ')' { [_ID.value, []]}
130
+ | ID '(' fact_list ')' { [_ID.value, _fact_list] }
131
+ ;
132
+ opt_attr:
133
+ { [] }
134
+ | '[' ']' { [] }
135
+ | '[' id_list ']' { _id_list }
136
+ ;
137
+ fact_list:
138
+ fact { [_fact] }
139
+ | fact_list ',' fact { _fact_list.push _fact }
140
+ ;
141
+ fact:
142
+ ID { _ID.value }
143
+ | '-' ID { '-' + _ID.value }
144
+ ;
145
+ id_list:
146
+ ID { [ _ID.value ] }
147
+ | id_list ',' ID { _id_list.push _ID.value }
148
+ ;
149
+ opt_action:
150
+ { {nil => Token.new('', 0)} }
151
+ | ACTION { {nil => _ACTION} }
152
+ | pass_action_list
153
+ {
154
+ Hash[ *_pass_action_list.flatten ].merge({nil => Token.new('', 0)})
155
+ }
156
+ ;
157
+ pass_action_list:
158
+ pass_action { [ _pass_action ] }
159
+ | pass_action_list pass_action { _pass_action_list << _pass_action }
160
+ ;
161
+
162
+ pass_action:
163
+ '<' ID '>' ACTION { [_ID.value, _ACTION]}
164
+ ;
165
+ #end-rule
166
+ %%
167
+ %hook post_rhs /=>/ skip
168
+ %banner '=>...'
169
+ %prec{
170
+ left LL '@'
171
+ %}
172
+ %inner{
173
+ def do_default
174
+ n = g_parser.rules.size-1
175
+ master.action_code << <<~CODE
176
+ def _ast_#{n} val
177
+ NilNode.new(basis.file.lineno)
178
+ end
179
+ CODE
180
+ master.on_reduce[n] = ":_ast_#{n}"
181
+ end
182
+ %}
183
+ %%
184
+
185
+ %LEX{
186
+ /[ \t]+/ { }
187
+ /\r?\n/ { yield nil, nil }
188
+ /<</ { yield token(:LL, $&) }
189
+ /%([a-zA-Z0-9_]+)((::[a-zA-Z0-9_]+)*)/
190
+ { yield token(:CONST, $1+$2) }
191
+ /%\((.+)\)%/ { yield token(:EMBED, $1) }
192
+ 'nil' { yield token(:NIL, $&) }
193
+ 'NilNode' { yield token(:NILNODE, $&) }
194
+ /[0-9]+/ { yield token(:NUMBER, $&.to_i) }
195
+ /:[a-zA-Z0-9_]+/ { yield token(:SYMBOL, $&) }
196
+ /[a-zA-Z][a-zA-Z0-9_]*/ { yield token(:ID, $&) }
197
+ /'(.+)'/ { yield token(:STR, $1) }
198
+ /./ { yield token($&, $&) }
199
+ %}
200
+ #begin-rule
201
+ start:
202
+ fnl
203
+ {
204
+ n = g_parser.rules.size-1
205
+ master.action_code <<
206
+ master.expand_inline_code(_fnl, basis.file.lineno, :wrap => "def _ast_#{n} val")
207
+ master.on_reduce[n] = ":_ast_#{n}"
208
+ }
209
+ ;
210
+ node:
211
+ ID '(' ')' { "#{master.node_name _ID.value}.new(basis.file.lineno)" }
212
+ | ID '(' fnlpair ')'
213
+ {
214
+ if g_parser.rhs.size > 0
215
+ "#{master.node_name _ID.value}.new(val[0].lineno, #{_fnlpair.join(', ')})"
216
+ else
217
+ "#{master.node_name _ID.value}.new(basis.file.lineno, #{_fnlpair.join(', ')})"
218
+ end
219
+ }
220
+ ;
221
+ fnlpair:
222
+ fnl { [_fnl] }
223
+ | fnlpair ',' fnl { _fnlpair << _fnl }
224
+ ;
225
+ fnl:
226
+ fact { _fact }
227
+ | node { _node }
228
+ | list { _list }
229
+ ;
230
+ fact:
231
+ ID opt_embed
232
+ {
233
+ unless i = g_parser.name_to_rhs_index(_ID.value)
234
+ warn "#{g_parser.lineno}: ?#{_ID.value}"
235
+ raise
236
+ end
237
+ "val[#{i}]#{val[1]}"
238
+ }
239
+ | CONST { "Depager::Token.new(#{_CONST.value})" }
240
+ | SYMBOL { "Depager::Token.new(#{_SYMBOL.value})" }
241
+ | STR { "Depager::Token.new('#{_STR.value}')" }
242
+ | NILNODE { "NilNode.new(basis.file.lineno)" }
243
+ | NUMBER { "Depager::Token.new(#{_NUMBER.value})" }
244
+ | NIL { "nil" }
245
+ ;
246
+ opt_embed:
247
+ { '' }
248
+ | EMBED { _EMBED.value }
249
+ ;
250
+ list:
251
+ '['']' { "#{master.node_name '@List'}.new(basis.file.lineno, [])" }
252
+ | '['fnlpair']'
253
+ {
254
+ if g_parser.rhs.size > 0
255
+ "#{master.node_name '@List'}.new(val[0].lineno, [#{_fnlpair.join(', ')}])"
256
+ else
257
+ "#{master.node_name '@List'}.new(basis.file.lineno, #{_fnlpair.join(', ')})"
258
+ end
259
+ }
260
+ | fnl-l LL fnl-r { "#{_l}.push(#{_r})" }
261
+ | fnl-l '@' fnl-r { "#{_l}.concat(#{_r})" }
262
+ ;
263
+ #end-rule
264
+ %%
265
+ %%
266
+
267
+ class Depager::ASTBuilderExtension
268
+ BASE_NODE_TEMPLATE = <<-'CODE'
269
+ class Node
270
+ attr_accessor :lineno
271
+ attr_accessor <%= _opt_attr.map{|i| ":#{i}" }.join(', ') %>
272
+ <%= ini %>
273
+
274
+ def self.[] lineno, *args
275
+ self.new lineno, *args
276
+ end
277
+
278
+ def accept v
279
+ end
280
+ end
281
+
282
+ class NodeList < Node
283
+ attr_accessor :lineno
284
+ def initialize(lineno, lst=[])
285
+ @lineno = lineno
286
+ @lst = lst.to_a.select{|i| ! i.is_a?(NilNode)}
287
+ end
288
+
289
+ <%- _opt_attr.each do |i| -%>
290
+ def all_<%= i %>
291
+ @lst.map{|i| i.<%= i %>}
292
+ end
293
+ <%- end -%>
294
+
295
+ def size
296
+ @lst.size
297
+ end
298
+ alias length size
299
+
300
+ def push(i)
301
+ @lst.push i unless i.is_a? NilNode
302
+ self
303
+ end
304
+
305
+ def concat(i)
306
+ @lst.concat i
307
+ self
308
+ end
309
+
310
+ def to_ary()
311
+ @lst
312
+ end
313
+
314
+ alias to_a to_ary
315
+ alias list to_ary
316
+
317
+ def accept(v)
318
+ @lst.each{|i| i.accept(v) }
319
+ end
320
+ end
321
+
322
+ class NilNode
323
+ attr_accessor :lineno
324
+ attr_accessor <%= _opt_attr.map{|i| ":#{i}" }.join(', ') %>
325
+
326
+ def initialize(lineno, *args)
327
+ @lineno = lineno
328
+ end
329
+
330
+ def accept v
331
+ end
332
+ end
333
+ CODE
334
+
335
+ NODE_TEMPLATE = <<-'CODE'
336
+ class Node_<%= name %> < Node
337
+ attr_accessor <%= nodes.map{|i| ":#{i}" }.join(', ') %>
338
+ attr_accessor <%= attrs.map{|i| ":#{i}" }.join(', ') %>
339
+
340
+ def initialize <%= ['lineno', *nodes].join(', ') %>
341
+ super()
342
+ @lineno = lineno
343
+ <%= nodes.inject(''){|r,i| r << " @#{i} = #{i}\n"} %>
344
+ end
345
+
346
+ def accept v
347
+ warn @lineno.to_s+':'+self.class.to_s if $DEBUG
348
+ <%= accept %>
349
+ v.visit_Node_<%= name %>(self)
350
+ self
351
+ end
352
+
353
+ def attributes
354
+ { <%= (nodes + attrs).uniq.map{|i| "#{i}: #{i}" }.join(', ') %>, lineno: lineno }
355
+ end
356
+ end
357
+ CODE
358
+
359
+ VISITOR_TEMPLATE = <<-'CODE'
360
+ class Visitor<%= name ? '_' + name : '' %>
361
+ def visit node
362
+ node.accept(self)
363
+ end
364
+ <%= body.join %>
365
+ end # Visitor<%= name ? '_' + name : '' %>
366
+ CODE
367
+ end