depager 0.2.3 → 0.3.0.b20160729

Sign up to get free protection for your applications and to get access to all the features.
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.