racc 1.4.14 → 1.4.15

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 (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