racc 1.4.14 → 1.4.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/Manifest.txt +50 -0
  3. data/ext/racc/com/headius/racc/Cparse.java +66 -23
  4. data/ext/racc/cparse.c +1 -1
  5. data/ext/racc/depend +1 -1
  6. data/lib/racc/info.rb +2 -2
  7. data/test/assets/bibtex.y +141 -0
  8. data/test/assets/cadenza.y +170 -0
  9. data/test/assets/cast.y +926 -0
  10. data/test/assets/csspool.y +729 -0
  11. data/test/assets/edtf.y +583 -0
  12. data/test/assets/huia.y +318 -0
  13. data/test/assets/journey.y +47 -0
  14. data/test/assets/liquor.y +313 -0
  15. data/test/assets/machete.y +423 -0
  16. data/test/assets/macruby.y +2197 -0
  17. data/test/assets/mediacloth.y +599 -0
  18. data/test/assets/mof.y +649 -0
  19. data/test/assets/namae.y +302 -0
  20. data/test/assets/nasl.y +626 -0
  21. data/test/assets/nokogiri-css.y +255 -0
  22. data/test/assets/opal.y +1807 -0
  23. data/test/assets/php_serialization.y +98 -0
  24. data/test/assets/rdblockparser.y +576 -0
  25. data/test/assets/rdinlineparser.y +561 -0
  26. data/test/assets/riml.y +665 -0
  27. data/test/assets/ruby18.y +1943 -0
  28. data/test/assets/ruby19.y +2174 -0
  29. data/test/assets/ruby20.y +2350 -0
  30. data/test/assets/ruby21.y +2359 -0
  31. data/test/assets/ruby22.y +2381 -0
  32. data/test/assets/tp_plus.y +622 -0
  33. data/test/assets/twowaysql.y +278 -0
  34. data/test/helper.rb +31 -15
  35. data/test/regress/bibtex +474 -0
  36. data/test/regress/cadenza +796 -0
  37. data/test/regress/cast +3425 -0
  38. data/test/regress/csspool +2318 -0
  39. data/test/regress/edtf +1794 -0
  40. data/test/regress/huia +1392 -0
  41. data/test/regress/journey +222 -0
  42. data/test/regress/liquor +885 -0
  43. data/test/regress/machete +833 -0
  44. data/test/regress/mediacloth +1463 -0
  45. data/test/regress/mof +1368 -0
  46. data/test/regress/namae +634 -0
  47. data/test/regress/nasl +2058 -0
  48. data/test/regress/nokogiri-css +836 -0
  49. data/test/regress/opal +6429 -0
  50. data/test/regress/php_serialization +336 -0
  51. data/test/regress/rdblockparser +1061 -0
  52. data/test/regress/rdinlineparser +1243 -0
  53. data/test/regress/riml +3297 -0
  54. data/test/regress/ruby18 +6351 -0
  55. data/test/regress/ruby22 +7456 -0
  56. data/test/regress/tp_plus +1933 -0
  57. data/test/regress/twowaysql +556 -0
  58. data/test/test_racc_command.rb +177 -0
  59. metadata +75 -20
