depager 0.1.9

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