depager 0.1.9

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 (53) hide show
  1. data/ChangeLog +4 -0
  2. data/Manifest.txt +52 -0
  3. data/README.en +64 -0
  4. data/README.ja +128 -0
  5. data/bin/depager +47 -0
  6. data/data/depager/misc/depager-mode.el +209 -0
  7. data/data/depager/sample/extension/paction.dr +15 -0
  8. data/data/depager/sample/extension/pactiontest.dr +14 -0
  9. data/data/depager/sample/pl0d/pl0ds.dr +334 -0
  10. data/data/depager/sample/pl0d/pl0test.pl0 +34 -0
  11. data/data/depager/sample/sample_calc/calc.action.dr +33 -0
  12. data/data/depager/sample/sample_calc/calc.astdf.dr +54 -0
  13. data/data/depager/sample/sample_calc/calc.astl.action.dr +66 -0
  14. data/data/depager/sample/sample_calc/calc.astl.dr +55 -0
  15. data/data/depager/sample/sample_calc/calc.atree.dr +43 -0
  16. data/data/depager/sample/sample_calc/calc.cst.dr +45 -0
  17. data/data/depager/sample/sample_calc/calc.dr +43 -0
  18. data/data/depager/sample/sample_calc/calc.lex.dr +29 -0
  19. data/data/depager/sample/sample_calc/calc.nvaction.dr +33 -0
  20. data/data/depager/sample/sample_calc/calc_prec.nvaction.dr +31 -0
  21. data/data/depager/sample/slex_test/slextest1.dr +37 -0
  22. data/data/depager/sample/slex_test/slextest2.dr +33 -0
  23. data/lib/depager.rb +608 -0
  24. data/lib/depager/Rakefile +30 -0
  25. data/lib/depager/action.rb +47 -0
  26. data/lib/depager/ast_base.dr +232 -0
  27. data/lib/depager/ast_base.rb +1249 -0
  28. data/lib/depager/astdf.rb +10 -0
  29. data/lib/depager/astl.rb +14 -0
  30. data/lib/depager/atree.dr +55 -0
  31. data/lib/depager/atree.rb +336 -0
  32. data/lib/depager/cst.dr +182 -0
  33. data/lib/depager/cst.rb +625 -0
  34. data/lib/depager/lex.dr +76 -0
  35. data/lib/depager/lex.rb +306 -0
  36. data/lib/depager/lr.rb +604 -0
  37. data/lib/depager/nvaction.rb +21 -0
  38. data/lib/depager/parse_action.rb +24 -0
  39. data/lib/depager/parser.rb +248 -0
  40. data/lib/depager/psrtmpl.rb +33 -0
  41. data/lib/depager/slex.dr +161 -0
  42. data/lib/depager/slex.rb +646 -0
  43. data/lib/depager/srp.rb +50 -0
  44. data/lib/depager/template/astdf.erbs +57 -0
  45. data/lib/depager/template/astl.erbs +57 -0
  46. data/lib/depager/template/extension_lalr_master.erb +51 -0
  47. data/lib/depager/template/extension_lalr_slave.erb +107 -0
  48. data/lib/depager/template/simple.erb +21 -0
  49. data/lib/depager/template/single_lalr_parser.erb +97 -0
  50. data/lib/depager/utils.rb +355 -0
  51. data/lib/depager/version.rb +9 -0
  52. data/setup.rb +1585 -0
  53. metadata +103 -0
