packcr 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/lib/packcr/context.rb +10 -827
- data/lib/packcr/generator.rb +1 -0
- data/lib/packcr/node/action_node.rb +8 -2
- data/lib/packcr/node/alternate_node.rb +8 -3
- data/lib/packcr/node/capture_node.rb +14 -0
- data/lib/packcr/node/charclass_node.rb +4 -0
- data/lib/packcr/node/error_node.rb +15 -2
- data/lib/packcr/node/expand_node.rb +4 -0
- data/lib/packcr/node/predicate_node.rb +8 -3
- data/lib/packcr/node/quantity_node.rb +9 -4
- data/lib/packcr/node/reference_node.rb +22 -0
- data/lib/packcr/node/rule_node.rb +14 -2
- data/lib/packcr/node/sequence_node.rb +8 -3
- data/lib/packcr/node/string_node.rb +4 -0
- data/lib/packcr/node.rb +17 -0
- data/lib/packcr/parser.rb +4292 -0
- data/lib/packcr/stream.rb +2 -1
- data/lib/packcr/util.rb +3 -0
- data/lib/packcr/version.rb +1 -1
- metadata +3 -2
data/lib/packcr/context.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require "
|
2
|
-
require "stringio"
|
1
|
+
require "packcr/parser"
|
3
2
|
|
4
3
|
class Packcr
|
5
|
-
class Context
|
4
|
+
class Context < Packcr::Parser
|
6
5
|
def initialize(path, lines: false, debug: false, ascii: false, lang: nil)
|
6
|
+
super(debug: debug)
|
7
7
|
if !path
|
8
8
|
raise ArgumentError, "bad path: #{path}";
|
9
9
|
end
|
@@ -40,7 +40,6 @@ class Packcr
|
|
40
40
|
end
|
41
41
|
|
42
42
|
@lines = !!lines
|
43
|
-
@debug = !!debug
|
44
43
|
@ascii = !!ascii
|
45
44
|
|
46
45
|
@errnum = 0
|
@@ -55,10 +54,9 @@ class Packcr
|
|
55
54
|
@source = []
|
56
55
|
@header = []
|
57
56
|
@lheader = []
|
57
|
+
@lsource = []
|
58
58
|
@location = []
|
59
|
-
@
|
60
|
-
@rulehash = {}
|
61
|
-
@buffer = Packcr::Buffer.new
|
59
|
+
@init = []
|
62
60
|
|
63
61
|
if block_given?
|
64
62
|
yield(self)
|
@@ -87,7 +85,7 @@ class Packcr
|
|
87
85
|
end
|
88
86
|
|
89
87
|
def class_name
|
90
|
-
prefix.gsub(/(?:_
|
88
|
+
prefix.gsub(/(?:_|^|(\W))([a-z])/) { "#{$1}#{$2}".upcase }
|
91
89
|
end
|
92
90
|
|
93
91
|
def auxil_def
|
@@ -100,308 +98,6 @@ class Packcr
|
|
100
98
|
"#{type}#{type =~ /\*$/ ? "" : " "}"
|
101
99
|
end
|
102
100
|
|
103
|
-
def eof?
|
104
|
-
refill_buffer(1) < 1
|
105
|
-
end
|
106
|
-
|
107
|
-
def eol?
|
108
|
-
return false if eof?
|
109
|
-
|
110
|
-
case @buffer[@bufcur]
|
111
|
-
when 0xa
|
112
|
-
@bufcur += 1
|
113
|
-
@linenum += 1
|
114
|
-
@charnum = 0
|
115
|
-
@linepos = @bufpos + @bufcur
|
116
|
-
true
|
117
|
-
when 0xd
|
118
|
-
@bufcur += 1
|
119
|
-
if !eof? && @buffer[@bufcur] == 0xd
|
120
|
-
@bufcur += 1
|
121
|
-
end
|
122
|
-
@linenum += 1
|
123
|
-
@charnum = 0
|
124
|
-
@linepos = @bufpos + @bufcur
|
125
|
-
true
|
126
|
-
else
|
127
|
-
false
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def column_number
|
132
|
-
unless @bufpos + @bufcur >= @linepos
|
133
|
-
raise "invalid position: expect #{@bufpos + @bufcur} >= #{@linepos}"
|
134
|
-
end
|
135
|
-
offset = @linepos > @bufpos ? @linepos - @bufpos : 0
|
136
|
-
if @ascii
|
137
|
-
@charnum + @bufcur - offset
|
138
|
-
else
|
139
|
-
@charnum + @buffer.count_characters(offset, @bufcur)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def make_rulehash
|
144
|
-
@rules.each do |rule|
|
145
|
-
@rulehash[rule.name] = rule
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def refill_buffer(num = nil)
|
150
|
-
while !num || @buffer.len - @bufcur < num
|
151
|
-
c = @ifile.getc
|
152
|
-
break if c.nil?
|
153
|
-
@buffer.add(c.ord)
|
154
|
-
end
|
155
|
-
|
156
|
-
return @buffer.len - @bufcur
|
157
|
-
end
|
158
|
-
|
159
|
-
def commit_buffer
|
160
|
-
if @buffer.len < @bufcur
|
161
|
-
raise "unexpected buffer state: length(#{@buffer.len}), current(#{@bufcur})"
|
162
|
-
end
|
163
|
-
if @linepos < @bufpos + @bufcur
|
164
|
-
count = @ascii ? @bufcur : @buffer.count_characters(0, @bufcur)
|
165
|
-
@charnum += count
|
166
|
-
end
|
167
|
-
@buffer.add_pos(@bufcur)
|
168
|
-
@bufpos = @bufpos + @bufcur
|
169
|
-
@bufcur = 0
|
170
|
-
end
|
171
|
-
|
172
|
-
def write_buffer(stream)
|
173
|
-
n = @buffer.len
|
174
|
-
text = @buffer.to_s
|
175
|
-
if n > 0 && text[-1] == "\r"
|
176
|
-
text = text[0..-2]
|
177
|
-
end
|
178
|
-
stream.write_text(text)
|
179
|
-
@bufcur = n
|
180
|
-
end
|
181
|
-
|
182
|
-
def match_character(ch)
|
183
|
-
if refill_buffer(1) >= 1
|
184
|
-
if @buffer[@bufcur].ord == ch.ord
|
185
|
-
@bufcur += 1
|
186
|
-
return true
|
187
|
-
end
|
188
|
-
end
|
189
|
-
false
|
190
|
-
end
|
191
|
-
|
192
|
-
def match_character_range(min, max)
|
193
|
-
if refill_buffer(1) >= 1
|
194
|
-
c = @buffer[@bufcur].ord
|
195
|
-
if (min..max) === c
|
196
|
-
@bufcur += 1
|
197
|
-
return true
|
198
|
-
end
|
199
|
-
end
|
200
|
-
false
|
201
|
-
end
|
202
|
-
|
203
|
-
def match_character_set(chars)
|
204
|
-
if refill_buffer(1) >= 1
|
205
|
-
c = @buffer[@bufcur].ord
|
206
|
-
chars.each_byte do |ch|
|
207
|
-
if c == ch
|
208
|
-
@bufcur += 1
|
209
|
-
return true
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
false
|
214
|
-
end
|
215
|
-
|
216
|
-
def match_string(str)
|
217
|
-
n = str.length
|
218
|
-
if refill_buffer(n) >= n
|
219
|
-
if @buffer.to_s[@bufcur, n] == str
|
220
|
-
@bufcur += n
|
221
|
-
return true
|
222
|
-
end
|
223
|
-
end
|
224
|
-
false
|
225
|
-
end
|
226
|
-
|
227
|
-
def match_blank
|
228
|
-
match_character_set(" \t\v\f")
|
229
|
-
end
|
230
|
-
|
231
|
-
def match_character_any
|
232
|
-
if refill_buffer(1) >= 1
|
233
|
-
@bufcur += 1
|
234
|
-
return true
|
235
|
-
end
|
236
|
-
false
|
237
|
-
end
|
238
|
-
|
239
|
-
def match_section_line_(head)
|
240
|
-
if match_string(head)
|
241
|
-
while !eol? && !eof?
|
242
|
-
match_character_any
|
243
|
-
end
|
244
|
-
return true
|
245
|
-
end
|
246
|
-
false
|
247
|
-
end
|
248
|
-
|
249
|
-
def match_section_line_continuable_(head)
|
250
|
-
if match_string(head)
|
251
|
-
while !eof?
|
252
|
-
pos = @bufcur
|
253
|
-
if eol?
|
254
|
-
if @buffer[pos - 1] != "\\".ord
|
255
|
-
break
|
256
|
-
end
|
257
|
-
else
|
258
|
-
match_character_any
|
259
|
-
end
|
260
|
-
end
|
261
|
-
return true
|
262
|
-
end
|
263
|
-
false
|
264
|
-
end
|
265
|
-
|
266
|
-
def match_section_block_(left, right, name)
|
267
|
-
l = @linenum
|
268
|
-
m = column_number
|
269
|
-
if match_string(left)
|
270
|
-
while !match_string(right)
|
271
|
-
if eof?
|
272
|
-
error l + 1, m + 1, "Premature EOF in #{name}"
|
273
|
-
break
|
274
|
-
end
|
275
|
-
if !eol?
|
276
|
-
match_character_any
|
277
|
-
end
|
278
|
-
end
|
279
|
-
return true
|
280
|
-
end
|
281
|
-
false
|
282
|
-
end
|
283
|
-
|
284
|
-
def match_quotation_(left, right, name)
|
285
|
-
l = @linenum
|
286
|
-
m = column_number
|
287
|
-
if match_string(left)
|
288
|
-
while !match_string(right)
|
289
|
-
if eof?
|
290
|
-
error l + 1, m + 1, "Premature EOF in #{name}"
|
291
|
-
break
|
292
|
-
end
|
293
|
-
if match_character("\\".ord)
|
294
|
-
if !eol?
|
295
|
-
match_character_any
|
296
|
-
end
|
297
|
-
else
|
298
|
-
if eol?
|
299
|
-
error l + 1, m + 1, "Premature EOF in #{name}"
|
300
|
-
break
|
301
|
-
end
|
302
|
-
match_character_any
|
303
|
-
end
|
304
|
-
end
|
305
|
-
return true
|
306
|
-
end
|
307
|
-
false
|
308
|
-
end
|
309
|
-
|
310
|
-
def match_directive_c
|
311
|
-
match_section_line_continuable_("#")
|
312
|
-
end
|
313
|
-
|
314
|
-
def match_comment
|
315
|
-
match_section_line_("#")
|
316
|
-
end
|
317
|
-
|
318
|
-
def match_comment_c
|
319
|
-
match_section_block_("/*", "*/", "C comment")
|
320
|
-
end
|
321
|
-
|
322
|
-
def match_comment_cxx
|
323
|
-
match_section_line_("//")
|
324
|
-
end
|
325
|
-
|
326
|
-
def match_quotation_single
|
327
|
-
match_quotation_("\'", "\'", "single quotation")
|
328
|
-
end
|
329
|
-
|
330
|
-
def match_quotation_double
|
331
|
-
match_quotation_("\"", "\"", "double quotation")
|
332
|
-
end
|
333
|
-
|
334
|
-
def match_character_class
|
335
|
-
match_quotation_("[", "]", "character class")
|
336
|
-
end
|
337
|
-
|
338
|
-
def match_spaces
|
339
|
-
n = 0
|
340
|
-
while match_blank || eol? || match_comment
|
341
|
-
n += 1
|
342
|
-
end
|
343
|
-
n > 0
|
344
|
-
end
|
345
|
-
|
346
|
-
def match_number
|
347
|
-
if match_character_range("0".ord, "9".ord)
|
348
|
-
nil while match_character_range("0".ord, "9".ord)
|
349
|
-
return true
|
350
|
-
end
|
351
|
-
return false
|
352
|
-
end
|
353
|
-
|
354
|
-
def match_identifier
|
355
|
-
if match_character_range("a".ord, "z".ord) || match_character_range("A".ord, "Z".ord) || match_character("_".ord)
|
356
|
-
nil while match_character_range("a".ord, "z".ord) || match_character_range("A".ord, "Z".ord) || match_character_range("0".ord, "9".ord) || match_character("_".ord)
|
357
|
-
return true
|
358
|
-
end
|
359
|
-
false
|
360
|
-
end
|
361
|
-
|
362
|
-
def match_code_block
|
363
|
-
l = @linenum
|
364
|
-
m = column_number
|
365
|
-
if match_character("{".ord)
|
366
|
-
d = 1
|
367
|
-
while true
|
368
|
-
if eof?
|
369
|
-
error l + 1, m + 1, "Premature EOF in code block"
|
370
|
-
break
|
371
|
-
end
|
372
|
-
if match_directive_c || match_comment_c || match_comment_cxx || match_quotation_single || match_quotation_double
|
373
|
-
next
|
374
|
-
end
|
375
|
-
if match_character("{".ord)
|
376
|
-
d += 1
|
377
|
-
elsif match_character("}".ord)
|
378
|
-
d -= 1
|
379
|
-
if d == 0
|
380
|
-
break
|
381
|
-
end
|
382
|
-
else
|
383
|
-
if !eol?
|
384
|
-
if match_character("$".ord)
|
385
|
-
if @lang == :rb
|
386
|
-
@buffer[@bufcur - 1] = "__"
|
387
|
-
else
|
388
|
-
@buffer[@bufcur - 1] = "_"
|
389
|
-
end
|
390
|
-
else
|
391
|
-
match_character_any
|
392
|
-
end
|
393
|
-
end
|
394
|
-
end
|
395
|
-
end
|
396
|
-
return true
|
397
|
-
end
|
398
|
-
return false
|
399
|
-
end
|
400
|
-
|
401
|
-
def match_footer_start
|
402
|
-
match_string("%%")
|
403
|
-
end
|
404
|
-
|
405
101
|
def dump_options
|
406
102
|
$stdout.print <<~EOS
|
407
103
|
value_type: '#{value_type}'
|
@@ -410,517 +106,17 @@ class Packcr
|
|
410
106
|
EOS
|
411
107
|
end
|
412
108
|
|
413
|
-
def rule(name)
|
414
|
-
@rulehash[name]
|
415
|
-
end
|
416
|
-
|
417
|
-
def parse_directive_include(name, *outputs)
|
418
|
-
if !match_string(name)
|
419
|
-
return false
|
420
|
-
end
|
421
|
-
|
422
|
-
match_spaces
|
423
|
-
|
424
|
-
pos = @bufcur
|
425
|
-
l = @linenum
|
426
|
-
m = column_number
|
427
|
-
if match_code_block
|
428
|
-
q = @bufcur
|
429
|
-
match_spaces
|
430
|
-
outputs.each do |output|
|
431
|
-
code = Packcr::CodeBlock.new(@buffer.to_s[pos + 1, q - pos - 2], q - pos - 2, l, m)
|
432
|
-
output.push(code)
|
433
|
-
end
|
434
|
-
else
|
435
|
-
error l + 1, m + 1, "Illegal #{name} syntax"
|
436
|
-
end
|
437
|
-
true
|
438
|
-
end
|
439
|
-
|
440
|
-
def parse_directive_string(name, varname, must_not_be_empty: false, must_not_be_void: false, must_be_identifier: false)
|
441
|
-
l = @linenum
|
442
|
-
m = column_number
|
443
|
-
if !match_string(name)
|
444
|
-
return false
|
445
|
-
end
|
446
|
-
|
447
|
-
match_spaces
|
448
|
-
pos = @bufcur
|
449
|
-
lv = @linenum
|
450
|
-
mv = column_number
|
451
|
-
s = nil
|
452
|
-
if match_quotation_single || match_quotation_double
|
453
|
-
q = @bufcur
|
454
|
-
match_spaces
|
455
|
-
s = @buffer.to_s[pos + 1, q - pos - 2]
|
456
|
-
if !Packcr.unescape_string(s, false)
|
457
|
-
error lv + 1, mv + 1, "Illegal escape sequence"
|
458
|
-
end
|
459
|
-
else
|
460
|
-
error l + 1, m + 1, "Illegal #{name} syntax"
|
461
|
-
end
|
462
|
-
|
463
|
-
if s
|
464
|
-
valid = true
|
465
|
-
s.sub!(/\A\s+/, "")
|
466
|
-
s.sub!(/\s+\z/, "")
|
467
|
-
is_empty = must_not_be_empty && s !~ /[^\s]/
|
468
|
-
if is_empty
|
469
|
-
error lv + 1, mv + 1, "Empty string"
|
470
|
-
vaild = false
|
471
|
-
end
|
472
|
-
if must_not_be_void && s == "void"
|
473
|
-
error lv + 1, mv + 1, "'void' not allowed"
|
474
|
-
vaild = false
|
475
|
-
end
|
476
|
-
if !is_empty && must_be_identifier && !Packcr.is_identifier_string(s)
|
477
|
-
error lv + 1, mv + 1, "Invalid identifier"
|
478
|
-
valid = false
|
479
|
-
end
|
480
|
-
if instance_variable_get(varname) != nil
|
481
|
-
error l + 1, m + 1, "Multiple #{name} definition"
|
482
|
-
valid
|
483
|
-
end
|
484
|
-
if valid
|
485
|
-
instance_variable_set(varname, s)
|
486
|
-
end
|
487
|
-
end
|
488
|
-
return true
|
489
|
-
end
|
490
|
-
|
491
|
-
class StopParsing < StandardError
|
492
|
-
end
|
493
|
-
|
494
|
-
def parse_primary(rule)
|
495
|
-
pos = @bufcur
|
496
|
-
l = @linenum
|
497
|
-
m = column_number
|
498
|
-
n = @charnum
|
499
|
-
o = @linepos
|
500
|
-
if match_identifier
|
501
|
-
q = @bufcur
|
502
|
-
r = s = nil
|
503
|
-
match_spaces
|
504
|
-
if match_character(":".ord)
|
505
|
-
match_spaces
|
506
|
-
r = @bufcur
|
507
|
-
if !match_identifier
|
508
|
-
raise StopParsing
|
509
|
-
end
|
510
|
-
s = @bufcur
|
511
|
-
match_spaces
|
512
|
-
end
|
513
|
-
if match_string("<-")
|
514
|
-
raise StopParsing
|
515
|
-
end
|
516
|
-
|
517
|
-
n_p = Packcr::Node::ReferenceNode.new
|
518
|
-
if r == nil
|
519
|
-
name = @buffer.to_s
|
520
|
-
name = name[pos, q - pos]
|
521
|
-
unless q >= pos
|
522
|
-
raise "Internal error"
|
523
|
-
end
|
524
|
-
n_p.var = nil
|
525
|
-
n_p.index = nil
|
526
|
-
n_p.name = name
|
527
|
-
else
|
528
|
-
var = @buffer.to_s
|
529
|
-
var = var[pos, q - pos]
|
530
|
-
unless s != nil # s should have a valid value when r has a valid value
|
531
|
-
raise "Internal error"
|
532
|
-
end
|
533
|
-
unless q >= pos
|
534
|
-
raise "Internal error"
|
535
|
-
end
|
536
|
-
|
537
|
-
n_p.var = var
|
538
|
-
if var.ord == "_".ord
|
539
|
-
error l + 1, m + 1, "Leading underscore in variable name '#{var}'"
|
540
|
-
end
|
541
|
-
|
542
|
-
i = rule.vars.index do |ref|
|
543
|
-
unless ref.is_a?(Packcr::Node::ReferenceNode)
|
544
|
-
raise "Unexpected node type: #{ref.class}"
|
545
|
-
end
|
546
|
-
var == ref.var
|
547
|
-
end
|
548
|
-
if !i
|
549
|
-
i = rule.vars.length
|
550
|
-
rule.vars << n_p
|
551
|
-
end
|
552
|
-
n_p.index = i
|
553
|
-
unless s >= r
|
554
|
-
raise "Internal error"
|
555
|
-
end
|
556
|
-
|
557
|
-
name = @buffer.to_s
|
558
|
-
name = name[r, s - r]
|
559
|
-
n_p.name = name
|
560
|
-
end
|
561
|
-
n_p.line = l
|
562
|
-
n_p.col = m
|
563
|
-
elsif match_character("(")
|
564
|
-
match_spaces
|
565
|
-
n_p = parse_expression(rule)
|
566
|
-
if !n_p
|
567
|
-
raise StopParsing
|
568
|
-
end
|
569
|
-
if !match_character(")")
|
570
|
-
raise StopParsing
|
571
|
-
end
|
572
|
-
match_spaces
|
573
|
-
elsif match_character("<")
|
574
|
-
capts = rule.capts
|
575
|
-
match_spaces
|
576
|
-
n_p = Packcr::Node::CaptureNode.new
|
577
|
-
n_p.index = capts.length
|
578
|
-
rule.capts << n_p
|
579
|
-
expr = parse_expression(rule)
|
580
|
-
n_p.expr = expr
|
581
|
-
if !expr || !match_character(">")
|
582
|
-
rule.capts = rule.capts[0, n_p.index]
|
583
|
-
raise StopParsing
|
584
|
-
end
|
585
|
-
match_spaces
|
586
|
-
elsif match_character("$")
|
587
|
-
match_spaces
|
588
|
-
pos2 = @bufcur
|
589
|
-
if match_number
|
590
|
-
q = @bufcur
|
591
|
-
s = @buffer.to_s
|
592
|
-
s = s[pos2, q - pos2]
|
593
|
-
match_spaces
|
594
|
-
n_p = Packcr::Node::ExpandNode.new
|
595
|
-
unless q >= pos2
|
596
|
-
raise StopParsing
|
597
|
-
end
|
598
|
-
index = s.to_i
|
599
|
-
n_p.index = index
|
600
|
-
if index == nil
|
601
|
-
error l + 1, m + 1, "Invalid unsigned number '#{s}'"
|
602
|
-
elsif index == 0
|
603
|
-
error l + 1, m + 1, "0 not allowed"
|
604
|
-
elsif s.ord == "0".ord
|
605
|
-
error l + 1, m + 1, "0-prefixed number not allowed"
|
606
|
-
n_p.index = 0
|
607
|
-
end
|
608
|
-
if index > 0 && index != nil
|
609
|
-
n_p.index = index - 1
|
610
|
-
n_p.line = l
|
611
|
-
n_p.col = m
|
612
|
-
end
|
613
|
-
else
|
614
|
-
raise StopParsing
|
615
|
-
end
|
616
|
-
elsif match_character(".")
|
617
|
-
match_spaces
|
618
|
-
n_p = Packcr::Node::CharclassNode.new
|
619
|
-
n_p.value = nil
|
620
|
-
if !@ascii
|
621
|
-
@utf8 = true
|
622
|
-
end
|
623
|
-
elsif match_character_class
|
624
|
-
q = @bufcur
|
625
|
-
charclass = @buffer.to_s
|
626
|
-
charclass = charclass[pos + 1, q - pos - 2]
|
627
|
-
match_spaces
|
628
|
-
n_p = Packcr::Node::CharclassNode.new
|
629
|
-
Packcr.unescape_string(charclass, true)
|
630
|
-
if !@ascii
|
631
|
-
charclass.force_encoding(Encoding::UTF_8)
|
632
|
-
end
|
633
|
-
if !@ascii && !charclass.valid_encoding?
|
634
|
-
error l + 1, m + 1, "Invalid UTF-8 string"
|
635
|
-
end
|
636
|
-
if !@ascii && !charclass.empty?
|
637
|
-
@utf8 = true
|
638
|
-
end
|
639
|
-
n_p.value = charclass
|
640
|
-
elsif match_quotation_single || match_quotation_double
|
641
|
-
q = @bufcur
|
642
|
-
string = @buffer.to_s
|
643
|
-
string = string[pos + 1, q - pos - 2]
|
644
|
-
match_spaces
|
645
|
-
n_p = ::Packcr::Node::StringNode.new
|
646
|
-
Packcr.unescape_string(string, true)
|
647
|
-
if !@ascii
|
648
|
-
string.force_encoding(Encoding::UTF_8)
|
649
|
-
end
|
650
|
-
if !@ascii && !string.valid_encoding?
|
651
|
-
error l + 1, m + 1, "Invalid UTF-8 string"
|
652
|
-
end
|
653
|
-
n_p.value = string
|
654
|
-
elsif match_code_block
|
655
|
-
q = @bufcur
|
656
|
-
text = @buffer.to_s
|
657
|
-
text = text[pos + 1, q - pos - 2]
|
658
|
-
codes = rule.codes
|
659
|
-
match_spaces
|
660
|
-
n_p = Packcr::Node::ActionNode.new
|
661
|
-
n_p.code = Packcr::CodeBlock.new(text, Packcr.find_trailing_blanks(text), l, m)
|
662
|
-
n_p.index = codes.length
|
663
|
-
codes.push(n_p)
|
664
|
-
else
|
665
|
-
raise StopParsing
|
666
|
-
end
|
667
|
-
n_p
|
668
|
-
rescue StopParsing
|
669
|
-
@bufcur = pos
|
670
|
-
@linenum = l
|
671
|
-
@charnum = n
|
672
|
-
@linepos = o
|
673
|
-
return nil
|
674
|
-
end
|
675
|
-
|
676
|
-
def parse_term(rule)
|
677
|
-
pos = @bufcur
|
678
|
-
l = @linenum
|
679
|
-
n = @charnum
|
680
|
-
o = @linepos
|
681
|
-
if match_character("&")
|
682
|
-
t = "&".ord
|
683
|
-
elsif match_character("!")
|
684
|
-
t = "!".ord
|
685
|
-
else
|
686
|
-
t = 0
|
687
|
-
end
|
688
|
-
if t
|
689
|
-
match_spaces
|
690
|
-
end
|
691
|
-
|
692
|
-
n_p = parse_primary(rule)
|
693
|
-
if !n_p
|
694
|
-
raise StopParsing
|
695
|
-
end
|
696
|
-
if match_character("*")
|
697
|
-
match_spaces
|
698
|
-
n_q = Packcr::Node::QuantityNode.new
|
699
|
-
n_q.min = 0
|
700
|
-
n_q.max = -1
|
701
|
-
n_q.expr = n_p
|
702
|
-
elsif match_character("+")
|
703
|
-
match_spaces
|
704
|
-
n_q = Packcr::Node::QuantityNode.new
|
705
|
-
n_q.min = 1
|
706
|
-
n_q.max = -1
|
707
|
-
n_q.expr = n_p
|
708
|
-
elsif match_character("?")
|
709
|
-
match_spaces
|
710
|
-
n_q = Packcr::Node::QuantityNode.new
|
711
|
-
n_q.min = 0
|
712
|
-
n_q.max = 1
|
713
|
-
n_q.expr = n_p
|
714
|
-
else
|
715
|
-
n_q = n_p
|
716
|
-
end
|
717
|
-
|
718
|
-
case t
|
719
|
-
when "&".ord
|
720
|
-
n_r = Packcr::Node::PredicateNode.new
|
721
|
-
n_r.neg = false
|
722
|
-
n_r.expr = n_q
|
723
|
-
when "!".ord
|
724
|
-
n_r = Packcr::Node::PredicateNode.new
|
725
|
-
n_r.neg = true
|
726
|
-
n_r.expr = n_q
|
727
|
-
else
|
728
|
-
n_r = n_q
|
729
|
-
end
|
730
|
-
|
731
|
-
if match_character("~")
|
732
|
-
match_spaces
|
733
|
-
pos2 = @bufcur
|
734
|
-
l2 = @linenum
|
735
|
-
m = column_number
|
736
|
-
if match_code_block
|
737
|
-
q = @bufcur
|
738
|
-
text = @buffer.to_s
|
739
|
-
text = text[pos2 + 1, q - pos2 - 2]
|
740
|
-
match_spaces
|
741
|
-
n_t = Packcr::Node::ErrorNode.new
|
742
|
-
n_t.expr = n_r
|
743
|
-
n_t.code = Packcr::CodeBlock.new(text, Packcr.find_trailing_blanks(text), l2, m);
|
744
|
-
n_t.index = rule.codes.length
|
745
|
-
rule.codes.push(n_t)
|
746
|
-
else
|
747
|
-
raise StopParsing
|
748
|
-
end
|
749
|
-
else
|
750
|
-
n_t = n_r
|
751
|
-
end
|
752
|
-
n_t
|
753
|
-
rescue StopParsing
|
754
|
-
@bufcur = pos
|
755
|
-
@linenum = l
|
756
|
-
@charnum = n
|
757
|
-
@linepos = o
|
758
|
-
return nil
|
759
|
-
end
|
760
|
-
|
761
|
-
def parse_sequence(rule)
|
762
|
-
pos = @bufcur
|
763
|
-
l = @linenum
|
764
|
-
n = @charnum
|
765
|
-
o = @linepos
|
766
|
-
n_t = parse_term(rule)
|
767
|
-
if !n_t
|
768
|
-
raise StopParsing
|
769
|
-
end
|
770
|
-
n_u = parse_term(rule);
|
771
|
-
if n_u
|
772
|
-
n_s = Packcr::Node::SequenceNode.new
|
773
|
-
n_s.nodes << n_t
|
774
|
-
n_s.nodes << n_u
|
775
|
-
while (n_t = parse_term(rule))
|
776
|
-
n_s.nodes << n_t
|
777
|
-
end
|
778
|
-
else
|
779
|
-
n_s = n_t
|
780
|
-
end
|
781
|
-
n_s
|
782
|
-
rescue StopParsing
|
783
|
-
@bufcur = pos
|
784
|
-
@linenum = l
|
785
|
-
@charnum = n
|
786
|
-
@linepos = o
|
787
|
-
return nil
|
788
|
-
end
|
789
|
-
|
790
|
-
def parse_expression(rule)
|
791
|
-
pos = @bufcur
|
792
|
-
l = @linenum
|
793
|
-
n = @charnum
|
794
|
-
o = @linepos
|
795
|
-
n_s = parse_sequence(rule)
|
796
|
-
if !n_s
|
797
|
-
raise StopParsing
|
798
|
-
end
|
799
|
-
q = @bufcur
|
800
|
-
if (match_character("/".ord))
|
801
|
-
@bufcur = q
|
802
|
-
n_e = Packcr::Node::AlternateNode.new
|
803
|
-
n_e.nodes << n_s
|
804
|
-
while match_character("/".ord)
|
805
|
-
match_spaces
|
806
|
-
n_s = parse_sequence(rule)
|
807
|
-
if !n_s
|
808
|
-
raise StopParsing
|
809
|
-
end
|
810
|
-
n_e.nodes << n_s
|
811
|
-
end
|
812
|
-
else
|
813
|
-
n_e = n_s
|
814
|
-
end
|
815
|
-
return n_e
|
816
|
-
rescue StopParsing
|
817
|
-
@bufcur = pos
|
818
|
-
@linenum = l
|
819
|
-
@charnum = n
|
820
|
-
@linepos = o
|
821
|
-
return nil
|
822
|
-
end
|
823
|
-
|
824
|
-
def parse_rule
|
825
|
-
pos = @bufcur
|
826
|
-
l = @linenum
|
827
|
-
m = column_number
|
828
|
-
n = @charnum
|
829
|
-
o = @linepos
|
830
|
-
if !match_identifier
|
831
|
-
raise StopParsing
|
832
|
-
end
|
833
|
-
|
834
|
-
q = @bufcur
|
835
|
-
match_spaces
|
836
|
-
if !match_string("<-")
|
837
|
-
raise StopParsing
|
838
|
-
end
|
839
|
-
match_spaces
|
840
|
-
|
841
|
-
n_r = Packcr::Node::RuleNode.new
|
842
|
-
expr = parse_expression(n_r)
|
843
|
-
n_r.expr = expr
|
844
|
-
if !expr
|
845
|
-
raise StopParsing
|
846
|
-
end
|
847
|
-
unless q >= pos
|
848
|
-
raise "Internal error"
|
849
|
-
end
|
850
|
-
name = @buffer.to_s
|
851
|
-
name = name[pos, q - pos]
|
852
|
-
n_r.name = name
|
853
|
-
n_r.line = l
|
854
|
-
n_r.col = m
|
855
|
-
n_r
|
856
|
-
rescue StopParsing
|
857
|
-
@bufcur = pos
|
858
|
-
@linenum = l
|
859
|
-
@charnum = n
|
860
|
-
@linepos = o
|
861
|
-
return nil
|
862
|
-
end
|
863
|
-
|
864
109
|
def parse
|
865
|
-
|
866
|
-
|
867
|
-
b = true
|
868
|
-
while true
|
869
|
-
if eof? || match_footer_start
|
870
|
-
break
|
871
|
-
end
|
872
|
-
if (
|
873
|
-
parse_directive_include("%earlysource", @esource) ||
|
874
|
-
parse_directive_include("%earlycommon", @esource, @eheader) ||
|
875
|
-
parse_directive_include("%source", @source) ||
|
876
|
-
parse_directive_include("%lateheader", @lheader) ||
|
877
|
-
parse_directive_include("%header", @header) ||
|
878
|
-
parse_directive_include("%common", @source, @header) ||
|
879
|
-
parse_directive_include("%location", @location) ||
|
880
|
-
parse_directive_string("%value", "@value_type", must_not_be_empty: true, must_not_be_void: true) ||
|
881
|
-
parse_directive_string("%auxil", "@auxil_type", must_not_be_empty: true, must_not_be_void: true) ||
|
882
|
-
parse_directive_string("%prefix", "@prefix", must_not_be_empty: true, must_be_identifier: true)
|
883
|
-
)
|
884
|
-
b = true
|
885
|
-
elsif match_character("%")
|
886
|
-
l = @linenum
|
887
|
-
m = column_number
|
888
|
-
error l + 1, m + 1, "Invalid directive"
|
889
|
-
match_identifier
|
890
|
-
match_spaces
|
891
|
-
b = true
|
892
|
-
else
|
893
|
-
l = @linenum
|
894
|
-
m = column_number
|
895
|
-
n = @charnum
|
896
|
-
o = @linepos
|
897
|
-
node = parse_rule
|
898
|
-
if node == nil
|
899
|
-
if b
|
900
|
-
error l + 1, m + 1, "Illegal rule syntax"
|
901
|
-
b = false
|
902
|
-
end
|
903
|
-
@linenum = l
|
904
|
-
@charnum = n
|
905
|
-
@linepos = o
|
906
|
-
if !match_identifier && !match_spaces
|
907
|
-
match_character_any
|
908
|
-
end
|
909
|
-
else
|
910
|
-
@rules.push(node)
|
911
|
-
b = true
|
912
|
-
end
|
913
|
-
end
|
914
|
-
commit_buffer
|
915
|
-
end
|
110
|
+
$stdin = @ifile
|
111
|
+
nil while super
|
916
112
|
|
917
113
|
if @location.empty?
|
918
114
|
@location = nil
|
919
115
|
end
|
920
|
-
commit_buffer
|
921
116
|
|
922
117
|
make_rulehash
|
923
118
|
@rules.each do |rule|
|
119
|
+
rule.setup
|
924
120
|
rule.expr.link_references(self)
|
925
121
|
end
|
926
122
|
@rules[1..-1]&.each do |rule|
|
@@ -956,19 +152,6 @@ class Packcr
|
|
956
152
|
sstream = ::Packcr::Stream.new(sio, @sname, @lines ? 0 : nil)
|
957
153
|
|
958
154
|
sstream.write Packcr.template("context/source.#{@lang}.erb", binding), rewrite_line_directive: true
|
959
|
-
|
960
|
-
eol?
|
961
|
-
if !eof?
|
962
|
-
sstream.write("\n")
|
963
|
-
end
|
964
|
-
commit_buffer
|
965
|
-
if @lines && !eof?
|
966
|
-
sstream.write_line_directive(@iname, @linenum)
|
967
|
-
end
|
968
|
-
while refill_buffer > 0
|
969
|
-
write_buffer(sstream)
|
970
|
-
commit_buffer
|
971
|
-
end
|
972
155
|
end
|
973
156
|
|
974
157
|
if !@errnum.zero?
|
@@ -979,4 +162,4 @@ class Packcr
|
|
979
162
|
true
|
980
163
|
end
|
981
164
|
end
|
982
|
-
end
|
165
|
+
end
|