racc 1.4.6
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/.gitattributes +2 -0
- data/.gitignore +7 -0
- data/COPYING +515 -0
- data/ChangeLog +846 -0
- data/DEPENDS +4 -0
- data/README.en.rdoc +86 -0
- data/README.ja.rdoc +96 -0
- data/Rakefile +15 -0
- data/TODO +5 -0
- data/bin/racc +308 -0
- data/bin/racc2y +195 -0
- data/bin/y2racc +339 -0
- data/doc/en/NEWS.en.rdoc +282 -0
- data/doc/en/command.en.html +78 -0
- data/doc/en/debug.en.rdoc +20 -0
- data/doc/en/grammar.en.rdoc +230 -0
- data/doc/en/index.en.html +10 -0
- data/doc/en/parser.en.rdoc +74 -0
- data/doc/en/usage.en.html +92 -0
- data/doc/ja/NEWS.ja.rdoc +307 -0
- data/doc/ja/command.ja.html +94 -0
- data/doc/ja/debug.ja.rdoc +36 -0
- data/doc/ja/grammar.ja.rdoc +348 -0
- data/doc/ja/index.ja.html +10 -0
- data/doc/ja/parser.ja.rdoc +125 -0
- data/doc/ja/usage.ja.html +414 -0
- data/ext/racc/cparse/MANIFEST +4 -0
- data/ext/racc/cparse/cparse.c +824 -0
- data/ext/racc/cparse/depend +1 -0
- data/ext/racc/cparse/extconf.rb +7 -0
- data/fastcache/extconf.rb +2 -0
- data/fastcache/fastcache.c +185 -0
- data/lib/racc.rb +6 -0
- data/lib/racc/compat.rb +40 -0
- data/lib/racc/debugflags.rb +59 -0
- data/lib/racc/exception.rb +15 -0
- data/lib/racc/grammar.rb +1115 -0
- data/lib/racc/grammarfileparser.rb +559 -0
- data/lib/racc/info.rb +16 -0
- data/lib/racc/iset.rb +91 -0
- data/lib/racc/logfilegenerator.rb +214 -0
- data/lib/racc/parser.rb +439 -0
- data/lib/racc/parserfilegenerator.rb +511 -0
- data/lib/racc/pre-setup +13 -0
- data/lib/racc/sourcetext.rb +34 -0
- data/lib/racc/state.rb +971 -0
- data/lib/racc/statetransitiontable.rb +316 -0
- data/lib/racc/static.rb +5 -0
- data/misc/dist.sh +31 -0
- data/sample/array.y +67 -0
- data/sample/array2.y +59 -0
- data/sample/calc-ja.y +66 -0
- data/sample/calc.y +65 -0
- data/sample/conflict.y +15 -0
- data/sample/hash.y +60 -0
- data/sample/lalr.y +17 -0
- data/sample/lists.y +57 -0
- data/sample/syntax.y +46 -0
- data/sample/yyerr.y +46 -0
- data/setup.rb +1587 -0
- data/tasks/doc.rb +12 -0
- data/tasks/email.rb +55 -0
- data/tasks/file.rb +37 -0
- data/tasks/gem.rb +37 -0
- data/tasks/test.rb +16 -0
- data/test/assets/chk.y +126 -0
- data/test/assets/conf.y +16 -0
- data/test/assets/digraph.y +29 -0
- data/test/assets/echk.y +118 -0
- data/test/assets/err.y +60 -0
- data/test/assets/expect.y +7 -0
- data/test/assets/firstline.y +4 -0
- data/test/assets/ichk.y +102 -0
- data/test/assets/intp.y +546 -0
- data/test/assets/mailp.y +437 -0
- data/test/assets/newsyn.y +25 -0
- data/test/assets/noend.y +4 -0
- data/test/assets/nonass.y +41 -0
- data/test/assets/normal.y +27 -0
- data/test/assets/norule.y +4 -0
- data/test/assets/nullbug1.y +25 -0
- data/test/assets/nullbug2.y +15 -0
- data/test/assets/opt.y +123 -0
- data/test/assets/percent.y +35 -0
- data/test/assets/recv.y +97 -0
- data/test/assets/rrconf.y +14 -0
- data/test/assets/scan.y +72 -0
- data/test/assets/syntax.y +50 -0
- data/test/assets/unterm.y +5 -0
- data/test/assets/useless.y +12 -0
- data/test/assets/yyerr.y +46 -0
- data/test/bench.y +36 -0
- data/test/helper.rb +88 -0
- data/test/infini.y +8 -0
- data/test/scandata/brace +7 -0
- data/test/scandata/gvar +1 -0
- data/test/scandata/normal +4 -0
- data/test/scandata/percent +18 -0
- data/test/scandata/slash +10 -0
- data/test/src.intp +34 -0
- data/test/start.y +20 -0
- data/test/test_chk_y.rb +51 -0
- data/test/test_grammar_file_parser.rb +15 -0
- data/test/test_racc_command.rb +155 -0
- data/test/test_scan_y.rb +51 -0
- data/test/testscanner.rb +51 -0
- data/web/racc.en.rhtml +42 -0
- data/web/racc.ja.rhtml +51 -0
- metadata +166 -0
data/test/assets/mailp.y
ADDED
@@ -0,0 +1,437 @@
|
|
1
|
+
#
|
2
|
+
# mailp for test
|
3
|
+
#
|
4
|
+
|
5
|
+
class Testp
|
6
|
+
|
7
|
+
rule
|
8
|
+
|
9
|
+
content : DateH datetime { @field.date = val[1] }
|
10
|
+
| RecvH received
|
11
|
+
| RetpathH returnpath
|
12
|
+
| MaddrH addrs { @field.addrs.replace val[1] }
|
13
|
+
| SaddrH addr { @field.addr = val[1] }
|
14
|
+
| MmboxH mboxes { @field.addrs.replace val[1] }
|
15
|
+
| SmboxH mbox { @field.addr = val[1] }
|
16
|
+
| MsgidH msgid { @field.msgid = val[1] }
|
17
|
+
| KeyH keys { @field.keys.replace val[1] }
|
18
|
+
| EncH enc
|
19
|
+
| VersionH version
|
20
|
+
| CTypeH ctype
|
21
|
+
| CEncodingH cencode
|
22
|
+
| CDispositionH cdisp
|
23
|
+
| Mbox mbox
|
24
|
+
{
|
25
|
+
mb = val[1]
|
26
|
+
@field.phrase = mb.phrase
|
27
|
+
@field.setroute mb.route
|
28
|
+
@field.local = mb.local
|
29
|
+
@field.domain = mb.domain
|
30
|
+
}
|
31
|
+
| Spec spec
|
32
|
+
{
|
33
|
+
mb = val[1]
|
34
|
+
@field.local = mb.local
|
35
|
+
@field.domain = mb.domain
|
36
|
+
}
|
37
|
+
;
|
38
|
+
|
39
|
+
datetime : day DIGIT ATOM DIGIT hour zone
|
40
|
+
# 0 1 2 3 4 5
|
41
|
+
# day month year
|
42
|
+
{
|
43
|
+
t = Time.gm( val[3].to_i, val[2], val[1].to_i, 0, 0, 0 )
|
44
|
+
result = (t + val[4] - val[5]).localtime
|
45
|
+
}
|
46
|
+
;
|
47
|
+
|
48
|
+
day : /* none */
|
49
|
+
| ATOM ','
|
50
|
+
;
|
51
|
+
|
52
|
+
hour : DIGIT ':' DIGIT
|
53
|
+
{
|
54
|
+
result = (result.to_i * 60 * 60) + (val[2].to_i * 60)
|
55
|
+
}
|
56
|
+
| DIGIT ':' DIGIT ':' DIGIT
|
57
|
+
{
|
58
|
+
result = (result.to_i * 60 * 60) +
|
59
|
+
(val[2].to_i * 60)
|
60
|
+
+ val[4].to_i
|
61
|
+
}
|
62
|
+
;
|
63
|
+
|
64
|
+
zone : ATOM
|
65
|
+
{
|
66
|
+
result = ::TMail.zonestr2i( val[0] ) * 60
|
67
|
+
}
|
68
|
+
;
|
69
|
+
|
70
|
+
received : from by via with id for recvdatetime
|
71
|
+
;
|
72
|
+
|
73
|
+
from : /* none */
|
74
|
+
| FROM domain
|
75
|
+
{
|
76
|
+
@field.from = Address.join( val[1] )
|
77
|
+
}
|
78
|
+
| FROM domain '@' domain
|
79
|
+
{
|
80
|
+
@field.from = Address.join( val[3] )
|
81
|
+
}
|
82
|
+
| FROM domain DOMLIT
|
83
|
+
{
|
84
|
+
@field.from = Address.join( val[1] )
|
85
|
+
}
|
86
|
+
;
|
87
|
+
|
88
|
+
by : /* none */
|
89
|
+
| BY domain
|
90
|
+
{
|
91
|
+
@field.by = Address.join( val[1] )
|
92
|
+
}
|
93
|
+
;
|
94
|
+
|
95
|
+
via : /* none */
|
96
|
+
| VIA ATOM
|
97
|
+
{
|
98
|
+
@field.via = val[1]
|
99
|
+
}
|
100
|
+
;
|
101
|
+
|
102
|
+
with : /* none */
|
103
|
+
| WITH ATOM
|
104
|
+
{
|
105
|
+
@field.with.push val[1]
|
106
|
+
}
|
107
|
+
;
|
108
|
+
|
109
|
+
id : /* none */
|
110
|
+
| ID msgid
|
111
|
+
{
|
112
|
+
@field.msgid = val[1]
|
113
|
+
}
|
114
|
+
| ID ATOM
|
115
|
+
{
|
116
|
+
@field.msgid = val[1]
|
117
|
+
}
|
118
|
+
;
|
119
|
+
|
120
|
+
for : /* none */
|
121
|
+
| FOR addr
|
122
|
+
{
|
123
|
+
@field.for_ = val[1].address
|
124
|
+
}
|
125
|
+
;
|
126
|
+
|
127
|
+
recvdatetime
|
128
|
+
: /* none */
|
129
|
+
| ';' datetime
|
130
|
+
{
|
131
|
+
@field.date = val[1]
|
132
|
+
}
|
133
|
+
;
|
134
|
+
|
135
|
+
returnpath: '<' '>'
|
136
|
+
| routeaddr
|
137
|
+
{
|
138
|
+
@field.route.replace result.route
|
139
|
+
@field.addr = result.addr
|
140
|
+
}
|
141
|
+
;
|
142
|
+
|
143
|
+
addrs : addr { result = val }
|
144
|
+
| addrs ',' addr { result.push val[2] }
|
145
|
+
;
|
146
|
+
|
147
|
+
addr : mbox
|
148
|
+
| group
|
149
|
+
;
|
150
|
+
|
151
|
+
mboxes : mbox
|
152
|
+
{
|
153
|
+
result = val
|
154
|
+
}
|
155
|
+
| mboxes ',' mbox
|
156
|
+
{
|
157
|
+
result.push val[2]
|
158
|
+
}
|
159
|
+
;
|
160
|
+
|
161
|
+
mbox : spec
|
162
|
+
| routeaddr
|
163
|
+
| phrase routeaddr
|
164
|
+
{
|
165
|
+
val[1].phrase = HFdecoder.decode( result )
|
166
|
+
result = val[1]
|
167
|
+
}
|
168
|
+
;
|
169
|
+
|
170
|
+
group : phrase ':' mboxes ';'
|
171
|
+
{
|
172
|
+
result = AddressGroup.new( result, val[2] )
|
173
|
+
}
|
174
|
+
# | phrase ':' ';' { result = AddressGroup.new( result ) }
|
175
|
+
;
|
176
|
+
|
177
|
+
routeaddr : '<' route spec '>'
|
178
|
+
{
|
179
|
+
result = val[2]
|
180
|
+
result.route = val[1]
|
181
|
+
}
|
182
|
+
| '<' spec '>'
|
183
|
+
{
|
184
|
+
result = val[1]
|
185
|
+
}
|
186
|
+
;
|
187
|
+
|
188
|
+
route : at_domains ':'
|
189
|
+
;
|
190
|
+
|
191
|
+
at_domains: '@' domain { result = [ val[1] ] }
|
192
|
+
| at_domains ',' '@' domain { result.push val[3] }
|
193
|
+
;
|
194
|
+
|
195
|
+
spec : local '@' domain { result = Address.new( val[0], val[2] ) }
|
196
|
+
| local { result = Address.new( result, nil ) }
|
197
|
+
;
|
198
|
+
|
199
|
+
local : word { result = val }
|
200
|
+
| local '.' word { result.push val[2] }
|
201
|
+
;
|
202
|
+
|
203
|
+
domain : domword { result = val }
|
204
|
+
| domain '.' domword { result.push val[2] }
|
205
|
+
;
|
206
|
+
|
207
|
+
domword : atom
|
208
|
+
| DOMLIT
|
209
|
+
| DIGIT
|
210
|
+
;
|
211
|
+
|
212
|
+
msgid : '<' spec '>'
|
213
|
+
{
|
214
|
+
val[1] = val[1].addr
|
215
|
+
result = val.join('')
|
216
|
+
}
|
217
|
+
;
|
218
|
+
|
219
|
+
phrase : word
|
220
|
+
| phrase word { result << ' ' << val[1] }
|
221
|
+
;
|
222
|
+
|
223
|
+
word : atom
|
224
|
+
| QUOTED
|
225
|
+
| DIGIT
|
226
|
+
;
|
227
|
+
|
228
|
+
keys : phrase
|
229
|
+
| keys ',' phrase
|
230
|
+
;
|
231
|
+
|
232
|
+
enc : word
|
233
|
+
{
|
234
|
+
@field.encrypter = val[0]
|
235
|
+
}
|
236
|
+
| word word
|
237
|
+
{
|
238
|
+
@field.encrypter = val[0]
|
239
|
+
@field.keyword = val[1]
|
240
|
+
}
|
241
|
+
;
|
242
|
+
|
243
|
+
version : DIGIT '.' DIGIT
|
244
|
+
{
|
245
|
+
@field.major = val[0].to_i
|
246
|
+
@field.minor = val[2].to_i
|
247
|
+
}
|
248
|
+
;
|
249
|
+
|
250
|
+
ctype : TOKEN '/' TOKEN params
|
251
|
+
{
|
252
|
+
@field.main = val[0]
|
253
|
+
@field.sub = val[2]
|
254
|
+
}
|
255
|
+
| TOKEN params
|
256
|
+
{
|
257
|
+
@field.main = val[0]
|
258
|
+
@field.sub = ''
|
259
|
+
}
|
260
|
+
;
|
261
|
+
|
262
|
+
params : /* none */
|
263
|
+
| params ';' TOKEN '=' value
|
264
|
+
{
|
265
|
+
@field.params[ val[2].downcase ] = val[4]
|
266
|
+
}
|
267
|
+
;
|
268
|
+
|
269
|
+
value : TOKEN
|
270
|
+
| QUOTED
|
271
|
+
;
|
272
|
+
|
273
|
+
cencode : TOKEN
|
274
|
+
{
|
275
|
+
@field.encoding = val[0]
|
276
|
+
}
|
277
|
+
;
|
278
|
+
|
279
|
+
cdisp : TOKEN disp_params
|
280
|
+
{
|
281
|
+
@field.disposition = val[0]
|
282
|
+
}
|
283
|
+
;
|
284
|
+
|
285
|
+
disp_params
|
286
|
+
: /* none */
|
287
|
+
| disp_params ';' disp_param
|
288
|
+
;
|
289
|
+
|
290
|
+
disp_param: /* none */
|
291
|
+
| TOKEN '=' value
|
292
|
+
{
|
293
|
+
@field.params[ val[0].downcase ] = val[2]
|
294
|
+
}
|
295
|
+
;
|
296
|
+
|
297
|
+
atom : ATOM
|
298
|
+
| FROM
|
299
|
+
| BY
|
300
|
+
| VIA
|
301
|
+
| WITH
|
302
|
+
| ID
|
303
|
+
| FOR
|
304
|
+
;
|
305
|
+
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
---- header
|
310
|
+
#
|
311
|
+
# mailp for test
|
312
|
+
#
|
313
|
+
|
314
|
+
require 'tmail/mails'
|
315
|
+
|
316
|
+
|
317
|
+
module TMail
|
318
|
+
|
319
|
+
---- inner
|
320
|
+
|
321
|
+
MAILP_DEBUG = false
|
322
|
+
|
323
|
+
def initialize
|
324
|
+
self.debug = MAILP_DEBUG
|
325
|
+
end
|
326
|
+
|
327
|
+
def debug=( flag )
|
328
|
+
@yydebug = flag && Racc_debug_parser
|
329
|
+
@scanner_debug = flag
|
330
|
+
end
|
331
|
+
|
332
|
+
def debug
|
333
|
+
@yydebug
|
334
|
+
end
|
335
|
+
|
336
|
+
|
337
|
+
def Mailp.parse( str, obj, ident )
|
338
|
+
new.parse( str, obj, ident )
|
339
|
+
end
|
340
|
+
|
341
|
+
|
342
|
+
NATIVE_ROUTINE = {
|
343
|
+
'TMail::MsgidH' => :msgid_parse,
|
344
|
+
'TMail::RefH' => :refs_parse
|
345
|
+
}
|
346
|
+
|
347
|
+
def parse( str, obj, ident )
|
348
|
+
return if /\A\s*\z/ === str
|
349
|
+
|
350
|
+
@field = obj
|
351
|
+
|
352
|
+
if mid = NATIVE_ROUTINE[ obj.type.name ] then
|
353
|
+
send mid, str
|
354
|
+
else
|
355
|
+
unless ident then
|
356
|
+
ident = obj.type.name.split('::')[-1].to_s
|
357
|
+
cmt = []
|
358
|
+
obj.comments.replace cmt
|
359
|
+
else
|
360
|
+
cmt = nil
|
361
|
+
end
|
362
|
+
|
363
|
+
@scanner = MailScanner.new( str, ident, cmt )
|
364
|
+
@scanner.debug = @scanner_debug
|
365
|
+
@first = [ ident.intern, ident ]
|
366
|
+
@pass_array = [nil, nil]
|
367
|
+
|
368
|
+
do_parse
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
|
373
|
+
private
|
374
|
+
|
375
|
+
|
376
|
+
def next_token
|
377
|
+
if @first then
|
378
|
+
ret = @first
|
379
|
+
@first = nil
|
380
|
+
ret
|
381
|
+
else
|
382
|
+
@scanner.scan @pass_array
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def on_error( tok, val, vstack )
|
387
|
+
raise ParseError,
|
388
|
+
"\nparse error in '#{@field.name}' header, on token #{val.inspect}"
|
389
|
+
end
|
390
|
+
|
391
|
+
|
392
|
+
|
393
|
+
def refs_parse( str )
|
394
|
+
arr = []
|
395
|
+
|
396
|
+
while mdata = ::TMail::MSGID.match( str ) do
|
397
|
+
str = mdata.post_match
|
398
|
+
|
399
|
+
pre = mdata.pre_match
|
400
|
+
pre.strip!
|
401
|
+
proc_phrase pre, arr unless pre.empty?
|
402
|
+
arr.push mdata.to_s
|
403
|
+
end
|
404
|
+
str.strip!
|
405
|
+
proc_phrase str, arr if not pre or pre.empty?
|
406
|
+
|
407
|
+
@field.refs.replace arr
|
408
|
+
end
|
409
|
+
|
410
|
+
def proc_phrase( str, arr )
|
411
|
+
while mdata = /"([^\\]*(?:\\.[^"\\]*)*)"/.match( str ) do
|
412
|
+
str = mdata.post_match
|
413
|
+
|
414
|
+
pre = mdata.pre_match
|
415
|
+
pre.strip!
|
416
|
+
arr.push pre unless pre.empty?
|
417
|
+
arr.push mdata[1]
|
418
|
+
end
|
419
|
+
str.strip!
|
420
|
+
arr.push unless str.empty?
|
421
|
+
end
|
422
|
+
|
423
|
+
|
424
|
+
def msgid_parse( str )
|
425
|
+
if mdata = ::TMail::MSGID.match( str ) then
|
426
|
+
@field.msgid = mdata.to_s
|
427
|
+
else
|
428
|
+
raise ParseError, "wrong Message-ID format: #{str}"
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
---- footer
|
433
|
+
|
434
|
+
end # module TMail
|
435
|
+
|
436
|
+
mp = TMail::Testp.new
|
437
|
+
mp.parse
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
class A
|
3
|
+
|
4
|
+
preclow
|
5
|
+
left preclow prechigh right left nonassoc token
|
6
|
+
right preclow prechigh right left nonassoc token
|
7
|
+
nonassoc preclow prechigh right left nonassoc token
|
8
|
+
prechigh
|
9
|
+
|
10
|
+
convert
|
11
|
+
left 'a'
|
12
|
+
right 'b'
|
13
|
+
preclow 'c'
|
14
|
+
nonassoc 'd'
|
15
|
+
preclow 'e'
|
16
|
+
prechigh 'f'
|
17
|
+
end
|
18
|
+
|
19
|
+
rule
|
20
|
+
|
21
|
+
left: right nonassoc preclow prechigh
|
22
|
+
|
23
|
+
right: A B C
|
24
|
+
|
25
|
+
end
|