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.
- data/ChangeLog +4 -0
- data/Manifest.txt +52 -0
- data/README.en +64 -0
- data/README.ja +128 -0
- data/bin/depager +47 -0
- data/data/depager/misc/depager-mode.el +209 -0
- data/data/depager/sample/extension/paction.dr +15 -0
- data/data/depager/sample/extension/pactiontest.dr +14 -0
- data/data/depager/sample/pl0d/pl0ds.dr +334 -0
- data/data/depager/sample/pl0d/pl0test.pl0 +34 -0
- data/data/depager/sample/sample_calc/calc.action.dr +33 -0
- data/data/depager/sample/sample_calc/calc.astdf.dr +54 -0
- data/data/depager/sample/sample_calc/calc.astl.action.dr +66 -0
- data/data/depager/sample/sample_calc/calc.astl.dr +55 -0
- data/data/depager/sample/sample_calc/calc.atree.dr +43 -0
- data/data/depager/sample/sample_calc/calc.cst.dr +45 -0
- data/data/depager/sample/sample_calc/calc.dr +43 -0
- data/data/depager/sample/sample_calc/calc.lex.dr +29 -0
- data/data/depager/sample/sample_calc/calc.nvaction.dr +33 -0
- data/data/depager/sample/sample_calc/calc_prec.nvaction.dr +31 -0
- data/data/depager/sample/slex_test/slextest1.dr +37 -0
- data/data/depager/sample/slex_test/slextest2.dr +33 -0
- data/lib/depager.rb +608 -0
- data/lib/depager/Rakefile +30 -0
- data/lib/depager/action.rb +47 -0
- data/lib/depager/ast_base.dr +232 -0
- data/lib/depager/ast_base.rb +1249 -0
- data/lib/depager/astdf.rb +10 -0
- data/lib/depager/astl.rb +14 -0
- data/lib/depager/atree.dr +55 -0
- data/lib/depager/atree.rb +336 -0
- data/lib/depager/cst.dr +182 -0
- data/lib/depager/cst.rb +625 -0
- data/lib/depager/lex.dr +76 -0
- data/lib/depager/lex.rb +306 -0
- data/lib/depager/lr.rb +604 -0
- data/lib/depager/nvaction.rb +21 -0
- data/lib/depager/parse_action.rb +24 -0
- data/lib/depager/parser.rb +248 -0
- data/lib/depager/psrtmpl.rb +33 -0
- data/lib/depager/slex.dr +161 -0
- data/lib/depager/slex.rb +646 -0
- data/lib/depager/srp.rb +50 -0
- data/lib/depager/template/astdf.erbs +57 -0
- data/lib/depager/template/astl.erbs +57 -0
- data/lib/depager/template/extension_lalr_master.erb +51 -0
- data/lib/depager/template/extension_lalr_slave.erb +107 -0
- data/lib/depager/template/simple.erb +21 -0
- data/lib/depager/template/single_lalr_parser.erb +97 -0
- data/lib/depager/utils.rb +355 -0
- data/lib/depager/version.rb +9 -0
- data/setup.rb +1585 -0
- metadata +103 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'depager/ast_base.rb'
|
2
|
+
class ASTBuilderDepthFirstExtension < ASTBuilderBaseExtension #:nodoc:all
|
3
|
+
def modify_action_code code, nodes=[]
|
4
|
+
code.gsub(/~([a-z_])/, 'node.\1')
|
5
|
+
end
|
6
|
+
def gen_accept_code sym
|
7
|
+
" @#{sym}.accept(v)\n"
|
8
|
+
end
|
9
|
+
Template = CodeUtils::make_tmpl("#{Depager::Tmpldir}/astdf.erbs")
|
10
|
+
end
|
data/lib/depager/astl.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'depager/ast_base.rb'
|
2
|
+
class ASTBuilderLazyExtension < ASTBuilderBaseExtension #:nodoc:all
|
3
|
+
def modify_action_code code, nodes=[]
|
4
|
+
code.gsub(/~([a-z_])/, 'node.\1')
|
5
|
+
end
|
6
|
+
def gen_accept_code sym
|
7
|
+
%{
|
8
|
+
def _#{sym}_ v
|
9
|
+
@#{sym}.accept(v); @#{sym}
|
10
|
+
end
|
11
|
+
}; #code
|
12
|
+
end
|
13
|
+
Template = CodeUtils::make_tmpl("#{Depager::Tmpldir}/astl.erbs")
|
14
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
%defext ATreeBuilderExtension
|
2
|
+
%extend NVAction ('depager/nvaction.rb')
|
3
|
+
%extend Lexer ('depager/lex.rb')
|
4
|
+
%decorate @NVAction
|
5
|
+
#%decorate ShiftReducePrinter ('depager/srp.rb')
|
6
|
+
%inner{
|
7
|
+
attr_accessor :optouter, :on_reduce
|
8
|
+
def init_parser
|
9
|
+
@optouter = []
|
10
|
+
@on_reduce = []
|
11
|
+
end
|
12
|
+
def postRuleList
|
13
|
+
g_parser.optouter <<
|
14
|
+
gen_action_decorator_code(target_name, paramkey,
|
15
|
+
@on_reduce, @optouter)
|
16
|
+
end
|
17
|
+
%}
|
18
|
+
%hook postrhs
|
19
|
+
%banner '=>...'
|
20
|
+
%%
|
21
|
+
%LEX{
|
22
|
+
/[ \t]+/ { }
|
23
|
+
/\n/ { yield nil, nil }
|
24
|
+
/[a-zA-Z][a-zA-Z0-9_]*/ { yield :ID, Token[$&, lineno] }
|
25
|
+
/'(.+)'/ { yield :STR, Token[$1, lineno] }
|
26
|
+
/::/ { yield :CC, Token[$&, lineno] }
|
27
|
+
/=>/ { yield :EG, Token[$&, lineno] }
|
28
|
+
/./ { yield $&, Token[$&, lineno] }
|
29
|
+
%}
|
30
|
+
|
31
|
+
#begin-rule
|
32
|
+
start:
|
33
|
+
EG ast
|
34
|
+
{
|
35
|
+
n = master.nrules
|
36
|
+
master.optouter <<
|
37
|
+
master.gen_defm_code("_atree_#{n} val", _ast, _EG.lineno)
|
38
|
+
master.on_reduce[n] = ":_atree_#{n}"
|
39
|
+
}
|
40
|
+
;
|
41
|
+
ast:
|
42
|
+
ID '(' ')' { "[:#{_ID.value}]" }
|
43
|
+
| ID '(' fact_list ')' { "[:#{_ID.value}, #{_fact_list.join(',')}]" }
|
44
|
+
| ID { "val[#{g_parser.name_to_rhs_index(_ID.value)}]" }
|
45
|
+
;
|
46
|
+
fact_list:
|
47
|
+
fact { [ _fact ] }
|
48
|
+
| fact_list ',' fact { _fact_list.push _fact }
|
49
|
+
;
|
50
|
+
fact:
|
51
|
+
ID { "val[#{g_parser.name_to_rhs_index(_ID.value)}]" }
|
52
|
+
| STR { "'#{_STR.value}'" }
|
53
|
+
;
|
54
|
+
#end-rule
|
55
|
+
%%
|
@@ -0,0 +1,336 @@
|
|
1
|
+
|
2
|
+
###
|
3
|
+
### ATreeBuilderExtension - Depager Extension (master)
|
4
|
+
###
|
5
|
+
require 'pp.rb'
|
6
|
+
require 'depager/parser.rb'
|
7
|
+
|
8
|
+
|
9
|
+
module D4ATreeBuilderExtension #:nodoc:all
|
10
|
+
end
|
11
|
+
|
12
|
+
class ATreeBuilderExtension #:nodoc:all
|
13
|
+
include Depager::ExtensionUtils
|
14
|
+
|
15
|
+
attr_accessor :h2p
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@master = self
|
19
|
+
@hook = []
|
20
|
+
@h2p = {}
|
21
|
+
init_parser
|
22
|
+
end
|
23
|
+
|
24
|
+
def __regext__ p
|
25
|
+
super p, :default, nil
|
26
|
+
|
27
|
+
@hook[0] = ATreeBuilderExtension_postrhs.new(p, @nparam, self)
|
28
|
+
@h2p['postrhs'] = @hook[0]
|
29
|
+
p.postrhs.push [@hook[0], :do_parse]
|
30
|
+
|
31
|
+
regext p
|
32
|
+
end
|
33
|
+
|
34
|
+
### Inner Code
|
35
|
+
attr_accessor :optouter, :on_reduce
|
36
|
+
def init_parser
|
37
|
+
@optouter = []
|
38
|
+
@on_reduce = []
|
39
|
+
end
|
40
|
+
def postRuleList
|
41
|
+
g_parser.optouter <<
|
42
|
+
gen_action_decorator_code(target_name, paramkey,
|
43
|
+
@on_reduce, @optouter)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
### Outer Code
|
49
|
+
|
50
|
+
###
|
51
|
+
### ATreeBuilderExtension_postrhs - Part of Depager Extension (slave)
|
52
|
+
###
|
53
|
+
module D4ATreeBuilderExtension_postrhs #:nodoc:all
|
54
|
+
end
|
55
|
+
|
56
|
+
class ATreeBuilderExtension_postrhs < Basis #:nodoc:all
|
57
|
+
include Depager::ExtensionUtils
|
58
|
+
|
59
|
+
|
60
|
+
### Reduce Table
|
61
|
+
reduce_table = [
|
62
|
+
[ -1, 1 ],
|
63
|
+
[ 0, 2 ],
|
64
|
+
[ 1, 3 ],
|
65
|
+
[ 1, 4 ],
|
66
|
+
[ 1, 1 ],
|
67
|
+
[ 2, 1 ],
|
68
|
+
[ 2, 3 ],
|
69
|
+
[ 3, 1 ],
|
70
|
+
[ 3, 1 ],
|
71
|
+
]
|
72
|
+
### Extension Params
|
73
|
+
nparams = {
|
74
|
+
'NVAction' => 2,
|
75
|
+
}
|
76
|
+
### Term to Int
|
77
|
+
t2i = {
|
78
|
+
nil => 0,
|
79
|
+
false => 1,
|
80
|
+
:EG => 2,
|
81
|
+
:ID => 3,
|
82
|
+
"(" => 4,
|
83
|
+
")" => 5,
|
84
|
+
"," => 6,
|
85
|
+
:STR => 7,
|
86
|
+
}
|
87
|
+
### Int to Term
|
88
|
+
i2t = [
|
89
|
+
nil,
|
90
|
+
false,
|
91
|
+
:EG,
|
92
|
+
:ID,
|
93
|
+
"(",
|
94
|
+
")",
|
95
|
+
",",
|
96
|
+
:STR,
|
97
|
+
]
|
98
|
+
### Action Table
|
99
|
+
action_table = [
|
100
|
+
[ nil, nil, 2, nil, nil, nil, nil, nil, ],
|
101
|
+
[ ACC, nil, nil, nil, nil, nil, nil, nil, ],
|
102
|
+
[ nil, nil, nil, 4, nil, nil, nil, nil, ],
|
103
|
+
[ nil, nil, nil, nil, nil, nil, nil, nil, ],
|
104
|
+
[ nil, nil, nil, nil, 5, nil, nil, nil, ],
|
105
|
+
[ nil, nil, nil, 7, nil, 10, nil, 6, ],
|
106
|
+
[ nil, nil, nil, nil, nil, nil, nil, nil, ],
|
107
|
+
[ nil, nil, nil, nil, nil, nil, nil, nil, ],
|
108
|
+
[ nil, nil, nil, nil, nil, 12, 11, nil, ],
|
109
|
+
[ nil, nil, nil, nil, nil, nil, nil, nil, ],
|
110
|
+
[ nil, nil, nil, nil, nil, nil, nil, nil, ],
|
111
|
+
[ nil, nil, nil, 7, nil, nil, nil, 6, ],
|
112
|
+
[ nil, nil, nil, nil, nil, nil, nil, nil, ],
|
113
|
+
[ nil, nil, nil, nil, nil, nil, nil, nil, ],
|
114
|
+
]
|
115
|
+
### Default Reduce Table
|
116
|
+
defred_table = [
|
117
|
+
nil,
|
118
|
+
nil,
|
119
|
+
nil,
|
120
|
+
-1,
|
121
|
+
-4,
|
122
|
+
nil,
|
123
|
+
-8,
|
124
|
+
-7,
|
125
|
+
nil,
|
126
|
+
-5,
|
127
|
+
-2,
|
128
|
+
nil,
|
129
|
+
-3,
|
130
|
+
-6,
|
131
|
+
]
|
132
|
+
defred_after_shift_table = [
|
133
|
+
nil,
|
134
|
+
nil,
|
135
|
+
nil,
|
136
|
+
-1,
|
137
|
+
nil,
|
138
|
+
nil,
|
139
|
+
-8,
|
140
|
+
-7,
|
141
|
+
nil,
|
142
|
+
-5,
|
143
|
+
-2,
|
144
|
+
nil,
|
145
|
+
-3,
|
146
|
+
-6,
|
147
|
+
]
|
148
|
+
### Nonterm to Int
|
149
|
+
nt2i = {
|
150
|
+
:start => 0,
|
151
|
+
:ast => 1,
|
152
|
+
:fact_list => 2,
|
153
|
+
:fact => 3,
|
154
|
+
}
|
155
|
+
### Int to Nonterm
|
156
|
+
i2nt = [
|
157
|
+
:start,
|
158
|
+
:ast,
|
159
|
+
:fact_list,
|
160
|
+
:fact,
|
161
|
+
]
|
162
|
+
### Goto Table
|
163
|
+
goto_table = [
|
164
|
+
[ 1, nil, nil, nil, ],
|
165
|
+
[ nil, nil, nil, nil, ],
|
166
|
+
[ nil, 3, nil, nil, ],
|
167
|
+
[ nil, nil, nil, nil, ],
|
168
|
+
[ nil, nil, nil, nil, ],
|
169
|
+
[ nil, nil, 8, 9, ],
|
170
|
+
[ nil, nil, nil, nil, ],
|
171
|
+
[ nil, nil, nil, nil, ],
|
172
|
+
[ nil, nil, nil, nil, ],
|
173
|
+
[ nil, nil, nil, nil, ],
|
174
|
+
[ nil, nil, nil, nil, ],
|
175
|
+
[ nil, nil, nil, 13, ],
|
176
|
+
[ nil, nil, nil, nil, ],
|
177
|
+
[ nil, nil, nil, nil, ],
|
178
|
+
]
|
179
|
+
|
180
|
+
Tables = [ reduce_table, nparams, action_table,
|
181
|
+
defred_table, defred_after_shift_table, goto_table,
|
182
|
+
t2i, i2t, nt2i, i2nt ]
|
183
|
+
|
184
|
+
attr_accessor :p, :m
|
185
|
+
def initialize p, nparam, master = nil
|
186
|
+
super()
|
187
|
+
@g_parser = @p = p
|
188
|
+
@master = @m = master
|
189
|
+
@nparam = nparam
|
190
|
+
@dect = D4ATreeBuilderExtension_postrhs::NVAction.new(self)
|
191
|
+
init_parser
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
|
196
|
+
def banner
|
197
|
+
"=>... / #{@master.class.name}"
|
198
|
+
end
|
199
|
+
|
200
|
+
### Inner Code
|
201
|
+
|
202
|
+
def lex
|
203
|
+
begin
|
204
|
+
until @line.empty? do
|
205
|
+
case @line
|
206
|
+
when /\A[ \t]+/
|
207
|
+
|
208
|
+
when /\A\n/
|
209
|
+
yield nil, nil
|
210
|
+
when /\A[a-zA-Z][a-zA-Z0-9_]*/
|
211
|
+
yield :ID, Token[$&, lineno]
|
212
|
+
when /\A'(.+)'/
|
213
|
+
yield :STR, Token[$1, lineno]
|
214
|
+
when /\A::/
|
215
|
+
yield :CC, Token[$&, lineno]
|
216
|
+
when /\A=>/
|
217
|
+
yield :EG, Token[$&, lineno]
|
218
|
+
when /\A./
|
219
|
+
yield $&, Token[$&, lineno]
|
220
|
+
|
221
|
+
else
|
222
|
+
raise RuntimeError, "must not happen #{@line}"
|
223
|
+
end
|
224
|
+
@oldline = @line
|
225
|
+
@line = $'
|
226
|
+
end
|
227
|
+
end while @line = getline
|
228
|
+
yield nil, nil
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
### Outer Code
|
234
|
+
|
235
|
+
class D4ATreeBuilderExtension_postrhs::NVAction < Depager::Action #:nodoc:all
|
236
|
+
include Depager::DecoratorUtils
|
237
|
+
|
238
|
+
on_reduce = [
|
239
|
+
nil,
|
240
|
+
:_act_0,
|
241
|
+
:_act_1,
|
242
|
+
:_act_2,
|
243
|
+
:_act_3,
|
244
|
+
:_act_4,
|
245
|
+
:_act_5,
|
246
|
+
:_act_6,
|
247
|
+
:_act_7,
|
248
|
+
|
249
|
+
]
|
250
|
+
Tables = [on_reduce]
|
251
|
+
def initialize inside
|
252
|
+
super inside, 'NVAction'
|
253
|
+
@on_reduce, = self.class::Tables
|
254
|
+
init_parser
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
module_eval <<-'.,.,118028145923483.,.,', 'atree.dr', 32
|
259
|
+
def _act_0 val
|
260
|
+
_EG, _ast = *val
|
261
|
+
|
262
|
+
n = master.nrules
|
263
|
+
master.optouter <<
|
264
|
+
master.gen_defm_code("_atree_#{n} val", _ast, _EG.lineno)
|
265
|
+
master.on_reduce[n] = ":_atree_#{n}"
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
.,.,118028145923483.,.,
|
270
|
+
|
271
|
+
module_eval <<-'.,.,11802814596513.,.,', 'atree.dr', 40
|
272
|
+
def _act_1 val
|
273
|
+
_ID, _, _ = *val
|
274
|
+
"[:#{_ID.value}]"
|
275
|
+
|
276
|
+
end
|
277
|
+
|
278
|
+
.,.,11802814596513.,.,
|
279
|
+
|
280
|
+
module_eval <<-'.,.,1180281459631.,.,', 'atree.dr', 41
|
281
|
+
def _act_2 val
|
282
|
+
_ID, _, _fact_list, _ = *val
|
283
|
+
"[:#{_ID.value}, #{_fact_list.join(',')}]"
|
284
|
+
|
285
|
+
end
|
286
|
+
|
287
|
+
.,.,1180281459631.,.,
|
288
|
+
|
289
|
+
module_eval <<-'.,.,11802814596304.,.,', 'atree.dr', 42
|
290
|
+
def _act_3 val
|
291
|
+
_ID = *val
|
292
|
+
"val[#{g_parser.name_to_rhs_index(_ID.value)}]"
|
293
|
+
|
294
|
+
end
|
295
|
+
|
296
|
+
.,.,11802814596304.,.,
|
297
|
+
|
298
|
+
module_eval <<-'.,.,11802814593265.,.,', 'atree.dr', 45
|
299
|
+
def _act_4 val
|
300
|
+
_fact = *val
|
301
|
+
[ _fact ]
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
.,.,11802814593265.,.,
|
306
|
+
|
307
|
+
module_eval <<-'.,.,11802814599160.,.,', 'atree.dr', 46
|
308
|
+
def _act_5 val
|
309
|
+
_fact_list, _, _fact = *val
|
310
|
+
_fact_list.push _fact
|
311
|
+
|
312
|
+
end
|
313
|
+
|
314
|
+
.,.,11802814599160.,.,
|
315
|
+
|
316
|
+
module_eval <<-'.,.,11802814594299.,.,', 'atree.dr', 49
|
317
|
+
def _act_6 val
|
318
|
+
_ID = *val
|
319
|
+
"val[#{g_parser.name_to_rhs_index(_ID.value)}]"
|
320
|
+
|
321
|
+
end
|
322
|
+
|
323
|
+
.,.,11802814594299.,.,
|
324
|
+
|
325
|
+
module_eval <<-'.,.,118028145927897.,.,', 'atree.dr', 50
|
326
|
+
def _act_7 val
|
327
|
+
_STR = *val
|
328
|
+
"'#{_STR.value}'"
|
329
|
+
|
330
|
+
end
|
331
|
+
|
332
|
+
.,.,118028145927897.,.,
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
|
data/lib/depager/cst.dr
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
%defext CSTBuilderExtension
|
2
|
+
%extend Lexer ('depager/lex.rb')
|
3
|
+
%extend NVAction ('depager/nvaction.rb')
|
4
|
+
%decorate @NVAction
|
5
|
+
#%decorate ShiftReducePrinter ('depager/srp.rb')
|
6
|
+
%mixin ActionParser ('depager/parse_action')
|
7
|
+
%inner{
|
8
|
+
attr_accessor :optouter, :nodes_code
|
9
|
+
def init_parser
|
10
|
+
super
|
11
|
+
@n = 0
|
12
|
+
@visitor_code = []
|
13
|
+
@nodes_code = []
|
14
|
+
@optouter = []
|
15
|
+
@on_reduce = []
|
16
|
+
end
|
17
|
+
def modify_action_code code
|
18
|
+
code.gsub(/~([a-z_])/, 'node.\1')
|
19
|
+
end
|
20
|
+
def postRhs
|
21
|
+
code = ''
|
22
|
+
lineno = g_parser.lineno
|
23
|
+
if token[0] == '{'
|
24
|
+
@line0, @line = g_parser.line0, g_parser.oldline
|
25
|
+
code = parse_action
|
26
|
+
|
27
|
+
fixline @line
|
28
|
+
gettoken
|
29
|
+
end
|
30
|
+
|
31
|
+
node_name = "#{lhs_name}_#{nrhs}"
|
32
|
+
accept = ""
|
33
|
+
nodes = g_parser.rhs.map do |i|
|
34
|
+
x = g_parser.int_to_sym(i)
|
35
|
+
if x.class == String
|
36
|
+
"tx#{x[0].to_s(16)}"
|
37
|
+
else
|
38
|
+
x = x.to_s
|
39
|
+
accept << "#{x}.accept(v); " if x =~ /\A[a-z_]+\Z/
|
40
|
+
x.downcase
|
41
|
+
end
|
42
|
+
end
|
43
|
+
attrc = nodes.map{|i| ":#{i}" }.join(', ')
|
44
|
+
inic = nodes.map{|i| "@#{i} = #{i}"}.join('; ')
|
45
|
+
@nodes_code << %{
|
46
|
+
class Node_#{node_name} < Node_#{lhs_name}
|
47
|
+
attr_accessor #{attrc}
|
48
|
+
def initialize #{nodes.join(', ')}
|
49
|
+
super()
|
50
|
+
#{inic}
|
51
|
+
end
|
52
|
+
def accept v
|
53
|
+
#{accept}
|
54
|
+
v.visit_Node_#{node_name}(self)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
}; #code
|
58
|
+
|
59
|
+
@visitor_code <<
|
60
|
+
gen_defm_code("visit_Node_#{node_name} node",
|
61
|
+
modify_action_code(code), lineno)
|
62
|
+
|
63
|
+
args = nodes.inject([]){|r, i| r << "val[#{r.size}]"}
|
64
|
+
code = "Node_#{node_name}.new(#{args.join(', ')})"
|
65
|
+
@optouter <<
|
66
|
+
gen_defm_code("_cst_#{nrules} val", code, lineno)
|
67
|
+
|
68
|
+
@on_reduce[nrules] = ":_cst_#{nrules}"
|
69
|
+
end
|
70
|
+
def postRuleList
|
71
|
+
code = unindent %{
|
72
|
+
class Node
|
73
|
+
def accept
|
74
|
+
end
|
75
|
+
end
|
76
|
+
}; #code
|
77
|
+
g_parser.optouter << code
|
78
|
+
|
79
|
+
code = unindent %{
|
80
|
+
class Visitor
|
81
|
+
$$!!@ CST @!!$$
|
82
|
+
end
|
83
|
+
}; #code
|
84
|
+
g_parser.optouter <<
|
85
|
+
code.sub!('$$!!@ CST @!!$$', @visitor_code.to_s) <<
|
86
|
+
unindent(@nodes_code) <<
|
87
|
+
gen_action_decorator_code(target_name, paramkey,
|
88
|
+
@on_reduce, @optouter)
|
89
|
+
end
|
90
|
+
%}
|
91
|
+
%hook prerulelist /%CST\{\s*\Z/ skip
|
92
|
+
%banner '%CST{ ... }'
|
93
|
+
%mixin ActionParser ('depager/parse_action')
|
94
|
+
%%
|
95
|
+
|
96
|
+
%LEX{
|
97
|
+
/\s+/, /#.*/ { }
|
98
|
+
/%\}\s*\Z/ { @line = $'; yield nil,nil }
|
99
|
+
'Node' { yield _Token(:NODE, $&) }
|
100
|
+
/\{/ { ln = lineno; yield _Token(:ACTION, parse_action, ln); //=~'' }
|
101
|
+
%}
|
102
|
+
|
103
|
+
#begin-rule
|
104
|
+
start:
|
105
|
+
opt_node opt_visitor
|
106
|
+
{
|
107
|
+
code = %{
|
108
|
+
class Node
|
109
|
+
$$!!@ NODE @!!$$
|
110
|
+
end
|
111
|
+
class Visitor
|
112
|
+
$$!!@ VISITOR @!!$$
|
113
|
+
end
|
114
|
+
}; #code
|
115
|
+
master.nodes_code <<
|
116
|
+
code.sub!('$$!!@ NODE @!!$$', _opt_node) \
|
117
|
+
.sub!('$$!!@ VISITOR @!!$$', _opt_visitor)
|
118
|
+
}
|
119
|
+
;
|
120
|
+
opt_node: { '' }
|
121
|
+
| NODE ACTION { _ACTION.value }
|
122
|
+
;
|
123
|
+
opt_visitor: { warn "VIS";'' }
|
124
|
+
| VISITOR ACTION { _ACTION.value }
|
125
|
+
;
|
126
|
+
#end-rule
|
127
|
+
%%
|
128
|
+
%hook postlhs /\[/ skip
|
129
|
+
%banner '[ ... ]'
|
130
|
+
%inner{
|
131
|
+
def do_default
|
132
|
+
master.nodes_code << %{
|
133
|
+
class Node_#{master.lhs_name} < Node
|
134
|
+
def initialize
|
135
|
+
super()
|
136
|
+
end
|
137
|
+
end
|
138
|
+
}; #code
|
139
|
+
end
|
140
|
+
%}
|
141
|
+
%%
|
142
|
+
|
143
|
+
%LEX{
|
144
|
+
/\A\s+/ { } #skip blank
|
145
|
+
/""/,/''/,/[0-9]+/,
|
146
|
+
/\{\s*\}/,/\[\s*\]/,
|
147
|
+
/nil/ { yield _Token(:LIT, $&) }
|
148
|
+
/\A[a-z][a-z_]*/ { yield _Token(:ID, $&) }
|
149
|
+
/\A(.)/ { yield _Token($&, $&) }
|
150
|
+
%}
|
151
|
+
|
152
|
+
#begin-rule
|
153
|
+
start:
|
154
|
+
'[' pair ']'
|
155
|
+
{
|
156
|
+
args = []; code = ''
|
157
|
+
_pair.each do |id, lit|
|
158
|
+
args << id
|
159
|
+
code << "#{id} = #{lit}; " if lit
|
160
|
+
end
|
161
|
+
attrc = args.map{|i| ":#{i}"}.join(', ')
|
162
|
+
master.nodes_code << %{
|
163
|
+
class Node_#{master.lhs_name} < Node
|
164
|
+
attr_accessor #{attrc}
|
165
|
+
def initialize
|
166
|
+
super()
|
167
|
+
#{code}
|
168
|
+
end
|
169
|
+
end
|
170
|
+
}; #code
|
171
|
+
}
|
172
|
+
;
|
173
|
+
pair:
|
174
|
+
expr { [ _expr ] }
|
175
|
+
| pair ',' expr { _pair << _expr }
|
176
|
+
;
|
177
|
+
expr:
|
178
|
+
ID { [ _ID.value, nil] }
|
179
|
+
| ID '=' LIT { [ _ID.value, _LIT.value ] }
|
180
|
+
;
|
181
|
+
#end-rule
|
182
|
+
%%
|