depager 0.2.3 → 0.3.0.b20160729

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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/README.en +4 -19
  3. data/README.ja +42 -79
  4. data/bin/depager +42 -45
  5. data/examples/action_pl0d/pl0d.action.dr +421 -0
  6. data/examples/action_pl0d/test.pl0ds +49 -0
  7. data/examples/c89/c89.dr +493 -496
  8. data/examples/c89/test.c89 +10 -10
  9. data/examples/extension/astdf.rb +10 -0
  10. data/examples/extension/atree.dr +55 -0
  11. data/examples/{sample_calc → extension}/calc.atree.dr +42 -43
  12. data/examples/extension/calc.simple_action.dr +33 -0
  13. data/examples/extension/paction.dr +16 -15
  14. data/examples/extension/pactiontest.dr +14 -14
  15. data/examples/extension/simple_action.rb +44 -0
  16. data/examples/pl0d/pl0ds.dr +337 -334
  17. data/examples/pl0d/test.pl0ds +33 -33
  18. data/examples/rie_calc/calc.rie.dr +57 -0
  19. data/examples/rie_calc/test.calc +4 -0
  20. data/examples/rie_dcuse/dcuse.rie.dr +71 -0
  21. data/examples/rie_dcuse/test.dcuse +1 -0
  22. data/examples/rie_pl0/orig_ex/exerrdg.pl0 +44 -0
  23. data/examples/rie_pl0/orig_ex/exerrm.pl0 +19 -0
  24. data/examples/rie_pl0/orig_ex/exerrmre.pl0 +20 -0
  25. data/examples/rie_pl0/orig_ex/exerrtok.pl0 +18 -0
  26. data/examples/rie_pl0/orig_ex/exmdg.pl0 +40 -0
  27. data/examples/rie_pl0/orig_ex/exmdgwwl.pl0 +43 -0
  28. data/examples/rie_pl0/orig_ex/exmrw.pl0 +22 -0
  29. data/examples/rie_pl0/orig_ex/exmwwl.pl0 +18 -0
  30. data/examples/rie_pl0/orig_ex/exnorw.pl0 +17 -0
  31. data/examples/rie_pl0/pl0.rie.dr +450 -0
  32. data/examples/rie_pl0/test.pl0 +10 -0
  33. data/examples/sample_calc/calc.action.dr +33 -33
  34. data/examples/sample_calc/calc.ast.action.dr +65 -66
  35. data/examples/sample_calc/calc.ast.dr +55 -55
  36. data/examples/sample_calc/calc.cst.dr +45 -45
  37. data/examples/sample_calc/calc.dr +43 -43
  38. data/examples/sample_calc/calc.lex.dr +29 -29
  39. data/examples/sample_calc/{calc_prec.nvaction.dr → calc_prec.action.dr} +31 -31
  40. data/examples/slex_test/divreg.slex.dr +29 -29
  41. data/examples/slex_test/ljoin.slex.dr +36 -36
  42. data/examples/slex_test/test.divreg +1 -1
  43. data/examples/slex_test/test.ljoin +3 -3
  44. data/lib/depager.rb +582 -670
  45. data/lib/depager/grammar.rb +256 -291
  46. data/lib/depager/lr.rb +574 -579
  47. data/lib/depager/parser.rb +282 -277
  48. data/lib/depager/ruby/plugins/_rie_debug.rb +35 -0
  49. data/lib/depager/ruby/plugins/action.rb +53 -43
  50. data/lib/depager/ruby/plugins/ast.dr +364 -269
  51. data/lib/depager/ruby/plugins/ast.rb +1367 -1308
  52. data/lib/depager/ruby/plugins/cst.dr +172 -180
  53. data/lib/depager/ruby/plugins/cst.rb +587 -626
  54. data/lib/depager/ruby/plugins/lex.dr +85 -89
  55. data/lib/depager/ruby/plugins/lex.rb +310 -336
  56. data/lib/depager/ruby/plugins/rie.dr +723 -0
  57. data/lib/depager/ruby/plugins/rie.rb +1653 -0
  58. data/lib/depager/ruby/plugins/slex.dr +202 -200
  59. data/lib/depager/ruby/plugins/slex.rb +780 -817
  60. data/lib/depager/ruby/plugins/srp.rb +56 -51
  61. data/lib/depager/ruby/templates/extension_lalr_master.erb +46 -51
  62. data/lib/depager/ruby/templates/extension_lalr_slave.erb +99 -107
  63. data/lib/depager/ruby/templates/single_lalr_parser.erb +115 -117
  64. data/lib/depager/utils.rb +148 -318
  65. data/lib/depager/version.rb +4 -3
  66. metadata +52 -60
  67. data/ChangeLog +0 -16
  68. data/data/depager/pre-setup.rb +0 -3
  69. data/examples/c89/c89.tab.rb +0 -7127
  70. data/examples/pl0d/pl0ds.tab.rb +0 -2698
  71. data/examples/sample_calc/calc.action.tab.rb +0 -457
  72. data/examples/sample_calc/calc.ast.action.tab.rb +0 -749
  73. data/examples/sample_calc/calc.ast.tab.rb +0 -665
  74. data/examples/sample_calc/calc.astdf.dr +0 -54
  75. data/examples/sample_calc/calc.astdf.tab.rb +0 -672
  76. data/examples/sample_calc/calc.atree.tab.rb +0 -451
  77. data/examples/sample_calc/calc.cst.tab.rb +0 -644
  78. data/examples/sample_calc/calc.lex.tab.rb +0 -374
  79. data/examples/sample_calc/calc.nvaction.dr +0 -33
  80. data/examples/sample_calc/calc.nvaction.tab.rb +0 -465
  81. data/examples/sample_calc/calc.tab.rb +0 -365
  82. data/examples/sample_calc/calc_prec.nvaction.tab.rb +0 -431
  83. data/examples/slex_test/divreg.slex.tab.rb +0 -303
  84. data/examples/slex_test/ljoin.slex.tab.rb +0 -370
  85. data/lib/depager/ruby/plugins/_ast_tmpl.rb +0 -73
  86. data/lib/depager/ruby/plugins/astdf.rb +0 -6
  87. data/lib/depager/ruby/plugins/atree.dr +0 -55
  88. data/lib/depager/ruby/plugins/atree.rb +0 -347
  89. data/lib/depager/ruby/plugins/nvaction.rb +0 -19
  90. data/lib/depager/ruby/templates/simple.erb +0 -23
  91. data/setup.rb +0 -1585