@@ -0,0 +1,98 @@
1
+ # MIT License
2
+ # See https://github.com/divoxx/ruby-php-serialization/blob/master/LICENSE.txt
3
+
4
+ class PhpSerialization::Unserializer
5
+ rule
6
+
7
+ data : null ';' { @object = val[0] }
8
+ | bool ';' { @object = val[0] }
9
+ | integer ';' { @object = val[0] }
10
+ | double ';' { @object = val[0] }
11
+ | string ';' { @object = val[0] }
12
+ | assoc_array { @object = val[0] }
13
+ | object { @object = val[0] }
14
+ ;
15
+
16
+ null : 'N' { result = nil }
17
+ ;
18
+
19
+ bool : 'b' ':' NUMBER { result = Integer(val[2]) > 0 }
20
+ ;
21
+
22
+ integer : 'i' ':' NUMBER { result = Integer(val[2]) }
23
+ ;
24
+
25
+ double : 'd' ':' NUMBER { result = Float(val[2]) }
26
+ ;
27
+
28
+ string : 's' ':' NUMBER ':' STRING { result = val[4] }
29
+ ;
30
+
31
+ object : 'O' ':' NUMBER ':' STRING ':' NUMBER ':' '{' attribute_list '}'
32
+ {
33
+ if eval("defined?(#{val[4]})")
34
+ result = Object.const_get(val[4]).new
35
+
36
+ val[9].each do |(attr_name, value)|
37
+ # Protected and private attributes will have a \0..\0 prefix
38
+ attr_name = attr_name.gsub(/\A\\0[^\\]+\\0/, '')
39
+ result.instance_variable_set("@#{attr_name}", value)
40
+ end
41
+ else
42
+ klass_name = val[4].gsub(/^Struct::/, '')
43
+ attr_names, values = [], []
44
+
45
+ val[9].each do |(attr_name, value)|
46
+ # Protected and private attributes will have a \0..\0 prefix
47
+ attr_names << attr_name.gsub(/\A\\0[^\\]+\\0/, '')
48
+ values << value
49
+ end
50
+
51
+ result = Struct.new(klass_name, *attr_names).new(*values)
52
+ result.instance_variable_set("@_php_class", klass_name)
53
+ end
54
+ }
55
+ ;
56
+
57
+ attribute_list : attribute_list attribute { result = val[0] << val[1] }
58
+ | { result = [] }
59
+ ;
60
+
61
+ attribute : data data { result = val }
62
+ ;
63
+
64
+ assoc_array : 'a' ':' NUMBER ':' '{' attribute_list '}'
65
+ {
66
+ # Checks if the keys are a sequence of integers
67
+ idx = -1
68
+ arr = val[5].all? { |(k,v)| k == (idx += 1) }
69
+
70
+ if arr
71
+ result = val[5].map { |(k,v)| v }
72
+ else
73
+ result = Hash[val[5]]
74
+ end
75
+ }
76
+ ;
77
+
78
+ end
79
+
80
+ ---- header ----
81
+ require 'php_serialization/tokenizer'
82
+
83
+ ---- inner ----
84
+ def initialize(tokenizer_klass = Tokenizer)
85
+ @tokenizer_klass = tokenizer_klass
86
+ end
87
+
88
+ def run(string)
89
+ @tokenizer = @tokenizer_klass.new(string)
90
+ yyparse(@tokenizer, :each)
91
+ return @object
92
+ ensure
93
+ @tokenizer = nil
94
+ end
95
+
96
+ def next_token
97
+ @tokenizer.next_token
98
+ end
@@ -0,0 +1,576 @@
1
+ # Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ # You can redistribute it and/or modify it under either the terms of the GPL
3
+ # version 2 (see https://github.com/uwabami/rdtool/blob/master/COPYING.txt),
4
+ # or the conditions below:
5
+ #
6
+ # 1. You may make and give away verbatim copies of the source form of the
7
+ # software without restriction, provided that you duplicate all of the
8
+ # original copyright notices and associated disclaimers.
9
+ #
10
+ # 2. You may modify your copy of the software in any way, provided that
11
+ # you do at least ONE of the following:
12
+ #
13
+ # a) place your modifications in the Public Domain or otherwise
14
+ # make them Freely Available, such as by posting said
15
+ # modifications to Usenet or an equivalent medium, or by allowing
16
+ # the author to include your modifications in the software.
17
+ #
18
+ # b) use the modified software only within your corporation or
19
+ # organization.
20
+ #
21
+ # c) rename any non-standard executables so the names do not conflict
22
+ # with standard executables, which must also be provided.
23
+ #
24
+ # d) make other distribution arrangements with the author.
25
+ #
26
+ # 3. You may distribute the software in object code or executable
27
+ # form, provided that you do at least ONE of the following:
28
+ #
29
+ # a) distribute the executables and library files of the software,
30
+ # together with instructions (in the manual page or equivalent)
31
+ # on where to get the original distribution.
32
+ #
33
+ # b) accompany the distribution with the machine-readable source of
34
+ # the software.
35
+ #
36
+ # c) give non-standard executables non-standard names, with
37
+ # instructions on where to get the original software distribution.
38
+ #
39
+ # d) make other distribution arrangements with the author.
40
+ #
41
+ # 4. You may modify and include the part of the software into any other
42
+ # software (possibly commercial). But some files in the distribution
43
+ # are not written by the author, so that they are not under this terms.
44
+ #
45
+ # They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
46
+ # files under the ./missing directory. See each file for the copying
47
+ # condition.
48
+ #
49
+ # 5. The scripts and library files supplied as input to or produced as
50
+ # output from the software do not automatically fall under the
51
+ # copyright of the software, but belong to whomever generated them,
52
+ # and may be sold commercially, and may be aggregated with this
53
+ # software.
54
+ #
55
+ # 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
56
+ # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
57
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58
+ # PURPOSE.
59
+
60
+ class RDParser
61
+
62
+ preclow
63
+ nonassoc DUMMY
64
+ left ITEMLISTLINE ENUMLISTLINE DESCLISTLINE METHODLISTLINE STRINGLINE
65
+ prechigh
66
+
67
+ token STRINGLINE ITEMLISTLINE ENUMLISTLINE DESCLISTLINE METHODLISTLINE
68
+ WHITELINE SUBTREE HEADLINE INCLUDE INDENT DEDENT DUMMY
69
+
70
+ rule
71
+ document : blocks { result = DocumentElement.new
72
+ add_children_to_element(result, *val[0])
73
+ }
74
+ | {
75
+ raise ParseError,
76
+ "Error: file empty."
77
+ }
78
+ ;
79
+ blocks : blocks block { result.concat(val[1]) }
80
+ | block
81
+ ;
82
+ block : textblock { result = val }
83
+ | verbatim { result = val }
84
+ | lists
85
+ | headline { result = val }
86
+ | include { result = val }
87
+ | WHITELINE { result = [] }
88
+ | SUBTREE { result = val[0].blocks }
89
+ ;
90
+
91
+ headline : HEADLINE { # val[0] is like [level, title]
92
+ title = @inline_parser.parse(val[0][1])
93
+ result = Headline.new(val[0][0])
94
+ add_children_to_element(result, *title)
95
+ }
96
+ ;
97
+ include : INCLUDE { result = Include.new(val[0]) }
98
+ ;
99
+
100
+ textblock : textblockcontent = DUMMY
101
+ { # val[0] is Array of String
102
+ content = cut_off(val[0]).join("")
103
+ contents = @inline_parser.parse(content)
104
+ result = TextBlock.new()
105
+ add_children_to_element(result, *contents)
106
+ }
107
+ ;
108
+ textblockcontent : textblockcontent STRINGLINE
109
+ { result.push(val[1]) }
110
+ | STRINGLINE { result = val }
111
+ ;
112
+
113
+ verbatim : INDENT verbatimcontent DEDENT
114
+ { # val[1] is Array of String
115
+ content = cut_off(val[1])
116
+ result = Verbatim.new(content)
117
+ # imform to lexer.
118
+ @in_verbatim = false }
119
+ ;
120
+ verbatim_after_lists : verbatimcontent
121
+ { # val[0] is Array of String
122
+ content = cut_off(val[0])
123
+ result = Verbatim.new(content)
124
+ # imform to lexer.
125
+ @in_verbatim = false }
126
+ ;
127
+ verbatimcontent : verbatimcontent STRINGLINE
128
+ { result.push(val[1]) }
129
+ | verbatimcontent INDENT verbatimcontent DEDENT
130
+ { result.concat(val[2]) }
131
+ | verbatimcontent WHITELINE
132
+ { result.push("\n") }
133
+ | STRINGLINE { result = val
134
+ # imform to lexer.
135
+ @in_verbatim = true }
136
+ ;
137
+
138
+ list : itemlist
139
+ | enumlist
140
+ | desclist
141
+ | methodlist
142
+ ;
143
+ lists : lists2 = DUMMY
144
+ | INDENT lists2 DEDENT { result = val[1] }
145
+ | INDENT lists2 verbatim_after_lists DEDENT
146
+ { result = val[1].push(val[2]) }
147
+ ;
148
+
149
+ lists2 : lists2 list { result.push(val[1]) }
150
+ | list { result = val }
151
+ ;
152
+
153
+ itemlist : itemlistitems = DUMMY {
154
+ result = ItemList.new
155
+ add_children_to_element(result, *val[0])
156
+ }
157
+ ;
158
+ itemlistitems : itemlistitems itemlistitem
159
+ { result.push(val[1]) }
160
+ | itemlistitem { result = val }
161
+ ;
162
+ itemlistitem : first_textblock_in_itemlist other_blocks_in_list DEDENT
163
+ {
164
+ result = ItemListItem.new
165
+ add_children_to_element(result, val[0], *val[1])
166
+ }
167
+ ;
168
+
169
+ enumlist : enumlistitems = DUMMY {
170
+ result = EnumList.new
171
+ add_children_to_element(result, *val[0])
172
+ }
173
+ ;
174
+ enumlistitems : enumlistitems enumlistitem
175
+ { result.push(val[1]) }
176
+ | enumlistitem { result = val }
177
+ ;
178
+ enumlistitem : first_textblock_in_enumlist other_blocks_in_list DEDENT
179
+ {
180
+ result = EnumListItem.new
181
+ add_children_to_element(result, val[0], *val[1])
182
+ }
183
+ ;
184
+
185
+ desclist : desclistitems = DUMMY {
186
+ result = DescList.new
187
+ add_children_to_element(result, *val[0])
188
+ }
189
+ ;
190
+ desclistitems : desclistitems desclistitem {
191
+ result.push(val[1]) }
192
+ | desclistitem { result = val }
193
+ ;
194
+ desclistitem : DESCLISTLINE description_part DEDENT
195
+ {
196
+ term = DescListItem::Term.new
197
+ term_contents = @inline_parser.parse(val[0].strip)
198
+ add_children_to_element(term, *term_contents)
199
+
200
+ result = DescListItem.new
201
+ set_term_to_element(result, term)
202
+ add_children_to_element(result, *val[1])
203
+ }
204
+ ;
205
+
206
+ methodlist : methodlistitems = DUMMY {
207
+ result = MethodList.new
208
+ add_children_to_element(result, *val[0])
209
+ }
210
+ ;
211
+ methodlistitems : methodlistitems methodlistitem
212
+ { result.push(val[1]) }
213
+ | methodlistitem { result = val }
214
+ ;
215
+ methodlistitem : METHODLISTLINE description_part DEDENT
216
+ {
217
+ term = MethodListItem::Term.new(val[0].strip)
218
+ result = MethodListItem.new
219
+ set_term_to_element(result, term)
220
+ add_children_to_element(result, *val[1])
221
+ }
222
+ ;
223
+
224
+ description_part : whitelines textblock blocks_in_list
225
+ { result = [val[1]].concat(val[2]) }
226
+ | whitelines textblock { result = [val[1]] }
227
+ | whitelines INDENT blocks_in_list DEDENT
228
+ { result = val[2] }
229
+ | whitelines { result = [] }
230
+ ;
231
+
232
+ blocks_in_list : blocks_in_list block_in_list { result.concat(val[1]) }
233
+ | block_in_list
234
+ ;
235
+ block_in_list : textblock { result = val }
236
+ | verbatim { result = val }
237
+ | lists
238
+ | WHITELINE { result = [] }
239
+ ;
240
+ whitelines : whitelines2
241
+ |
242
+ ;
243
+ whitelines2 : WHITELINE whitelines2
244
+ | WHITELINE
245
+ ;
246
+
247
+ first_textblock_in_itemlist : ITEMLISTLINE textblockcontent
248
+
249
+ { content = cut_off([val[0]].concat(val[1])).join("")
250
+ contents = @inline_parser.parse(content)
251
+ result = TextBlock.new()
252
+ add_children_to_element(result, *contents)
253
+ }
254
+ | ITEMLISTLINE
255
+
256
+ { content = cut_off([val[0]]).join("")
257
+ contents = @inline_parser.parse(content)
258
+ result = TextBlock.new()
259
+ add_children_to_element(result, *contents)
260
+ }
261
+ ;
262
+ first_textblock_in_enumlist : ENUMLISTLINE textblockcontent
263
+
264
+ { content = cut_off([val[0]].concat(val[1])).join("")
265
+ contents = @inline_parser.parse(content)
266
+ result = TextBlock.new()
267
+ add_children_to_element(result, *contents)
268
+ }
269
+ | ENUMLISTLINE
270
+
271
+ { content = cut_off([val[0]]).join("")
272
+ contents = @inline_parser.parse(content)
273
+ result = TextBlock.new()
274
+ add_children_to_element(result, *contents)
275
+ }
276
+ ;
277
+ other_blocks_in_list : verbatim blocks_in_list
278
+ { result = [val[0]].concat(val[1]) }
279
+ | lists blocks_in_list { result.concat(val[1]) }
280
+ | WHITELINE blocks_in_list { result = val[1] }
281
+ | verbatim { result = val }
282
+ | lists
283
+ | WHITELINE { result = [] }
284
+ | { result = [] }
285
+ ;
286
+ end
287
+
288
+ ---- inner
289
+ include ParserUtility
290
+
291
+ TMPFILE = ["rdtmp", $$, 0]
292
+
293
+ attr_reader :tree
294
+
295
+ def initialize
296
+ @inline_parser = RDInlineParser.new(self)
297
+ end
298
+
299
+ def parse(src, tree)
300
+ @src = src
301
+ @src.push(false)
302
+ # RDtree
303
+ @tree = tree
304
+
305
+ # @i: index(line no.) of src
306
+ @i = 0
307
+ # stack for current indentation
308
+ @indent_stack = []
309
+ # how indented.
310
+ @current_indent = @indent_stack.join("")
311
+ # RDParser for tmp src
312
+ @subparser = nil
313
+ # which part is in now
314
+ @in_part = nil
315
+ @part_content = []
316
+
317
+ @in_verbatim = false
318
+
319
+ @yydebug = true
320
+ do_parse
321
+ end
322
+
323
+ def next_token
324
+ # preprocessing
325
+ # if it is not in RD part
326
+ # => method
327
+ while @in_part != "rd"
328
+ line = @src[@i]
329
+ @i += 1 # next line
330
+
331
+ case line
332
+ # src end
333
+ when false
334
+ return [false, false]
335
+ # RD part begin
336
+ when /^=begin\s*(?:\bRD\b.*)?\s*$/
337
+ if @in_part # if in non-RD part
338
+ @part_content.push(line)
339
+ else
340
+ @in_part = "rd"
341
+ return [:WHITELINE, "=begin\n"] # <= for textblockand
342
+ end
343
+ # non-RD part begin
344
+ when /^=begin\s+(\w+)/
345
+ part = $1
346
+ if @in_part # if in non-RD part
347
+ @part_content.push(line)
348
+ else
349
+ @in_part = part if @tree.filter[part] # if filter exists
350
+ # p "BEGIN_PART: #{@in_part}" # DEBUG
351
+ end
352
+ # non-RD part end
353
+ when /^=end/
354
+ if @in_part # if in non-RD part
355
+ # p "END_PART: #{@in_part}" # DEBUG
356
+ # make Part-in object
357
+ part = RD::Part.new(@part_content.join(""), @tree, "r")
358
+ @part_content.clear
359
+ # call filter, part_out is output(Part object)
360
+ part_out = @tree.filter[@in_part].call(part)
361
+
362
+ if @tree.filter[@in_part].mode == :rd # if output is RD formated
363
+ subtree = parse_subtree( (RUBY_VERSION >= '1.9.0' ? part_out.lines.to_a : part_out.to_a ) )
364
+ else # if output is target formated
365
+ basename = TMPFILE.join('.')
366
+ TMPFILE[-1] += 1
367
+ tmpfile = open(@tree.tmp_dir + "/" + basename + ".#{@in_part}", "w")
368
+ tmpfile.print(part_out)
369
+ tmpfile.close
370
+ subtree = parse_subtree(["=begin\n", "<<< #{basename}\n", "=end\n"])
371
+ end
372
+ @in_part = nil
373
+ return [:SUBTREE, subtree]
374
+ end
375
+ else
376
+ if @in_part # if in non-RD part
377
+ @part_content.push(line)
378
+ end
379
+ end
380
+ end
381
+
382
+ @current_indent = @indent_stack.join("")
383
+ line = @src[@i]
384
+ case line
385
+ when false
386
+ if_current_indent_equal("") do
387
+ [false, false]
388
+ end
389
+ when /^=end/
390
+ if_current_indent_equal("") do
391
+ @in_part = nil
392
+ [:WHITELINE, "=end"] # MUST CHANGE??
393
+ end
394
+ when /^\s*$/
395
+ @i += 1 # next line
396
+ return [:WHITELINE, ':WHITELINE']
397
+ when /^\#/ # comment line
398
+ @i += 1 # next line
399
+ self.next_token()
400
+ when /^(={1,4})(?!=)\s*(?=\S)/, /^(\+{1,2})(?!\+)\s*(?=\S)/
401
+ rest = $' # '
402
+ rest.strip!
403
+ mark = $1
404
+ if_current_indent_equal("") do
405
+ return [:HEADLINE, [Headline.mark_to_level(mark), rest]]
406
+ end
407
+ when /^<<<\s*(\S+)/
408
+ file = $1
409
+ if_current_indent_equal("") do
410
+ suffix = file[-3 .. -1]
411
+ if suffix == ".rd" or suffix == ".rb"
412
+ subtree = parse_subtree(get_included(file))
413
+ [:SUBTREE, subtree]
414
+ else
415
+ [:INCLUDE, file]
416
+ end
417
+ end
418
+ when /^(\s*)\*(\s*)/
419
+ rest = $' # '
420
+ newIndent = $2
421
+ if_current_indent_equal($1) do
422
+ if @in_verbatim
423
+ [:STRINGLINE, line]
424
+ else
425
+ @indent_stack.push("\s" << newIndent)
426
+ [:ITEMLISTLINE, rest]
427
+ end
428
+ end
429
+ when /^(\s*)(\(\d+\))(\s*)/
430
+ rest = $' # '
431
+ mark = $2
432
+ newIndent = $3
433
+ if_current_indent_equal($1) do
434
+ if @in_verbatim
435
+ [:STRINGLINE, line]
436
+ else
437
+ @indent_stack.push("\s" * mark.size << newIndent)
438
+ [:ENUMLISTLINE, rest]
439
+ end
440
+ end
441
+ when /^(\s*):(\s*)/
442
+ rest = $' # '
443
+ newIndent = $2
444
+ if_current_indent_equal($1) do
445
+ if @in_verbatim
446
+ [:STRINGLINE, line]
447
+ else
448
+ @indent_stack.push("\s" << $2)
449
+ [:DESCLISTLINE, rest]
450
+ end
451
+ end
452
+ when /^(\s*)---(?!-|\s*$)/
453
+ indent = $1
454
+ rest = $'
455
+ /\s*/ === rest
456
+ term = $'
457
+ new_indent = $&
458
+ if_current_indent_equal(indent) do
459
+ if @in_verbatim
460
+ [:STRINGLINE, line]
461
+ else
462
+ @indent_stack.push("\s\s\s" + new_indent)
463
+ [:METHODLISTLINE, term]
464
+ end
465
+ end
466
+ when /^(\s*)/
467
+ if_current_indent_equal($1) do
468
+ [:STRINGLINE, line]
469
+ end
470
+ else
471
+ raise "[BUG] parsing error may occured."
472
+ end
473
+ end
474
+
475
+ =begin private
476
+ --- RDParser#if_current_indent_equal(indent)
477
+ if (({@current_indent == ((|indent|))})) then yield block, otherwise
478
+ process indentation.
479
+ =end
480
+ # always @current_indent = @indent_stack.join("")
481
+ def if_current_indent_equal(indent)
482
+ indent = indent.sub(/\t/, "\s" * 8)
483
+ if @current_indent == indent
484
+ @i += 1 # next line
485
+ yield
486
+ elsif indent.index(@current_indent) == 0
487
+ @indent_stack.push(indent[@current_indent.size .. -1])
488
+ [:INDENT, ":INDENT"]
489
+ else
490
+ @indent_stack.pop
491
+ [:DEDENT, ":DEDENT"]
492
+ end
493
+ end
494
+ private :if_current_indent_equal
495
+
496
+ def cut_off(src)
497
+ ret = []
498
+ whiteline_buf = []
499
+ line = src.shift
500
+ /^\s*/ =~ line
501
+ indent = Regexp.quote($&)
502
+ ret.push($') # '
503
+ while line = src.shift
504
+ if /^(\s*)$/ =~ line
505
+ whiteline_buf.push(line)
506
+ elsif /^#{indent}/ =~ line
507
+ unless whiteline_buf.empty?
508
+ ret.concat(whiteline_buf)
509
+ whiteline_buf.clear
510
+ end
511
+ ret.push($') # '
512
+ else
513
+ raise "[BUG]: probably Parser Error while cutting off.\n"
514
+ end
515
+ end
516
+ ret
517
+ end
518
+ private :cut_off
519
+
520
+ def set_term_to_element(parent, term)
521
+ # parent.set_term_under_document_struct(term, @tree.document_struct)
522
+ parent.set_term_without_document_struct(term)
523
+ end
524
+ private :set_term_to_element
525
+
526
+ def on_error( et, ev, _values )
527
+ line = @src[@i]
528
+ prv, cur, nxt = format_line_num(@i, @i+1, @i+2)
529
+
530
+ raise ParseError, <<Msg
531
+
532
+ RD syntax error: line #{@i+1}:
533
+ #{prv} |#{@src[@i-1].chomp}
534
+ #{cur}=>|#{@src[@i].chomp}
535
+ #{nxt} |#{@src[@i+1].chomp}
536
+
537
+ Msg
538
+ end
539
+
540
+ def line_index
541
+ @i
542
+ end
543
+
544
+ def parse_subtree(src)
545
+ @subparser = RD::RDParser.new() unless @subparser
546
+
547
+ @subparser.parse(src, @tree)
548
+ end
549
+ private :parse_subtree
550
+
551
+ def get_included(file)
552
+ included = ""
553
+ @tree.include_path.each do |dir|
554
+ file_name = dir + "/" + file
555
+ if test(?e, file_name)
556
+ included = IO.readlines(file_name)
557
+ break
558
+ end
559
+ end
560
+ included
561
+ end
562
+ private :get_included
563
+
564
+ def format_line_num(*args)
565
+ width = args.collect{|i| i.to_s.length }.max
566
+ args.collect{|i| sprintf("%#{width}d", i) }
567
+ end
568
+ private :format_line_num
569
+
570
+ ---- header
571
+ require "rd/rdinlineparser.tab.rb"
572
+ require "rd/parser-util"
573
+
574
+ module RD
575
+ ---- footer
576
+ end # end of module RD