depager 0.1.9 → 0.2.0
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/bin/depager +1 -0
- data/data/depager/misc/depager-mode.el +35 -24
- data/data/depager/pre-setup.rb +3 -0
- data/examples/Rakefile +36 -0
- data/examples/c89/c89.dr +496 -0
- data/examples/c89/c89.tab.rb +2197 -0
- data/examples/c89/test.c89 +10 -0
- data/{data/depager/sample → examples}/extension/paction.dr +0 -0
- data/{data/depager/sample → examples}/extension/pactiontest.dr +0 -0
- data/{data/depager/sample → examples}/pl0d/pl0ds.dr +0 -0
- data/examples/pl0d/pl0ds.tab.rb +1702 -0
- data/{data/depager/sample/pl0d/pl0test.pl0 → examples/pl0d/test.pl0ds} +0 -0
- data/{data/depager/sample → examples}/sample_calc/calc.action.dr +0 -0
- data/examples/sample_calc/calc.action.tab.rb +283 -0
- data/{data/depager/sample → examples}/sample_calc/calc.astdf.dr +0 -0
- data/examples/sample_calc/calc.astdf.tab.rb +476 -0
- data/{data/depager/sample → examples}/sample_calc/calc.astl.action.dr +0 -0
- data/examples/sample_calc/calc.astl.action.tab.rb +593 -0
- data/{data/depager/sample → examples}/sample_calc/calc.astl.dr +0 -0
- data/examples/sample_calc/calc.astl.tab.rb +501 -0
- data/{data/depager/sample → examples}/sample_calc/calc.atree.dr +0 -0
- data/examples/sample_calc/calc.atree.tab.rb +277 -0
- data/{data/depager/sample → examples}/sample_calc/calc.cst.dr +0 -0
- data/examples/sample_calc/calc.cst.tab.rb +478 -0
- data/{data/depager/sample → examples}/sample_calc/calc.dr +0 -0
- data/{data/depager/sample → examples}/sample_calc/calc.lex.dr +0 -0
- data/examples/sample_calc/calc.lex.tab.rb +192 -0
- data/{data/depager/sample → examples}/sample_calc/calc.nvaction.dr +0 -0
- data/examples/sample_calc/calc.nvaction.tab.rb +291 -0
- data/examples/sample_calc/calc.tab.rb +183 -0
- data/{data/depager/sample → examples}/sample_calc/calc_prec.nvaction.dr +0 -0
- data/examples/sample_calc/calc_prec.nvaction.tab.rb +257 -0
- data/examples/sample_calc/test.calc +1 -0
- data/{data/depager/sample/slex_test/slextest1.dr → examples/slex_test/divreg.slex.dr} +3 -11
- data/examples/slex_test/divreg.slex.tab.rb +227 -0
- data/{data/depager/sample/slex_test/slextest2.dr → examples/slex_test/ljoin.slex.dr} +10 -7
- data/examples/slex_test/ljoin.slex.tab.rb +277 -0
- data/examples/slex_test/test.divreg +1 -0
- data/examples/slex_test/test.ljoin +3 -0
- data/lib/depager.rb +194 -127
- data/lib/depager/Rakefile +8 -4
- data/lib/depager/ast_base.dr +3 -3
- data/lib/depager/ast_base.rb +197 -144
- data/lib/depager/atree.rb +55 -36
- data/lib/depager/cst.dr +6 -4
- data/lib/depager/cst.rb +69 -49
- data/lib/depager/grammar.rb +136 -0
- data/lib/depager/lex.dr +22 -8
- data/lib/depager/lex.rb +94 -53
- data/lib/depager/lr.rb +101 -167
- data/lib/depager/parse_action.rb +1 -1
- data/lib/depager/parser.rb +34 -7
- data/lib/depager/slex.dr +76 -36
- data/lib/depager/slex.rb +345 -151
- data/lib/depager/srp.rb +3 -2
- data/lib/depager/template/extension_lalr_slave.erb +1 -1
- data/lib/depager/template/single_lalr_parser.erb +1 -1
- data/lib/depager/utils.rb +2 -1
- data/lib/depager/version.rb +2 -2
- metadata +42 -28
- data/Manifest.txt +0 -52
- data/lib/depager/psrtmpl.rb +0 -33
data/lib/depager/lr.rb
CHANGED
@@ -1,31 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@
|
9
|
-
@
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
1
|
+
require 'pp'
|
2
|
+
require 'depager/grammar.rb'
|
3
|
+
module Depager::LALR
|
4
|
+
class SingleParserGenerator < Simple::SingleGenerator
|
5
|
+
Tmplfile = 'single_lalr_parser.erb'
|
6
|
+
def initialize d_parser
|
7
|
+
super
|
8
|
+
@parsing_method = LALR
|
9
|
+
@basis_name = @d_parser.target_name + '.new()'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class ExtensionParserGenerator < Simple::ExtensionGenerator
|
14
|
+
TmplfileMaster = "#{Tmpldir}/extension_lalr_master.erb"
|
15
|
+
TmplfileSlave = "#{Tmpldir}/extension_lalr_slave.erb"
|
16
|
+
def initialize d_parser
|
17
|
+
super
|
18
|
+
@parsing_method = LALR
|
19
|
+
@basis_name = 'self'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Eps = Depager::ParsingMethodCommon::G::Eps
|
24
|
+
class Grammar < Depager::ParsingMethodCommon::G
|
25
|
+
attr_accessor :closure, :memo_closure1
|
26
|
+
def initialize_depend
|
27
27
|
make_sym_f0e
|
28
28
|
@closure = {}
|
29
|
+
@memo_closure1 = {}
|
29
30
|
end
|
30
31
|
|
31
32
|
def make_sym_f0e
|
@@ -60,127 +61,46 @@ module Depager
|
|
60
61
|
end
|
61
62
|
end while cnt
|
62
63
|
end
|
63
|
-
|
64
|
-
def make_sym_first
|
65
|
-
@first1 = {@tla => [@tla]}
|
66
|
-
@syms.each_key do |s|
|
67
|
-
if terms? s
|
68
|
-
@first1[s] = [s]
|
69
|
-
else
|
70
|
-
@first1[s] = []
|
71
|
-
@first1[s].push Eps if @epr[s]
|
72
|
-
end
|
73
|
-
end
|
74
|
-
begin
|
75
|
-
cnt = false
|
76
|
-
@syms.each_key do |s|
|
77
|
-
@gh[s].each do |rule|
|
78
|
-
rule.r.each do |es|
|
79
|
-
ss = @first1[es] - @first1[s]
|
80
|
-
unless ss.empty?
|
81
|
-
@first1[s] |= ss
|
82
|
-
cnt = true
|
83
|
-
end
|
84
|
-
break unless @first1[es].include? Eps
|
85
|
-
end
|
86
|
-
unless @first1[s].include? Eps
|
87
|
-
if rule.r.all?{|i| @first1[i].include? Eps }
|
88
|
-
@first1.push Eps
|
89
|
-
cnt = true
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end if nonterms? s
|
93
|
-
end
|
94
|
-
end while cnt
|
95
|
-
end
|
96
|
-
|
97
|
-
def first p
|
98
|
-
r = []
|
99
|
-
x = 0
|
100
|
-
p.each do |i|
|
101
|
-
if i == Eps
|
102
|
-
elsif i.class == Array
|
103
|
-
i.each do |j|
|
104
|
-
r |= @first1[j]
|
105
|
-
end
|
106
|
-
break unless i.any?{|j| @epr[j] || j==Eps }
|
107
|
-
else
|
108
|
-
r |= @first1[i]
|
109
|
-
break unless @epr[i]
|
110
|
-
end
|
111
|
-
x += 1
|
112
|
-
end
|
113
|
-
r -= [Eps]
|
114
|
-
r |= [Eps] if x == p.size
|
115
|
-
return r
|
116
|
-
end
|
117
|
-
|
118
|
-
def terms? i
|
119
|
-
i && i >= @nssize
|
120
|
-
end
|
121
|
-
|
122
|
-
def nonterms? i
|
123
|
-
i && i < @nssize
|
124
|
-
end
|
125
|
-
|
126
|
-
def [](n)
|
127
|
-
@rulelist[n]
|
128
|
-
end
|
129
64
|
end
|
130
|
-
|
131
|
-
|
132
|
-
attr_accessor :l, :r, :g, :n, :act, :epr, :prec
|
133
|
-
def initialize l, r, g = nil, n = nil, act = nil, prec = nil
|
134
|
-
@l = l
|
135
|
-
@r = r
|
136
|
-
@g = g
|
137
|
-
@n = n
|
138
|
-
@act = act
|
139
|
-
@epr = []
|
140
|
-
@prec = prec
|
141
|
-
end
|
142
|
-
def self.[] l, r, prec = nil
|
143
|
-
Rule.new l, r, nil, nil, nil, prec
|
144
|
-
end
|
145
|
-
|
146
|
-
def to_s
|
147
|
-
r = @r.map{|i| @g.syms[i]}.join(' ')
|
148
|
-
"(#{'%03s'%@n}) #{@g.syms[@l]} : #{r}"
|
65
|
+
class Rule < Depager::ParsingMethodCommon::Rule
|
66
|
+
def initialize_depend
|
149
67
|
end
|
150
|
-
|
151
|
-
def hash
|
152
|
-
(@l.hash % 37) * (@r.hash % 37)
|
153
|
-
end
|
154
|
-
def eql? i
|
155
|
-
@l == i.l && @r == i.r
|
156
|
-
end
|
157
|
-
alias == eql?
|
158
|
-
|
159
68
|
def closure1 n, la
|
160
|
-
|
161
|
-
|
162
|
-
|
69
|
+
key = [self.n, n, la]
|
70
|
+
return @g.memo_closure1[key] if @g.memo_closure1[key]
|
71
|
+
_G = @g
|
72
|
+
_I = [ LRItem[self, n, la] ]
|
73
|
+
memo = { _I[0].rule.n => _I[0] }
|
74
|
+
_I.each do |_IA|
|
75
|
+
_B, beta = _IA.dotsym, _IA.dotrest
|
76
|
+
next if !_B or !_G.gh[_B]
|
77
|
+
|
78
|
+
b = _G.first(beta)
|
79
|
+
if b.include? Eps
|
80
|
+
b.delete(Eps)
|
81
|
+
b |= _IA.la
|
82
|
+
end
|
163
83
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
li
|
172
|
-
|
173
|
-
|
174
|
-
else
|
175
|
-
li.la = @g.first(b + [ji.la])
|
176
|
-
j << li
|
177
|
-
h[li] = j.size-1
|
84
|
+
_G.gh[_B].each do |_Brule|
|
85
|
+
if li = memo[_Brule.n]
|
86
|
+
#warn "= #{li} ;"+
|
87
|
+
# " [#{(beta+[a]).map{|i| @g.syms[i] || '$' }}]"+
|
88
|
+
# " :: #{b.map{|i| @g.syms[i] }}"
|
89
|
+
s0 = li.la.size
|
90
|
+
li.la |= b
|
91
|
+
if li.la.size > s0 # (b - li.la).empty?
|
92
|
+
_I << li
|
93
|
+
# warn "! #{b.map{|i| @g.syms[i]}}; #{li}"
|
178
94
|
end
|
95
|
+
else
|
96
|
+
li = memo[_Brule.n] = LRItem[_Brule, 0, b]
|
97
|
+
_I << li
|
98
|
+
# warn "+ #{memo[_Brule.n]}"
|
179
99
|
end
|
180
100
|
end
|
181
|
-
i += 1
|
182
101
|
end
|
183
|
-
|
102
|
+
@g.memo_closure1[key] = _I
|
103
|
+
_I
|
184
104
|
end
|
185
105
|
|
186
106
|
def closure n, base=nil
|
@@ -249,6 +169,12 @@ module Depager
|
|
249
169
|
@goto[x] = I[]
|
250
170
|
end
|
251
171
|
end
|
172
|
+
def dotsym
|
173
|
+
@rule.r[@n]
|
174
|
+
end
|
175
|
+
def dotrest
|
176
|
+
@rule.r[@n+1 .. -1]
|
177
|
+
end
|
252
178
|
end
|
253
179
|
|
254
180
|
class I
|
@@ -309,13 +235,14 @@ module Depager
|
|
309
235
|
end
|
310
236
|
end
|
311
237
|
|
312
|
-
class
|
238
|
+
class Table
|
313
239
|
attr_accessor :g, :action_table, :goto_table
|
314
240
|
attr_accessor :defred_table, :defred_after_shift_table
|
315
241
|
def initialize g
|
316
242
|
@g = g
|
317
243
|
@c = nil
|
318
|
-
|
244
|
+
@warnings = []
|
245
|
+
|
319
246
|
items
|
320
247
|
mkset
|
321
248
|
mktable
|
@@ -378,7 +305,7 @@ module Depager
|
|
378
305
|
def checkconf newv, oldv, key, g = nil
|
379
306
|
return newv unless oldv
|
380
307
|
if oldv == 'ACC'
|
381
|
-
|
308
|
+
@warnings << "'ACC' conflict #{g}."
|
382
309
|
return oldv
|
383
310
|
end
|
384
311
|
# warn "\n-- N:#{newv} O:#{oldv} K:#{@g.syms[key]} "
|
@@ -392,7 +319,7 @@ module Depager
|
|
392
319
|
# warn "+:reduce #{@g[-newv]}"
|
393
320
|
newv
|
394
321
|
else
|
395
|
-
|
322
|
+
@warnings << "shift/reduce conflict '#{@g.syms[key]}'\n#{g}."
|
396
323
|
oldv
|
397
324
|
end
|
398
325
|
elsif newv > 0 and oldv < 0
|
@@ -404,7 +331,7 @@ module Depager
|
|
404
331
|
# warn "reduce"
|
405
332
|
oldv
|
406
333
|
else
|
407
|
-
|
334
|
+
@warnings << "shift/reduce conflict\n#{g}."
|
408
335
|
newv
|
409
336
|
end
|
410
337
|
elsif newv < 0 and oldv < 0
|
@@ -412,7 +339,7 @@ module Depager
|
|
412
339
|
warn "?? newv == oldv == #{newv}."
|
413
340
|
newv
|
414
341
|
else
|
415
|
-
|
342
|
+
@warnings << "reduce/reduce conflict\n#{g}."
|
416
343
|
newv
|
417
344
|
end
|
418
345
|
else
|
@@ -494,6 +421,10 @@ module Depager
|
|
494
421
|
put_table if $DEBUG
|
495
422
|
end
|
496
423
|
|
424
|
+
def check_table dp
|
425
|
+
@warnings.each{|i| dp.warning i }
|
426
|
+
end
|
427
|
+
|
497
428
|
def put_table
|
498
429
|
syms, first1, f0e, rulelist = @g.syms, @g.first1, @g.f0e, @g.rulelist
|
499
430
|
|
@@ -501,14 +432,14 @@ module Depager
|
|
501
432
|
|
502
433
|
f_ = first1.map {|k, v|
|
503
434
|
"#{syms[k]} => " << v.map{|i|
|
504
|
-
i ==
|
435
|
+
i == Eps ? ':eps' : syms[i]
|
505
436
|
}.join(' ')
|
506
437
|
}.join("\n")
|
507
438
|
|
508
439
|
e = f0e.map {|k, v|
|
509
440
|
"#{syms[k].inspect} => " << v.map{|n, f|
|
510
441
|
" #{rulelist[n]} ? " << f.map{|i|
|
511
|
-
i ==
|
442
|
+
i == Eps ? ':eps' : syms[i].inspect
|
512
443
|
}.join(' ')
|
513
444
|
}.join("\n")
|
514
445
|
}.join("\n")
|
@@ -546,10 +477,16 @@ module Depager
|
|
546
477
|
g << "\n"
|
547
478
|
}
|
548
479
|
|
480
|
+
gh = ""
|
481
|
+
@g.gh.each_with_index{|i, x|
|
482
|
+
gh << "#{syms[x]}(#{x}) => #{i}\n"
|
483
|
+
}
|
484
|
+
|
549
485
|
warn "** SYMS **\n\n#{s}\n\n" <<
|
550
486
|
"** FIRST1 **\n\n#{f_}\n\n" <<
|
551
487
|
"** Eps Reduce Rule **\n\n#{e}\n\n" <<
|
552
488
|
"*** Grammar ***\n\n#{r}\n\n" <<
|
489
|
+
"** GH **\n\n#{gh}\n\n" <<
|
553
490
|
"*** States ***\n\n#{c}\n\n" <<
|
554
491
|
"*** Action Table ***\n\n#{a}\n" <<
|
555
492
|
"*** Goto Table ***\n\n#{g}\n"
|
@@ -558,39 +495,36 @@ module Depager
|
|
558
495
|
def mkset
|
559
496
|
warn '** cal LA **' if $MP_DEBUG
|
560
497
|
trn = []
|
561
|
-
@c.each do |
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
if
|
566
|
-
|
567
|
-
if
|
568
|
-
i.la
|
569
|
-
|
570
|
-
|
571
|
-
end
|
572
|
-
elsif ai == @g.tla
|
573
|
-
ci.goto(j.rule.r[j.n]).items.each do |i|
|
574
|
-
if i.rule == j.rule && i.n == j.n+1
|
575
|
-
trn.push [k, i]
|
576
|
-
break
|
498
|
+
@c.each do |_K|
|
499
|
+
_K.items.each do |_B|
|
500
|
+
_B.closure1([@g.tla]).each do |_A|
|
501
|
+
_K.goto(_A.dotsym).items.each do |i|
|
502
|
+
if i.rule == _A.rule and i.n == _A.n+1
|
503
|
+
_A.la.each do |a|
|
504
|
+
if a != @g.tla
|
505
|
+
i.la << a unless i.la.include?(a)
|
506
|
+
else
|
507
|
+
trn.push [_B, i, _K, _K.goto(_A.dotsym)]
|
577
508
|
end
|
578
509
|
end
|
510
|
+
break
|
579
511
|
end
|
580
512
|
end
|
581
513
|
end
|
582
514
|
end
|
583
515
|
end
|
584
516
|
|
517
|
+
#puts @g.closure.values.join("\n")
|
518
|
+
#puts "-----"
|
519
|
+
#puts @g.memo_closure1.sort_by{|k,v| k}.map{|k,v| "#{k.inspect}:\n#{v.join("\n")}"}
|
585
520
|
#puts 'mk'; mk.each{|k, v| p "#{k}=>#{v}"}
|
586
|
-
#
|
587
|
-
#
|
588
|
-
|
521
|
+
#trn = trn.uniq
|
522
|
+
#puts 'trn',trn.map{|a| "<#{a[2].n}>#{a[0]} => <#{a[3].n}>#{a[1]}"}
|
589
523
|
warn '** mk LALR(1) **' if $MP_DEBUG
|
590
524
|
@c[0].items[0].la = [@g.nssize] # '$'
|
591
525
|
begin
|
592
526
|
change = false
|
593
|
-
trn.each do |k, v|
|
527
|
+
trn.each do |k, v, _|
|
594
528
|
k.la.each do |i|
|
595
529
|
unless v.la.include? i
|
596
530
|
change = true
|
data/lib/depager/parse_action.rb
CHANGED
data/lib/depager/parser.rb
CHANGED
@@ -1,11 +1,38 @@
|
|
1
1
|
require "depager/utils.rb"
|
2
|
-
module Depager
|
3
|
-
#
|
4
|
-
# Token
|
5
|
-
#
|
6
|
-
Token = Struct.new(:value, :lineno, :filename)
|
7
2
|
|
8
|
-
|
3
|
+
#
|
4
|
+
# Token
|
5
|
+
#
|
6
|
+
class Depager::Token
|
7
|
+
def self.[] *args
|
8
|
+
self.new(*args)
|
9
|
+
end
|
10
|
+
attr_accessor :value, :lineno, :filename
|
11
|
+
def initialize value, lineno=nil, filename=nil
|
12
|
+
@value = value
|
13
|
+
@lineno = lineno
|
14
|
+
@filename = filename
|
15
|
+
end
|
16
|
+
def [](n)
|
17
|
+
case n
|
18
|
+
when 0 ; @value
|
19
|
+
when 1 ; @lineno
|
20
|
+
when 2 ; @filename
|
21
|
+
else ; nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
def to_s
|
25
|
+
"#{@value.inspect}:#{@lineno}@#{@filename}"
|
26
|
+
end
|
27
|
+
def inspect
|
28
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)}" <<
|
29
|
+
" #{@value.inspect}:#{@lineno}@#{@filename}>"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# LALR runtime
|
34
|
+
module Depager::LALR
|
35
|
+
# = Parser runtime
|
9
36
|
# == Stack
|
10
37
|
# s:: state
|
11
38
|
# la:: look ahead
|
@@ -107,7 +134,7 @@ module Depager
|
|
107
134
|
|
108
135
|
def _Token sym, val=nil, lineno=nil
|
109
136
|
lineno ||= file.lineno
|
110
|
-
return sym, Token[val, lineno, file.path]
|
137
|
+
return sym, Depager::Token[val, lineno, file.path]
|
111
138
|
end
|
112
139
|
|
113
140
|
public
|
data/lib/depager/slex.dr
CHANGED
@@ -25,30 +25,45 @@
|
|
25
25
|
def postRhs
|
26
26
|
j = 0
|
27
27
|
rhs = g_parser.rhs
|
28
|
-
@ins.each do |i,
|
28
|
+
@ins.each do |i, option_list, debug|
|
29
29
|
state_name = "#{lhs_name}_#{nrhs}_#{i}"
|
30
|
+
m_name = "_lex_#{state_name}"
|
30
31
|
if i != rhs.size
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@addition << [
|
32
|
+
nt_name = "__#{state_name}__"
|
33
|
+
isym = g_parser.add_nonterm(nt_name)
|
34
|
+
g_parser.rhs_insert_sym(i+j, isym, nt_name)
|
35
|
+
@addition << [ isym, m_name ]
|
35
36
|
j += 1
|
36
37
|
else
|
37
|
-
@on_reduce[nrules] =
|
38
|
+
@on_reduce[nrules] = ':'+m_name
|
39
|
+
end
|
40
|
+
|
41
|
+
codes = option_list.map do |k, m|
|
42
|
+
case k
|
43
|
+
when :GOTO
|
44
|
+
"@basis.lex_state = #{m}" <<
|
45
|
+
(debug ? ";warn 'MODE:->#{m}'" : '')
|
46
|
+
when :ADD
|
47
|
+
"@basis.lex_context[#{m}] = true" <<
|
48
|
+
(debug ? ";warn 'CONTEXT:+#{m}/\#{@context.inspect}'" : '')
|
49
|
+
when :SUB
|
50
|
+
"@basis.lex_context.delete #{m}" <<
|
51
|
+
(debug ? ";warn 'CONTEXT:-#{m}'/\#{@context.inspect}" : '')
|
52
|
+
else
|
53
|
+
end
|
38
54
|
end
|
39
55
|
@optouter.push << %{
|
40
|
-
def
|
41
|
-
|
56
|
+
def #{m_name} val
|
57
|
+
#{codes.join("\n ")}
|
42
58
|
end
|
43
59
|
}
|
44
60
|
end
|
45
61
|
@ins.clear
|
46
62
|
end
|
47
63
|
def postRhsList
|
48
|
-
@addition.each do |
|
49
|
-
g_parser.
|
50
|
-
|
51
|
-
@on_reduce[nrules] = val
|
64
|
+
@addition.each do |isym, m_name|
|
65
|
+
g_parser.add_rule isym, []
|
66
|
+
@on_reduce[nrules] = ':'+m_name
|
52
67
|
end
|
53
68
|
@addition.clear
|
54
69
|
end
|
@@ -63,10 +78,18 @@
|
|
63
78
|
%LEX{
|
64
79
|
/\s+/, /#.*\Z/ { }
|
65
80
|
/[A-Z]+/ { yield _Token(:ID, $&) }
|
66
|
-
/\%\}\s*\Z/ {
|
67
|
-
/\/(([^\/\\]+|\\.)*)
|
68
|
-
/'([^'\\]+|\\.)
|
69
|
-
|
81
|
+
/\%\}\s*\Z/ { yield nil,nil }
|
82
|
+
/\/(([^\/\\]+|\\.)*)\// { yield _Token(:LEX, "/\\A#{$1}/") }
|
83
|
+
/'([^'\\]+|\\.)*'/,
|
84
|
+
/"([^"\\]+|\\.)*"/
|
85
|
+
{
|
86
|
+
yield _Token(:LEX, "/\\A#{Regexp.escape($1).gsub('/', '\/')}/")
|
87
|
+
}
|
88
|
+
'{' !
|
89
|
+
{
|
90
|
+
_lineno = lineno
|
91
|
+
yield _Token(:ACTION, parse_action, _lineno)
|
92
|
+
}
|
70
93
|
/./ { yield _Token($&, $&) }
|
71
94
|
%}
|
72
95
|
#begin-rule
|
@@ -75,32 +98,31 @@
|
|
75
98
|
{
|
76
99
|
ll = ''
|
77
100
|
_mode_list.each do |m, s, l|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
101
|
+
else_code = if s
|
102
|
+
"lex_#{s}(&block)"
|
103
|
+
else
|
104
|
+
'raise RuntimeError, "must not happen #{@line}"'
|
105
|
+
end
|
83
106
|
ll << %{
|
84
107
|
def lex_#{m}(&block)
|
85
|
-
_rest = ''
|
86
108
|
case @line
|
87
109
|
#{l.map{|i| ' '*4+i}}
|
88
110
|
else
|
89
|
-
#{
|
111
|
+
#{else_code}
|
90
112
|
end
|
91
|
-
return _rest
|
92
113
|
end
|
93
114
|
}; #code
|
94
115
|
end
|
95
116
|
g_parser.optinner << ll << %{
|
96
|
-
attr_accessor :lex_state
|
117
|
+
attr_accessor :lex_state, :lex_context
|
97
118
|
def lex(&block)
|
98
|
-
@lex_state
|
119
|
+
@lex_state ||= :START
|
120
|
+
@lex_context ||= {}
|
99
121
|
begin
|
100
122
|
until @line.empty?
|
101
|
-
|
123
|
+
self.send "lex_\#{@lex_state}", &block
|
102
124
|
end
|
103
|
-
end while @line = getline
|
125
|
+
end while @line0 = @line = getline
|
104
126
|
yield nil, nil
|
105
127
|
end
|
106
128
|
}; #code
|
@@ -122,15 +144,19 @@
|
|
122
144
|
| lexactlist lexact { _lexactlist << _lexact }
|
123
145
|
;
|
124
146
|
lexact:
|
125
|
-
lexlist ACTION
|
147
|
+
lexlist opt_noskip ACTION
|
126
148
|
{
|
127
149
|
%{
|
128
150
|
when #{_lexlist.join(', ')}
|
129
|
-
|
151
|
+
#{ _opt_noskip ? '#' : "@oldline = @line; @line = $'" }
|
130
152
|
#{ _ACTION.value }
|
131
153
|
}; #code
|
132
154
|
}
|
133
155
|
;
|
156
|
+
opt_noskip:
|
157
|
+
{ false }
|
158
|
+
| '!' { true }
|
159
|
+
;
|
134
160
|
lexlist:
|
135
161
|
LEX { [ _LEX.value ] }
|
136
162
|
| lexlist ',' LEX { _lexlist.push _LEX }
|
@@ -144,18 +170,32 @@
|
|
144
170
|
%banner '[> ...]'
|
145
171
|
%%
|
146
172
|
%LEX{
|
147
|
-
/\s+/
|
148
|
-
/:[a-zA-Z_]
|
149
|
-
/\]/
|
150
|
-
/./
|
173
|
+
/\s+/ { }
|
174
|
+
/:[a-zA-Z_]+\??/ { yield _Token(:SYMBOL, $&) }
|
175
|
+
/\]/ { yield _Token($&, $&); @line = $'; yield nil, nil }
|
176
|
+
/./ { yield _Token($&, $&) }
|
151
177
|
%}
|
152
178
|
|
153
179
|
#begin-rule
|
154
180
|
start:
|
155
|
-
'['
|
181
|
+
'[' option_list ']'
|
156
182
|
{
|
157
|
-
master.ins.push [g_parser.rhs.size,
|
183
|
+
master.ins.push [g_parser.rhs.size, _option_list, false]
|
158
184
|
}
|
185
|
+
| '[' option_list '?' ']'
|
186
|
+
{
|
187
|
+
master.ins.push [g_parser.rhs.size, _option_list, true]
|
188
|
+
}
|
189
|
+
|
190
|
+
;
|
191
|
+
option_list:
|
192
|
+
option { [_option] }
|
193
|
+
| option_list option { _option_list << _option }
|
194
|
+
;
|
195
|
+
option:
|
196
|
+
'>' SYMBOL { [:GOTO, _SYMBOL.value] }
|
197
|
+
| '+' SYMBOL { [:ADD, _SYMBOL.value] }
|
198
|
+
| '-' SYMBOL { [:SUB, _SYMBOL.value] }
|
159
199
|
;
|
160
200
|
#end-rule
|
161
201
|
%%
|