@@ -0,0 +1,450 @@
1
+ %class Pl0::Parser
2
+ %extend Depager::Lexer ('plugins/lex.rb')
3
+ %extend Depager::Rie ('plugins/rie.rb')
4
+ #%decorate Depager::LALR::ShiftReducePrinter ('plugins/srp.rb')
5
+ %decorate @Rie
6
+ %inner{
7
+ KEYWORDS = {
8
+ "begin" => :BEGINN,
9
+ "end" => :END,
10
+ "call" => :CALL,
11
+ "const" => :CONST,
12
+ "do" => :DO,
13
+ "if" => :IF,
14
+ "then" => :THEN,
15
+ "odd" => :ODD,
16
+ "procedure" => :PROCEDURE,
17
+ "read" => :READ,
18
+ "writeln" => :WRITELN,
19
+ "write" => :WRITE,
20
+ "var" => :VAR,
21
+ "while" => :WHILE,
22
+ }
23
+ %}
24
+ %%
25
+ %LEX{
26
+ /\s+/, /\#.*/ { }
27
+ "<>" { yield token( '<>' ) }
28
+ "<=" { yield token( '<=' ) }
29
+ ">=" { yield token( '>=' ) }
30
+ ":=" { yield token( ':=' ) }
31
+ /\d+/ { yield token( :NUMBER, $&.to_i ) }
32
+ /\w+/ { yield token( KEYWORDS[$&] || :IDENT, $& ) }
33
+ /./ { yield token( $& ) }
34
+ %}
35
+
36
+ #begin-rule
37
+ program [ code ] :
38
+ block '.'
39
+ {
40
+ block._env = newenv()
41
+ block._lab = genlab()
42
+ $.code = block.code
43
+ exec_code(linearize_code($.code))
44
+ }
45
+ ;
46
+ block [ _env, _lab, code ] :
47
+ constdefpart vardeclpart procdeclpart statement
48
+ {
49
+ %thread env
50
+ %except constdefpart._env = newenv( $._env )
51
+ $.code = [
52
+ [ :O_JMP, 0, $._lab ],
53
+ procdeclpart.code,
54
+ [ :O_LAB, 0, $._lab ],
55
+ [ :O_INT, 0, procdeclpart.env.nvars ],
56
+ statement.code,
57
+ [ :O_OPR, 0, :P_RET ]
58
+ ]
59
+ debug_info "SYMS:\n" + procdeclpart.env.pretty_inspect
60
+ debug_info "CODE:\n" + $.code.pretty_inspect
61
+ }
62
+ ;
63
+ constdefpart [ _env:eq, env ] :
64
+ # empty
65
+ { %thread env }
66
+ | CONST constdeflist ';'
67
+ { %thread env }
68
+ ;
69
+ constdeflist [ _env:eq, env ] :
70
+ constdef
71
+ { %thread env }
72
+ | constdeflist ',' constdef
73
+ { %thread env }
74
+ ;
75
+ constdef [ _env:eq, env ] :
76
+ IDENT '=' NUMBER
77
+ {
78
+ $.env = $._env | [ entry(:CONSTANT, IDENT.value, NUMBER.value) ]
79
+ not $._env[ IDENT.value ] or
80
+ message "redeclaration of constant '%s'", IDENT.value
81
+ }
82
+ ;
83
+ vardeclpart [ _env:eq, env ] :
84
+ # empty
85
+ { %thread env }
86
+ | VAR vardecllist ';'
87
+ { %thread env }
88
+ ;
89
+ vardecllist [ _env:eq, env ] :
90
+ vardecl
91
+ { %thread env }
92
+ | vardecllist ',' vardecl
93
+ { %thread env }
94
+ ;
95
+ vardecl [ _env:eq, env ] :
96
+ IDENT
97
+ {
98
+ $.env = $._env | [ entry(:VARIABLE, IDENT.value, 0) ]
99
+ not $._env[ IDENT.value ] or
100
+ message "redeclaration of variable '%s'",IDENT.value
101
+ }
102
+ ;
103
+ procdeclpart [ _env:eq, env, code ] :
104
+ # empty
105
+ {
106
+ %thread env
107
+ $.code = [ ]
108
+ }
109
+ | procdeclpart procdecl
110
+ {
111
+ %thread env
112
+ $.code = procdeclpart.code + procdecl.code
113
+ }
114
+ ;
115
+ procdecl [ _env:eq, env, code ] :
116
+ prochead ';' block ';'
117
+ {
118
+ %thread env
119
+ %transfer code
120
+ block._lab = prochead.lab
121
+ }
122
+ ;
123
+ prochead [ _env:eq, env, lab ] :
124
+ PROCEDURE IDENT
125
+ {
126
+ lab = genlab()
127
+ $.env = $._env | [ entry(:PROC, IDENT.value, lab) ]
128
+ $.lab = lab
129
+ not $._env[ IDENT.value ] or
130
+ message "redeclaration of procedure '%s'",IDENT.value
131
+ }
132
+ ;
133
+ statement [ _env:eq, code ] :
134
+ # empty
135
+ { $.code = []; }
136
+ | ident ':=' expression
137
+ {
138
+ %transfer _env
139
+ $.code = [
140
+ expression.code,
141
+ [ :O_STO, $._env.level - ident.entry.level, ident.entry.value ]
142
+ ]
143
+ ident.entry.kind == :VARIABLE or
144
+ message "assignment to constant/procedure is not allowed"
145
+ }
146
+ | CALL ident
147
+ {
148
+ %transfer _env
149
+ $.code = [
150
+ [ :O_CAL, $._env.level - ident.entry.level, ident.entry.value ]
151
+ ]
152
+ ident.entry.kind == :PROC or
153
+ message "call of a constant or a variable is meaningless"
154
+ }
155
+ | IF condition THEN statement
156
+ {
157
+ %transfer _env
158
+ lab = genlab();
159
+ $.code = [
160
+ condition.code,
161
+ [ :O_JPC, 0, lab ],
162
+ statement.code,
163
+ [ :O_LAB, 0, lab ]
164
+ ]
165
+ }
166
+ | WHILE condition DO statement
167
+ {
168
+ %transfer _env
169
+ lab1 = genlab()
170
+ lab2 = genlab()
171
+ $.code = [
172
+ [ :O_LAB, 0, lab1 ],
173
+ condition.code,
174
+ [ :O_JPC, 0, lab2 ],
175
+ statement.code,
176
+ [ :O_JMP, 0, lab1 ],
177
+ [ :O_LAB, 0, lab2 ]
178
+ ]
179
+ }
180
+ | WRITE '(' expression ')'
181
+ {
182
+ %transfer _env
183
+ $.code = [
184
+ expression.code,
185
+ [ :O_CSP, 0, :WRI ]
186
+ ]
187
+ }
188
+ | WRITELN '(' expression ')'
189
+ {
190
+ %transfer _env
191
+ $.code = [
192
+ expression.code,
193
+ [ :O_CSP, 0, :WRI ],
194
+ [ :O_CSP, 0, :WRL ]
195
+ ]
196
+ }
197
+ | WRITELN
198
+ { $.code = [ [ :O_CSP, 0, :WRL ] ] }
199
+ | READ '(' ident ')'
200
+ {
201
+ %transfer _env
202
+ $.code = [
203
+ [ :O_CSP, 0, :RDI ],
204
+ [ :O_STO, $._env.level - ident.entry.level, ident.entry.value ]
205
+ ]
206
+ ident.entry.kind == :VARIABLE or
207
+ message "read to constant/procedure is not allowed"
208
+ }
209
+ | BEGINN statementlist END
210
+ { %transfer _env, code }
211
+ ;
212
+
213
+ statementlist [ _env:eq, code ] :
214
+ statement
215
+ { %transfer _env, code }
216
+ | statementlist ';' statement
217
+ {
218
+ %transfer _env
219
+ $.code = statementlist.code + [ statement.code ]
220
+ }
221
+
222
+ ;
223
+ expression [ _env:eq, code ] :
224
+ term
225
+ { %transfer _env, code }
226
+ | '+' term
227
+ { %transfer _env, code }
228
+ | '-' term
229
+ {
230
+ %transfer _env
231
+ $.code = [
232
+ term.code,
233
+ [ :O_OPR, 0, :P_NEG ]
234
+ ]
235
+ }
236
+ | expression addsub term
237
+ {
238
+ %transfer _env;
239
+ $.code = [
240
+ expression.code,
241
+ term.code,
242
+ addsub.code
243
+ ]
244
+ }
245
+ ;
246
+ addsub [ code ] :
247
+ '+' { $.code = [ :O_OPR, 0, :P_ADD ] }
248
+ | '-' { $.code = [ :O_OPR, 0, :P_SUB ] }
249
+ ;
250
+ term [ _env:eq, code ] :
251
+ factor
252
+ { %transfer _env, code }
253
+ | term muldiv factor
254
+ {
255
+ %transfer _env
256
+ $.code = [
257
+ term.code,
258
+ factor.code,
259
+ muldiv.code
260
+ ]
261
+ }
262
+ ;
263
+ muldiv [ code ] :
264
+ '*' { $.code = [ :O_OPR, 0, :P_MUL ] }
265
+ | '/' { $.code = [ :O_OPR, 0, :P_DIV ] }
266
+ ;
267
+ factor [ _env:eq, code ] :
268
+ ident
269
+ {
270
+ %transfer _env
271
+ $.code = ident.entry.kind == :CONSTANT ?
272
+ [ :O_LIT, 0, ident.entry.value ] :
273
+ [ :O_LOD, $._env.level - ident.entry.level, ident.entry.value ]
274
+ ident.entry.kind != :PROC or
275
+ message "expression must not contain a procedure identifier"
276
+ }
277
+ | NUMBER
278
+ { $.code = [ :O_LIT, 0, NUMBER.value ] }
279
+ | '(' expression ')'
280
+ { %transfer _env, code }
281
+ ;
282
+
283
+ condition [ _env:eq, code ] :
284
+ ODD expression
285
+ {
286
+ %transfer _env
287
+ $.code = [
288
+ expression.code,
289
+ [ :O_OPR, 0, :P_ODD ]
290
+ ]
291
+ }
292
+ | expression-left relop expression-right
293
+ {
294
+ %transfer _env
295
+ $.code = [
296
+ left.code,
297
+ right.code,
298
+ relop.code
299
+ ]
300
+ }
301
+ ;
302
+ relop [ code ] :
303
+ '=' { $.code = [ :O_OPR, 0, :P_EQ ] }
304
+ | '<>' { $.code = [ :O_OPR, 0, :P_NE ] }
305
+ | '<' { $.code = [ :O_OPR, 0, :P_LT ] }
306
+ | '>' { $.code = [ :O_OPR, 0, :P_GT ] }
307
+ | '<=' { $.code = [ :O_OPR, 0, :P_LE ] }
308
+ | '>=' { $.code = [ :O_OPR, 0, :P_GE ] }
309
+ ;
310
+ ident [ _env:eq, entry ] :
311
+ IDENT
312
+ {
313
+ $.entry = $._env[ IDENT.value ]
314
+ $._env[ IDENT.value ] or
315
+ message "undeclared identifier %s", IDENT.value
316
+ }
317
+ ;
318
+ #end-rule
319
+ %%
320
+ class Pl0::Rie
321
+ class Env
322
+ attr_reader :ary, :level
323
+ def initialize ary, level = 0
324
+ @ary, @level = ary, level
325
+ # warn self.inspect
326
+ end
327
+ def nvars
328
+ @ary.inject(0){|r, i| i.level == level and i.kind == :VARIABLE and r += 1 ; r }
329
+ end
330
+ def | ary
331
+ x = @ary.find_all{|i| i.level == level and i.kind == :VARIABLE }.size+3
332
+ arg = @ary.dup
333
+ ary.each do |i|
334
+ i.level = level
335
+ if i.kind == :VARIABLE
336
+ i.value = x
337
+ x += 1
338
+ end
339
+ arg.delete_if{|j| j.name == i.name}
340
+ arg << i
341
+ end
342
+ Env.new(arg, level)
343
+ end
344
+ def [] name
345
+ @ary.find{|i| i.name == name }
346
+ end
347
+ def inspect
348
+ "[#{@level}|#{@ary.inspect}]"
349
+ end
350
+ end
351
+ def newenv arg = nil
352
+ arg ? Env.new(arg.ary.dup, arg.level+1) : Env.new([])
353
+ end
354
+ def genlab
355
+ @label ||= 0
356
+ @label += 1
357
+ end
358
+ class Entry
359
+ attr_accessor :kind, :name, :value, :level
360
+ def initialize k, n, v
361
+ @kind, @name, @value = k, n, v
362
+ @level = nil
363
+ end
364
+ def inspect
365
+ "(#{@name}.#{@level}:#{@kind.to_s[0,1]}/#{@value})"
366
+ end
367
+ end
368
+ def entry k, n, v
369
+ #warn "ENTRY:#{n}:#{v.inspect}"
370
+ Entry.new(k, n, v)
371
+ end
372
+ def message *args
373
+ print("#{basis.file.lineno}:")
374
+ printf(*args); puts "\n"; exit
375
+ end
376
+
377
+ def debug_info *args
378
+ $DEBUG and warn(sprintf(*args))
379
+ end
380
+ def linearize_code code, res=[], labs={}
381
+ code.each do |i|
382
+ case i[0]
383
+ when :O_LAB
384
+ lab, addr = i[2], res.size
385
+ debug_info "PATCH: #{lab}->#{addr} @ #{labs[lab].inspect}"
386
+ labs[lab] and labs[lab].each{|i| res[i][2] = addr }
387
+ labs[lab] = res.size
388
+ when :O_JMP, :O_JPC, :O_CAL
389
+ lab, addr = i[2], labs[i[2]]
390
+ if addr.is_a? Integer
391
+ i[2] = addr
392
+ else
393
+ labs[lab] ||= []
394
+ labs[lab] << res.size
395
+ end
396
+ res << i
397
+ when Symbol
398
+ res << i
399
+ else
400
+ linearize_code i, res, labs
401
+ end
402
+ end ; res
403
+ end
404
+ # :-3(BP) :-2 :-1 *STACK*
405
+ # [lexical base][caller base][PC]{...vars...}
406
+ def exec_code ils
407
+ warn "\n** CODE **"
408
+ ils.each_with_index{|i,x| warn "#{'% 4i'%x} #{i.inspect}"}
409
+ warn "\n** EXEC **"
410
+ pc, bp, s = 0, 1, [0, 0, 0, 0]
411
+ begin
412
+ op, l, a = ils[pc] ; pc += 1
413
+ debug_info " #{s.inspect}\nPC:#{pc-1} BP:#{bp} CODE:[#{op}, #{l}, #{a}]"
414
+ case op
415
+ when :O_LIT ; s.push a
416
+ when :O_OPR ;
417
+ case a
418
+ when :P_RET; _, bp, pc, = s.slice!(bp, s.size-1)
419
+ when :P_NEG; s.push(-s.pop)
420
+ when :P_ODD; s.push s.pop % 2
421
+ when :P_ADD; r=s.pop; s.push s.pop + r
422
+ when :P_SUB; r=s.pop; s.push s.pop - r
423
+ when :P_MUL; r=s.pop; s.push s.pop * r
424
+ when :P_DIV; r=s.pop; s.push s.pop / r
425
+ when :P_EQ ; r=s.pop; s.push( s.pop == r ? 1 : 0 )
426
+ when :P_NE ; r=s.pop; s.push( s.pop != r ? 1 : 0 )
427
+ when :P_LT ; r=s.pop; s.push( s.pop < r ? 1 : 0 )
428
+ when :P_GE ; r=s.pop; s.push( s.pop >= r ? 1 : 0 )
429
+ when :P_GT ; r=s.pop; s.push( s.pop > r ? 1 : 0 )
430
+ when :P_LE ; r=s.pop; s.push( s.pop <= r ? 1 : 0 )
431
+ end
432
+ when :O_LOD; x=bp;l.times{x=s[x]}; s.push s[x+a];
433
+ when :O_STO; x=bp;l.times{x=s[x]}; s[x+a] = s.pop;
434
+ when :O_CAL; x=bp;l.times{x=s[x]}; s.push x, bp, pc; bp, pc = s.size-3, a;
435
+ when :O_INT; s.fill(0, s.size, a)
436
+ when :O_JMP; pc = a
437
+ when :O_JPC; pc = a if s.pop == 0
438
+ when :O_CSP;
439
+ case a
440
+ when :RDI; print "?"; s.push Integer(STDIN.gets)
441
+ when :WRI; printf( "\t%10d", s.pop )
442
+ when :WRL; puts ""
443
+ end
444
+ end
445
+ end while pc != 0
446
+ end
447
+ end
448
+
449
+ parser = Pl0.create_decorated_parser
450
+ r, = parser.parse(ARGF)
@@ -0,0 +1,10 @@
1
+ var x, y;
2
+ procedure multiply;
3
+ var a;
4
+ begin
5
+ a := x*y;
6
+ write(x) ; write(y) ; writeln(a)
7
+ end;
8
+ begin
9
+ x := 5; y := 10; call multiply
10
+ end.