@@ -0,0 +1,15 @@
1
+ %defext PseudoActionExtension
2
+ %extend Lexer ('depager/lex.rb')
3
+ %extend Action ('depager/action.rb')
4
+ %decorate @Action ('depager/action.rb')
5
+ #%decorate ShiftReducePrinter ('depager/srp.rb')
6
+ %hook postrhs
7
+ %%
8
+ %LEX{
9
+ /\s/ { }
10
+ /./ { yield $&, $&, @lineno }
11
+ %}
12
+ start:
13
+ '{' '}' { warn 'HIT' }
14
+ ;
15
+ %%
@@ -0,0 +1,14 @@
1
+ %class PseudoActionTest
2
+ %extend PseudoAction ('paction.rb')
3
+ %%
4
+ #begin-rule
5
+ expr:
6
+ expr '+' fact { }
7
+ ;
8
+ fact:
9
+ ID { }
10
+ ;
11
+ #end-rule
12
+ %%
13
+ p = PseudoActionTest.new()
14
+ #p.yyparse(STDIN)
@@ -0,0 +1,334 @@
1
+ %class PL0d
2
+ %extend Lexer ('depager/lex.rb')
3
+ %extend ASTBuilderLazy ('depager/astl.rb')
4
+ %decorate @ASTBuilderLazy
5
+ #%decorate ShiftReducePrinter ('depager/srp.rb')
6
+ %%
7
+ %LEX{
8
+ /\s+/ { }
9
+ ':=' { yield _Token(:COLOEQ, $&) }
10
+ '<>' { yield _Token(:NOTEQ, $&) }
11
+ '<=' { yield _Token(:LE, $&) }
12
+ '>=' { yield _Token(:GE, $&) }
13
+ '=' { yield _Token(:EQ, $&) }
14
+ '<' { yield _Token(:LT, $&) }
15
+ '>' { yield _Token(:GT, $&) }
16
+ 'const' { yield _Token(:CONST, $&) }
17
+ 'var' { yield _Token(:VAR, $&) }
18
+ 'function'{ yield _Token(:FUNCTION, $&) }
19
+ 'begin' { yield _Token(:BEGINN, $&) }
20
+ 'end' { yield _Token(:END, $&) }
21
+ 'if' { yield _Token(:IF, $&) }
22
+ 'then' { yield _Token(:THEN, $&) }
23
+ 'while' { yield _Token(:WHILE, $&) }
24
+ 'do' { yield _Token(:DO, $&) }
25
+ 'return' { yield _Token(:RETURN, $&) }
26
+ 'writeln' { yield _Token(:WRITELN, $&) }
27
+ 'write' { yield _Token(:WRITE, $&) }
28
+ 'odd' { yield _Token(:ODD, $&) }
29
+ /[a-zA-Z][a-zA-Z0-9_]*/
30
+ { yield _Token(:IDENT, $&) }
31
+ /[0-9]+/ { yield _Token(:NUMBER, $&.to_i) }
32
+ /./ { yield _Token($&, $&) }
33
+ %}
34
+
35
+ %AST{
36
+ Node [value] { @value = nil }
37
+ Visitor
38
+ {
39
+ STEntry = Struct.new(:kind, :narg, :value)
40
+ def initialize
41
+ @global = {
42
+ '+' => STEntry.new(:FUNC, 2, proc{|a| a[0] + a[1] }),
43
+ '-' => STEntry.new(:FUNC, 2, proc{|a| a[0] - a[1] }),
44
+ '*' => STEntry.new(:FUNC, 2, proc{|a| a[0] * a[1] }),
45
+ '/' => STEntry.new(:FUNC, 2, proc{|a| a[0] / a[1] }),
46
+ '=' => STEntry.new(:FUNC, 2, proc{|a| a[0] == a[1] ? 1 : 0}),
47
+ '<>' => STEntry.new(:FUNC, 2, proc{|a| a[0] != a[1] ? 1 : 0}),
48
+ '<' => STEntry.new(:FUNC, 2, proc{|a| a[0] < a[1] ? 1 : 0}),
49
+ '>' => STEntry.new(:FUNC, 2, proc{|a| a[0] > a[1] ? 1 : 0}),
50
+ '<=' => STEntry.new(:FUNC, 2, proc{|a| a[0] <= a[1] ? 1 : 0}),
51
+ '>=' => STEntry.new(:FUNC, 2, proc{|a| a[0] >= a[1] ? 1 : 0}),
52
+ 'odd'=> STEntry.new(:FUNC, 1, proc{|a| a[0] & 1 }),
53
+
54
+ 'write' => STEntry.new(:FUNC, 1, proc{|a| print "#{a[0]} "; 1}),
55
+ 'writeln' => STEntry.new(:FUNC, 0, proc{|a| puts ''; 1}),
56
+ }
57
+ @env = [@global]
58
+ end
59
+ def lookup name
60
+ @env.reverse_each{|s| return s[name] if s[name]}
61
+ return nil
62
+ end
63
+ def dump_env n = 2
64
+ n = @env.size if n > @env.size
65
+ e = @env[n..-1].map{|i| Hash[* i.map{|k, v| [k, v.value]}.flatten ] }
66
+ warn e.pretty_inspect
67
+ end
68
+ }
69
+ program(block)
70
+ {
71
+ visit(~block)
72
+ }
73
+ block(decls, stmt)
74
+ {
75
+ @env.push({})
76
+ visit(~decls)
77
+ visit(~stmt)
78
+ @env.pop
79
+ }
80
+ var_decl(-idents)
81
+ {
82
+ ~idents.each do |ident|
83
+ if @env.last[ident.value]
84
+ warn "'#{ident.value}' already exist."; exit
85
+ else
86
+ @env.last[ident.value] = STEntry.new(:VAR, 0, 0)
87
+ end
88
+ end
89
+ }
90
+ const_decl(const_inits)
91
+ {
92
+ visit(~const_inits)
93
+ }
94
+ const_init(-ident, -number)
95
+ {
96
+ if @env.last[~ident.value]
97
+ warn "'#{~ident.value}' already exist."; exit
98
+ else
99
+ @env.last[~ident.value] = STEntry.new(:CONST, 0, ~number.value)
100
+ end
101
+ }
102
+ func_decl(-ident, -params, -block)
103
+ {
104
+ if @env[0][~ident.value]
105
+ warn "'#{~ident.value}' already exist."; exit
106
+ end
107
+ body = proc do |args|
108
+ value = 0
109
+ n = @env.size
110
+ @env.push({})
111
+ value = callcc do |c|
112
+ @env.last['return'] = STEntry.new(:VAR, 0, c)
113
+ ~params.each_with_index do |a, x|
114
+ @env.last[a.value] = STEntry.new(:VAR, 0, args[x])
115
+ end
116
+ visit(~block)
117
+ end
118
+ @env = @env[0, n]
119
+ value
120
+ end
121
+ @env.last[~ident.value] = STEntry.new(:FUNC, ~params.size, body)
122
+ }
123
+ nop_stmt(-nop)
124
+ {
125
+ }
126
+ assign_stmt(-ident, expr)
127
+ {
128
+ if ent = lookup(~ident.value)
129
+ unless ent.kind == :VAR
130
+ warn "'#{~ident.value}' not var."; exit
131
+ end
132
+ ent.value = visit(~expr).value
133
+ else
134
+ warn @env.pretty_inspect
135
+ warn "'#{~ident.value}' not found."; exit
136
+ end
137
+ }
138
+ begin_stmt(stmt, stmts)
139
+ {
140
+ visit(~stmt)
141
+ visit(~stmts)
142
+ }
143
+ if_stmt(cond, stmt)
144
+ {
145
+ if visit(~cond).value != 0
146
+ visit(~stmt)
147
+ end
148
+ }
149
+ while_stmt(cond, stmt)
150
+ {
151
+ while visit(~cond).value != 0
152
+ visit(~stmt)
153
+ end
154
+ }
155
+ return_stmt(expr)
156
+ {
157
+ ent = nil
158
+ @env.reverse_each{|s| break if ent = s['return'] }
159
+ unless ent
160
+ warn "'return' not in func."; exit
161
+ end
162
+ ent.value.call(visit(~expr).value)
163
+ }
164
+ apply(-ident, -args)
165
+ {
166
+ ent = nil
167
+ @env.reverse_each{|s| break if ent = s[~ident.value] }
168
+ unless ent
169
+ warn "'#{~ident.value}' not found."; exit
170
+ end
171
+ unless ent.kind == :FUNC
172
+ warn "'#{~ident.value}' not func."; exit
173
+ end
174
+
175
+ args = ~args.map{|a| visit(a).value }
176
+ # warn "#{' '*(@env.size-2)}|#{~ident.value} : #{args.inspect}"
177
+ unless ent.narg == args.size
178
+ warn "#{ent.narg} #{args.size} #{args.inspect}"
179
+ warn "'#{~ident.value}' unmatch args."; exit
180
+ end
181
+ ~value = ent.value.call(args)
182
+ # warn "#{' '*(@env.size-2)}|-> #{~value} @ #{~ident.value}"
183
+ }
184
+ refv(-ident)
185
+ {
186
+ unless ent = lookup(~ident.value)
187
+ warn "'#{~ident.value}' not found."; exit
188
+ end
189
+ if ent.kind == :VAR || ent.kind == :CONST
190
+ ~value = ent.value
191
+ else
192
+ warn "'#{~ident.value}' not var."; exit
193
+ end
194
+ }
195
+ number(-n)
196
+ {
197
+ ~value = ~n.value
198
+ }
199
+ %}
200
+ #begin-rule
201
+ program:
202
+ block '.'
203
+ => program(block)
204
+ ;
205
+
206
+ block:
207
+ opt_decl_list statement
208
+ => block(opt_decl_list, statement)
209
+ ;
210
+
211
+ opt_decl_list:
212
+ => []
213
+ | opt_decl_list decl
214
+ => opt_decl_list << decl
215
+ ;
216
+
217
+ decl:
218
+ CONST const_init_list ';'
219
+ => const_decl(const_init_list)
220
+ | VAR ident_list ';'
221
+ => var_decl(ident_list)
222
+ | FUNCTION IDENT '(' ')' block ';'
223
+ => func_decl(IDENT, [], block)
224
+ | FUNCTION IDENT '(' ident_list ')' block ';'
225
+ => func_decl(IDENT, ident_list, block)
226
+ ;
227
+
228
+ const_init_list:
229
+ const_init
230
+ => [ const_init ]
231
+ | const_init_list ',' const_init
232
+ => const_init_list << const_init
233
+ ;
234
+
235
+ const_init:
236
+ IDENT EQ NUMBER
237
+ => const_init(IDENT, NUMBER)
238
+ ;
239
+
240
+ ident_list:
241
+ IDENT
242
+ => [ IDENT ]
243
+ | ident_list ',' IDENT
244
+ => ident_list << IDENT
245
+ ;
246
+
247
+ statement:
248
+ => nop_stmt([])
249
+ | IDENT COLOEQ expression
250
+ => assign_stmt(IDENT, expression)
251
+ | BEGINN statement opt_state_list END
252
+ => begin_stmt(statement, opt_state_list)
253
+ | IF condition THEN statement
254
+ => if_stmt(condition, statement)
255
+ | WHILE condition DO statement
256
+ => while_stmt(condition, statement)
257
+ | RETURN expression
258
+ => return_stmt(expression)
259
+ | WRITE expression
260
+ => apply('write', [expression])
261
+ | WRITELN
262
+ => apply('writeln', [])
263
+ ;
264
+
265
+ opt_state_list:
266
+ => []
267
+ | opt_state_list ';' statement
268
+ => opt_state_list << statement
269
+ ;
270
+
271
+ condition:
272
+ ODD expression
273
+ => apply('odd', [expression])
274
+ | expression-e0 EQ expression-e1
275
+ => apply('=', [e0, e1])
276
+ | expression-e0 NOTEQ expression-e1
277
+ => apply('<>', [e0, e1])
278
+ | expression-e0 LT expression-e1
279
+ => apply('<', [e0, e1])
280
+ | expression-e0 GT expression-e1
281
+ => apply('>', [e0, e1])
282
+ | expression-e0 LE expression-e1
283
+ => apply('<=', [e0, e1])
284
+ | expression-e0 GE expression-e1
285
+ => apply('>=', [e0, e1])
286
+ ;
287
+
288
+ expression:
289
+ expression '+' term
290
+ => apply('+', [expression, term])
291
+ | expression '-' term
292
+ => apply('-', [expression, term])
293
+ | term
294
+ => term
295
+ | '-' term
296
+ => apply('UMINUS', [term])
297
+ ;
298
+
299
+ term:
300
+ term '*' factor
301
+ => apply('*', [term, factor])
302
+ | term '/' factor
303
+ => apply('/', [term, factor])
304
+ | factor
305
+ => factor
306
+ ;
307
+
308
+ factor:
309
+ IDENT
310
+ => refv(IDENT)
311
+ | NUMBER
312
+ => number(NUMBER)
313
+ | IDENT '(' ')'
314
+ => apply(IDENT, [])
315
+ | IDENT '(' exp_list ')'
316
+ => apply(IDENT, exp_list)
317
+ | '(' expression ')'
318
+ => expression
319
+ ;
320
+
321
+ exp_list:
322
+ expression
323
+ => [ expression ]
324
+ | exp_list ',' expression
325
+ => exp_list << expression
326
+ ;
327
+ #end-rule
328
+ %%
329
+ require 'pp'
330
+ psr = createDecoratedPL0d
331
+ t, = psr.yyparse(STDIN)
332
+ # pp t
333
+ v = Visitor.new
334
+ t.accept(v)
@@ -0,0 +1,34 @@
1
+ const m = 7, n = 85;
2
+ var x,y;
3
+
4
+ function puts10(x)
5
+ var i;
6
+ begin
7
+ i := 0;
8
+ while i < 10 do
9
+ begin
10
+ write x; writeln;
11
+ i := i + 1;
12
+ end;
13
+ return i
14
+ end;
15
+
16
+ function fact(x)
17
+ begin
18
+ write x; writeln;
19
+ if x = 1 then return 1;
20
+ return x * fact(x - 1);
21
+ end;
22
+
23
+ begin
24
+ x := m; y := n;
25
+ write x; write y; writeln;
26
+ x := 84; y := 36;
27
+ write x; write y; writeln;
28
+
29
+ y := puts10(5);
30
+ write y; writeln;
31
+
32
+ y := fact(5);
33
+ write y; writeln;
34
+ end.
@@ -0,0 +1,33 @@
1
+ %class TinyCalc
2
+ %extend Lexer ('depager/lex.rb')
3
+ %extend Action ('depager/action.rb')
4
+ %decorate @Action
5
+ #%decorate ShiftReducePrinter ('depager/srp.rb')
6
+ %%
7
+
8
+ %LEX{
9
+ /\s+/, /\#.*/ { }
10
+ /[1-9][0-9]*/ { yield _Token(:NUM, $&.to_i) }
11
+ /./ { yield _Token($&, $&) }
12
+ %}
13
+
14
+ #begin-rule
15
+ expr :
16
+ expr '+' term { val[0] + val[2] }
17
+ | expr '-' term { val[0] - val[2] }
18
+ | term { val[0] }
19
+ ;
20
+ term :
21
+ term '*' fact { val[0] * val[2] }
22
+ | term '/' fact { val[0] / val[2] }
23
+ | fact { val[0] }
24
+ ;
25
+ fact :
26
+ NUM { val[0].value }
27
+ | '(' expr ')' { val[1] }
28
+ ;
29
+ #end-rule
30
+ %%
31
+ parser = TinyCalc::createDecoratedParser
32
+ r, = parser.yyparse(STDIN)
33
+ puts r
@@ -0,0 +1,54 @@
1
+ %class TinyCalc
2
+ %extend Lexer ('depager/lex.rb')
3
+ %extend ASTBuilderDepthFirst ('depager/astdf.rb')
4
+ %decorate @ASTBuilderDepthFirst
5
+ #%decorate ShiftReducePrinter ('depager/srp.rb')
6
+ %%
7
+
8
+ %LEX{
9
+ /\s+/, /\#.*/ { }
10
+ /[1-9][0-9]*/ { yield _Token(:NUM, $&.to_i) }
11
+ /./ { yield _Token($&, $&) }
12
+ %}
13
+
14
+ %AST{
15
+ Node [value] { @value = nil }
16
+ Visitor { }
17
+ add(left, right) { ~value = ~left.value + ~right.value }
18
+ sub(left, right) { ~value = ~left.value - ~right.value }
19
+ mul(left, right) { ~value = ~left.value * ~right.value }
20
+ div(left, right) { ~value = ~left.value / ~right.value }
21
+ literal(-n) { ~value = ~n.value }
22
+ %}
23
+
24
+ #begin-rule
25
+ expr :
26
+ expr '+' term
27
+ => add(expr, term)
28
+ | expr '-' term
29
+ => sub(expr, term)
30
+ | term
31
+ => term
32
+ ;
33
+ term :
34
+ term '*' fact
35
+ => mul(term, fact)
36
+ | term '/' fact
37
+ => div(term, fact)
38
+ | fact
39
+ => fact
40
+ ;
41
+ fact :
42
+ NUM
43
+ => literal(NUM)
44
+ | '(' expr ')'
45
+ => expr
46
+ ;
47
+ #end-rule
48
+ %%
49
+ require 'pp'
50
+ parser = createDecoratedTinyCalc()
51
+ t, = parser.yyparse(STDIN)
52
+ v = Visitor.new
53
+ pp t.accept(v).value
54
+ pp t