depager 0.2.0 → 0.2.2
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/README.en +5 -10
- data/bin/depager +17 -20
- data/examples/c89/c89.tab.rb +5632 -702
- data/examples/pl0d/pl0ds.dr +41 -41
- data/examples/pl0d/pl0ds.tab.rb +1887 -874
- data/examples/sample_calc/calc.action.tab.rb +243 -69
- data/examples/sample_calc/{calc.astl.action.dr → calc.ast.action.dr} +7 -7
- data/examples/sample_calc/calc.ast.action.tab.rb +755 -0
- data/examples/sample_calc/{calc.astl.dr → calc.ast.dr} +7 -7
- data/examples/sample_calc/calc.ast.tab.rb +672 -0
- data/examples/sample_calc/calc.astdf.dr +5 -5
- data/examples/sample_calc/calc.astdf.tab.rb +405 -202
- data/examples/sample_calc/calc.atree.tab.rb +243 -69
- data/examples/sample_calc/calc.cst.tab.rb +275 -109
- data/examples/sample_calc/calc.lex.tab.rb +210 -28
- data/examples/sample_calc/calc.nvaction.tab.rb +251 -77
- data/examples/sample_calc/calc.tab.rb +210 -28
- data/examples/sample_calc/calc_prec.nvaction.tab.rb +224 -50
- data/examples/slex_test/divreg.slex.tab.rb +97 -21
- data/examples/slex_test/ljoin.slex.tab.rb +128 -35
- data/lib/depager.rb +77 -44
- data/lib/depager/{ast_base.dr → ast.dr} +56 -18
- data/lib/depager/{ast_base.rb → ast.rb} +432 -424
- data/lib/depager/astdf.rb +3 -6
- data/lib/depager/atree.rb +54 -62
- data/lib/depager/cst.dr +2 -2
- data/lib/depager/cst.rb +64 -77
- data/lib/depager/grammar.rb +225 -66
- data/lib/depager/lex.dr +1 -1
- data/lib/depager/lex.rb +45 -54
- data/lib/depager/lr.rb +181 -262
- data/lib/depager/lr_put_table.rb +116 -0
- data/lib/depager/nvaction.rb +1 -1
- data/lib/depager/parser.rb +23 -2
- data/lib/depager/slex.dr +3 -3
- data/lib/depager/slex.rb +148 -169
- data/lib/depager/srp.rb +1 -1
- data/lib/depager/template/ast.erbs +69 -0
- data/lib/depager/template/extension_lalr_master.erb +3 -3
- data/lib/depager/template/extension_lalr_slave.erb +7 -7
- data/lib/depager/template/simple.erb +4 -2
- data/lib/depager/template/single_lalr_parser.erb +30 -10
- data/lib/depager/utils.rb +10 -9
- data/lib/depager/version.rb +2 -8
- metadata +10 -11
- data/examples/sample_calc/calc.astl.action.tab.rb +0 -593
- data/examples/sample_calc/calc.astl.tab.rb +0 -501
- data/lib/depager/astl.rb +0 -14
- data/lib/depager/template/astdf.erbs +0 -57
- data/lib/depager/template/astl.erbs +0 -57
data/lib/depager/lr.rb
CHANGED
@@ -20,129 +20,123 @@ module Depager::LALR
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
Eps = Depager::
|
24
|
-
|
25
|
-
|
23
|
+
Eps = Depager::ParsingMethod::Grammar::Eps
|
24
|
+
TLA = Eps - 1
|
25
|
+
class Grammar < Depager::ParsingMethod::Grammar
|
26
|
+
attr_accessor :memo_closure
|
26
27
|
def initialize_depend
|
28
|
+
@first1[TLA] = [TLA]
|
29
|
+
@sym_mask[TLA] = (1 << @sym_mask.size)
|
30
|
+
@mask_sym << TLA
|
27
31
|
make_sym_f0e
|
28
|
-
@
|
32
|
+
@memo_closure = {}
|
29
33
|
@memo_closure1 = {}
|
30
34
|
end
|
31
35
|
|
32
36
|
def make_sym_f0e
|
37
|
+
@f0e = {}
|
38
|
+
@empty_rules.each do |lhs, rule_no|
|
39
|
+
@f0e[lhs] = { rule_no => symset([Eps]) }
|
40
|
+
end
|
33
41
|
begin
|
34
|
-
|
42
|
+
changed = false
|
35
43
|
@rulelist.each do |rule|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
else
|
51
|
-
tf = fst
|
52
|
-
end
|
53
|
-
ss = tf - @f0e[rl][ern]
|
54
|
-
unless ss.empty?
|
55
|
-
@f0e[rl][ern] |= ss
|
56
|
-
cnt = true
|
57
|
-
end
|
58
|
-
end
|
44
|
+
next unless @f0e[rule.rhs[0]]
|
45
|
+
|
46
|
+
lhs, rhs = rule.lhs, rule.rhs
|
47
|
+
@f0e[lhs] ||= {}
|
48
|
+
@f0e[rhs[0]].each do |n, fst|
|
49
|
+
@f0e[lhs][n] ||= symset()
|
50
|
+
if fst.include? Eps
|
51
|
+
fst = fst.dup
|
52
|
+
fst.delete(Eps)
|
53
|
+
fst.merge!(first(rhs[1 .. -1]))
|
54
|
+
end
|
55
|
+
unless fst.subset_of? @f0e[lhs][n]
|
56
|
+
@f0e[lhs][n].merge! fst
|
57
|
+
changed = true
|
59
58
|
end
|
60
59
|
end
|
61
60
|
end
|
62
|
-
end while
|
63
|
-
end
|
64
|
-
end
|
65
|
-
class Rule < Depager::ParsingMethodCommon::Rule
|
66
|
-
def initialize_depend
|
61
|
+
end while changed
|
67
62
|
end
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
63
|
+
|
64
|
+
def closure1 rule, n, la
|
65
|
+
key = [rule.n, n, la]
|
66
|
+
return @memo_closure1[key] if @memo_closure1[key]
|
67
|
+
|
68
|
+
result = [ LRItem[rule, n, symset(la)] ]
|
69
|
+
memo = n == 0 ? { result[0].rule.n => result[0] } : {}
|
70
|
+
memo2 = {}
|
71
|
+
i = 0
|
72
|
+
while i < result.size
|
73
|
+
ri = result[i] ; i += 1
|
74
|
+
dotsym = ri.dotsym
|
75
|
+
next unless nonterms? dotsym
|
76
|
+
|
77
|
+
b = first(ri.dotrest)
|
78
|
+
if b.delete(Eps) then b.merge! ri.la
|
79
|
+
elsif memo2[ ri ] then next
|
82
80
|
end
|
81
|
+
memo2[ ri ] = true
|
83
82
|
|
84
|
-
|
85
|
-
if li = memo[
|
86
|
-
|
87
|
-
|
88
|
-
|
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}"
|
83
|
+
lhs_to_rule[dotsym].each do |rule|
|
84
|
+
if li = memo[rule.n]
|
85
|
+
unless b.subset_of? li.la
|
86
|
+
li.la.merge! b
|
87
|
+
result << li
|
94
88
|
end
|
95
89
|
else
|
96
|
-
li = memo[
|
97
|
-
|
98
|
-
# warn "+ #{memo[_Brule.n]}"
|
90
|
+
li = memo[rule.n] = LRItem[rule, 0, b]
|
91
|
+
result << li
|
99
92
|
end
|
100
93
|
end
|
101
94
|
end
|
102
|
-
|
103
|
-
|
95
|
+
|
96
|
+
result.uniq!
|
97
|
+
@memo_closure1[key] = result
|
104
98
|
end
|
105
99
|
|
106
|
-
def closure n, base=nil
|
107
|
-
i = 0
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
while i <
|
112
|
-
|
113
|
-
if
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
@g.closure[ji] = []
|
119
|
-
@g.gh[ji].each do |rule|
|
120
|
-
li = LRItem[rule, 0]
|
121
|
-
j.push li
|
122
|
-
@g.closure[ji].push li
|
100
|
+
def closure rule, n, base=nil
|
101
|
+
i = 0; appended = {}
|
102
|
+
result = [base ? base : LRItem[rule, n]]
|
103
|
+
memo = memo_closure
|
104
|
+
|
105
|
+
while i < result.size
|
106
|
+
ds = result[i].dotsym
|
107
|
+
if nonterms?(ds) && !appended[ds]
|
108
|
+
unless memo[ds]
|
109
|
+
memo[ds] = []
|
110
|
+
lhs_to_rule[ds].each do |rule|
|
111
|
+
memo[ds] << LRItem[rule, 0]
|
123
112
|
end
|
124
113
|
end
|
114
|
+
result.concat memo[ds]
|
115
|
+
appended[ds] = true
|
125
116
|
end
|
126
117
|
i += 1
|
127
118
|
end
|
128
|
-
|
119
|
+
result
|
129
120
|
end
|
130
121
|
end
|
122
|
+
class Rule < Depager::ParsingMethod::Rule
|
123
|
+
end
|
131
124
|
|
132
125
|
class LRItem
|
133
126
|
attr_accessor :rule, :n, :la
|
134
|
-
def initialize rule, n, la =
|
127
|
+
def initialize rule, n, la = nil
|
135
128
|
@rule = rule
|
136
129
|
@n = n
|
137
|
-
@la = la
|
138
|
-
@
|
130
|
+
@la = la || rule.grammar.symset()
|
131
|
+
@_hash = nil
|
139
132
|
end
|
140
|
-
def self.[] rule, n, la =
|
133
|
+
def self.[] rule, n, la = nil
|
141
134
|
LRItem.new rule, n, la
|
142
135
|
end
|
143
136
|
|
144
137
|
def hash
|
145
|
-
|
138
|
+
return @_hash if @_hash
|
139
|
+
@_hash = (@rule.hash * 217 + @n.hash) % 76511
|
146
140
|
end
|
147
141
|
def eql? i
|
148
142
|
@rule == i.rule && @n == i.n
|
@@ -150,46 +144,41 @@ module Depager::LALR
|
|
150
144
|
alias == eql?
|
151
145
|
|
152
146
|
def to_s
|
153
|
-
la
|
154
|
-
|
155
|
-
|
156
|
-
|
147
|
+
la = @la.map{|i| @rule.grammar.symname i}.sort.join(' ')
|
148
|
+
lhs = @rule.grammar.symname @rule.lhs
|
149
|
+
rhs = @rule.rhs.map{|i| @rule.grammar.symname i}.insert(@n, '_').join(' ')
|
150
|
+
|
151
|
+
str = "(#{'%03s' % @rule.n}) #{lhs} : #{rhs}"
|
152
|
+
str << "\n # #{la}" if $MP_DEBUG && $MP_DEBUG.match(/l/)
|
153
|
+
return str
|
157
154
|
end
|
158
155
|
def closure1 la
|
159
|
-
@rule.closure1 @n, la
|
156
|
+
@rule.grammar.closure1 @rule, @n, la
|
160
157
|
end
|
161
158
|
def closure
|
162
|
-
@rule.closure @n, self
|
163
|
-
end
|
164
|
-
def goto x
|
165
|
-
return @goto[x] if @goto[x]
|
166
|
-
if @rule.r[@n] == x && @n < @rule.r.size
|
167
|
-
@goto[x] = I.new [ LRItem[@rule, @n+1] ]
|
168
|
-
else
|
169
|
-
@goto[x] = I[]
|
170
|
-
end
|
159
|
+
@rule.grammar.closure @rule, @n, self
|
171
160
|
end
|
172
161
|
def dotsym
|
173
|
-
@rule.
|
162
|
+
@rule.rhs[@n]
|
174
163
|
end
|
175
164
|
def dotrest
|
176
|
-
@rule.
|
165
|
+
@rule.rhs[@n+1 .. -1]
|
177
166
|
end
|
178
167
|
end
|
179
168
|
|
180
|
-
class
|
169
|
+
class State
|
181
170
|
attr_accessor :items, :n
|
182
171
|
def initialize items, n = nil
|
183
172
|
@items = items
|
184
173
|
@goto = {}
|
185
174
|
@n = n
|
186
|
-
@hash = nil
|
187
175
|
@closure = nil
|
176
|
+
@_hash = nil
|
188
177
|
end
|
189
178
|
|
190
179
|
def hash
|
191
|
-
return @
|
192
|
-
@
|
180
|
+
return @_hash if @_hash
|
181
|
+
@_hash = @items.hash
|
193
182
|
end
|
194
183
|
def eql? i
|
195
184
|
@items == i.items
|
@@ -197,14 +186,13 @@ module Depager::LALR
|
|
197
186
|
alias == eql?
|
198
187
|
|
199
188
|
def to_s
|
200
|
-
("I%03i = " % n) << @items.join("\n"
|
201
|
-
#"I#{n}= #{@items.join(' | ')}"
|
189
|
+
("I%03i = \n" % n) << @items.map{|i| " #{i}"}.join("\n")
|
202
190
|
end
|
203
191
|
def empty?
|
204
192
|
@items.empty?
|
205
193
|
end
|
206
194
|
def self.[] items = []
|
207
|
-
|
195
|
+
State.new items
|
208
196
|
end
|
209
197
|
def closure
|
210
198
|
return @closure if @closure
|
@@ -220,71 +208,68 @@ module Depager::LALR
|
|
220
208
|
def mkgoto
|
221
209
|
r = Hash.new{|h,k| h[k]=[]}
|
222
210
|
closure.each do |c|
|
223
|
-
if c.n < c.rule.
|
224
|
-
r[c.
|
211
|
+
if c.n < c.rule.rhs.size
|
212
|
+
r[c.dotsym].push LRItem[c.rule, c.n+1]
|
225
213
|
end
|
226
214
|
end
|
227
215
|
rg = []
|
228
216
|
r.each do |k, v|
|
229
|
-
rg.push [k, (@goto[k] =
|
217
|
+
rg.push [k, (@goto[k] = State.new(v))]
|
230
218
|
end
|
231
219
|
rg
|
232
220
|
end
|
233
221
|
def goto x
|
234
|
-
return @goto[x] ||
|
222
|
+
return @goto[x] || State.new([])
|
235
223
|
end
|
236
224
|
end
|
237
225
|
|
238
226
|
class Table
|
239
|
-
attr_accessor :
|
227
|
+
attr_accessor :grammar, :action_table, :goto_table, :states
|
240
228
|
attr_accessor :defred_table, :defred_after_shift_table
|
241
|
-
def initialize
|
242
|
-
@
|
243
|
-
@
|
244
|
-
@
|
229
|
+
def initialize grammar
|
230
|
+
@grammar = grammar
|
231
|
+
@states = nil
|
232
|
+
@warning_list = []
|
245
233
|
|
246
234
|
items
|
247
235
|
mkset
|
248
236
|
mktable
|
249
|
-
# @g.closure.each{|k,v| warn "#{k} =>"; v.each{|i| warn " #{i}"}}
|
250
|
-
# @c.each{|i| warn "#{i}"; i.gg.each{|k,v| warn " #{@g.syms[k]} => #{v}" unless v.empty?}}
|
251
|
-
#exit
|
252
237
|
end
|
253
238
|
|
254
239
|
def items
|
255
|
-
warn '**
|
240
|
+
warn '** LR(0) **' if $MP_DEBUG
|
256
241
|
n = 0
|
257
242
|
m = 0
|
258
|
-
|
259
|
-
|
243
|
+
states = [ State.new([ LRItem[grammar[0], 0] ], 0) ]
|
244
|
+
memo = {states[0] => m}
|
260
245
|
|
261
|
-
while n <
|
262
|
-
|
246
|
+
while n < states.size
|
247
|
+
states[n].mkgoto.each do |x, a|
|
263
248
|
unless a.empty?
|
264
|
-
if
|
265
|
-
|
249
|
+
if memo_a = memo[a]
|
250
|
+
states[n].gg[x] = states[memo_a]
|
266
251
|
else
|
267
252
|
m += 1
|
268
253
|
a.n = m
|
269
|
-
|
270
|
-
|
254
|
+
states[m] = a
|
255
|
+
memo[a] = m
|
271
256
|
end
|
272
257
|
end
|
273
258
|
end
|
274
259
|
n += 1
|
275
260
|
end
|
276
|
-
@
|
261
|
+
@states = states
|
277
262
|
end
|
278
263
|
|
279
264
|
# -1:reduce sh; 1:shift rd(=key); 0:can't resolve
|
280
265
|
def resolveconf(sh, rd)
|
281
|
-
precs =
|
266
|
+
precs = grammar.precs
|
282
267
|
psh = precs[sh]
|
283
|
-
mrt =
|
284
|
-
prd =
|
268
|
+
mrt = grammar[rd].rhs.reverse.find{|i| grammar.terms?(i) }
|
269
|
+
prd = grammar[rd].prec || precs[mrt]
|
285
270
|
|
286
|
-
# warn "#{
|
287
|
-
# warn "#{
|
271
|
+
# warn "#{grammar.syms[sh]} #{psh.inspect}"
|
272
|
+
# warn "#{grammar[rd]} #{prd.inspect}"
|
288
273
|
|
289
274
|
if psh && prd
|
290
275
|
if psh[1] == prd[1]
|
@@ -304,22 +289,28 @@ module Depager::LALR
|
|
304
289
|
|
305
290
|
def checkconf newv, oldv, key, g = nil
|
306
291
|
return newv unless oldv
|
292
|
+
|
293
|
+
rl = grammar.rulelist
|
294
|
+
syms = grammar.syms
|
307
295
|
if oldv == 'ACC'
|
308
|
-
@
|
296
|
+
@warning_list << "'ACC' conflict #{g}."
|
309
297
|
return oldv
|
310
298
|
end
|
311
|
-
# warn "\n-- N:#{newv} O:#{oldv} K:#{
|
299
|
+
# warn "\n-- N:#{newv} O:#{oldv} K:#{grammar.syms[key]} "
|
312
300
|
if newv < 0 and oldv > 0
|
313
|
-
# warn "-:shift #{
|
301
|
+
# warn "-:shift #{grammar.syms[key]} go to #{oldv}"
|
314
302
|
r = resolveconf(key, -newv)
|
315
303
|
if r > 0
|
316
|
-
# warn "+:shift #{
|
304
|
+
# warn "+:shift #{grammar.syms[key]} go to #{oldv}"
|
317
305
|
oldv
|
318
306
|
elsif r < 0
|
319
|
-
# warn "+:reduce #{
|
307
|
+
# warn "+:reduce #{grammar[-newv]}"
|
320
308
|
newv
|
321
309
|
else
|
322
|
-
@
|
310
|
+
@warning_list <<
|
311
|
+
("shift/reduce conflict #{syms[key]}.\n #{g}\n" <<
|
312
|
+
" shift : #{syms[key]}\n" <<
|
313
|
+
" reduce: #{rl[-newv]}")
|
323
314
|
oldv
|
324
315
|
end
|
325
316
|
elsif newv > 0 and oldv < 0
|
@@ -331,15 +322,18 @@ module Depager::LALR
|
|
331
322
|
# warn "reduce"
|
332
323
|
oldv
|
333
324
|
else
|
334
|
-
@
|
325
|
+
@warning_list <<
|
326
|
+
("shift/reduce conflict #{syms[key]}.\n #{g}\n" <<
|
327
|
+
" shift : #{syms[key]}\n" <<
|
328
|
+
" reduce: #{rl[-oldv]}")
|
335
329
|
newv
|
336
330
|
end
|
337
331
|
elsif newv < 0 and oldv < 0
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
332
|
+
unless newv == oldv
|
333
|
+
@warning_list <<
|
334
|
+
("reduce/reduce conflict #{syms[key]}.\n #{g}\n" <<
|
335
|
+
" reduce: #{rl[-newv]}\n" <<
|
336
|
+
" reduce: #{rl[-oldv]}" )
|
343
337
|
newv
|
344
338
|
end
|
345
339
|
else
|
@@ -349,39 +343,41 @@ module Depager::LALR
|
|
349
343
|
end
|
350
344
|
|
351
345
|
def mktable
|
352
|
-
warn '**
|
353
|
-
taction = (0...@
|
354
|
-
tgoto = (0...@
|
346
|
+
warn '** TABLE **' if $MP_DEBUG
|
347
|
+
taction = (0...@states.size).map{ Array.new(grammar.syms.size - grammar.nonterms.size) }
|
348
|
+
tgoto = (0...@states.size).map{ Array.new(grammar.nonterms.size - 1) }
|
355
349
|
|
356
|
-
@
|
350
|
+
@states.each_with_index do |c, i|
|
357
351
|
c.gg.each do |k, j|
|
358
352
|
next unless k
|
359
|
-
if
|
360
|
-
key = k -
|
353
|
+
if grammar.terms? k
|
354
|
+
key = k - grammar.nonterms.size
|
361
355
|
taction[i][key] = checkconf(j.n, taction[i][key], k, c )
|
362
356
|
else
|
363
357
|
tgoto[i][k - 1] = j.n
|
364
358
|
end
|
365
359
|
end
|
366
360
|
c.items.each do |j|
|
367
|
-
if j.n == j.rule.
|
361
|
+
if j.n == j.rule.rhs.size and j.rule.lhs != 0 # $start
|
368
362
|
j.la.each do |u|
|
369
|
-
key = u -
|
363
|
+
key = u - grammar.nonterms.size
|
370
364
|
taction[i][key] = checkconf(-j.rule.n, taction[i][key], u, c)
|
371
365
|
end
|
372
|
-
elsif efs =
|
366
|
+
elsif efs = grammar.f0e[j.dotsym]
|
373
367
|
efs.each do |rn, ef|
|
374
368
|
ef.each do |es|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
369
|
+
fst = grammar.symset
|
370
|
+
j.la.each do |la|
|
371
|
+
fst |= grammar.first [es, *j.dotrest].push(la)
|
372
|
+
end
|
373
|
+
fst.each do |u|
|
374
|
+
key = u - grammar.nonterms.size
|
379
375
|
taction[i][key] = checkconf(-rn, taction[i][key], u, c)
|
380
376
|
end
|
381
377
|
end
|
382
378
|
end
|
383
379
|
end
|
384
|
-
if j.rule ==
|
380
|
+
if j.rule == grammar[0] && j.n == 1 # $start : ...
|
385
381
|
taction[i][0] = 'ACC'
|
386
382
|
end
|
387
383
|
end
|
@@ -418,121 +414,44 @@ module Depager::LALR
|
|
418
414
|
|
419
415
|
@action_table=taction
|
420
416
|
@goto_table=tgoto
|
421
|
-
put_table if $DEBUG
|
422
417
|
end
|
423
418
|
|
424
419
|
def check_table dp
|
425
|
-
@
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
f_ = first1.map {|k, v|
|
434
|
-
"#{syms[k]} => " << v.map{|i|
|
435
|
-
i == Eps ? ':eps' : syms[i]
|
436
|
-
}.join(' ')
|
437
|
-
}.join("\n")
|
438
|
-
|
439
|
-
e = f0e.map {|k, v|
|
440
|
-
"#{syms[k].inspect} => " << v.map{|n, f|
|
441
|
-
" #{rulelist[n]} ? " << f.map{|i|
|
442
|
-
i == Eps ? ':eps' : syms[i].inspect
|
443
|
-
}.join(' ')
|
444
|
-
}.join("\n")
|
445
|
-
}.join("\n")
|
446
|
-
|
447
|
-
r = rulelist.join("\n")
|
448
|
-
c = @c.join("\n")
|
449
|
-
|
450
|
-
ws = (@g.nssize ... @g.syms.size).map{|i| syms[i].to_s.size}
|
451
|
-
ws = ws.map{|i| i < 6 ? 6 : i}
|
452
|
-
a = " |"
|
453
|
-
(@g.nssize ... @g.syms.size).each_with_index{|i, x|
|
454
|
-
a << ("%0#{ws[x]}s|" % @g.syms[i])
|
455
|
-
}
|
456
|
-
a << " $default|\n"
|
457
|
-
@action_table.each_with_index{|i,x|
|
458
|
-
a << ("%03i|" % x)
|
459
|
-
i.each_with_index{|j, y|
|
460
|
-
a << ("%0#{ws[y]}s|" % j)
|
461
|
-
}
|
462
|
-
a << ("%04s,%04s|\n" % [@defred_table[x], @defred_after_shift_table[x]])
|
463
|
-
}
|
464
|
-
|
465
|
-
ws = (1 ... @g.nssize).map{|i| @g.syms[i].to_s.size}
|
466
|
-
ws = ws.map{|i| i < 6 ? 6 : i}
|
467
|
-
g = " |"
|
468
|
-
(1 ... @g.nssize).each_with_index{|i, x|
|
469
|
-
g << ("%0#{ws[x]}s|" % @g.syms[i])
|
470
|
-
}
|
471
|
-
g << "\n"
|
472
|
-
@goto_table.each_with_index{|i,x|
|
473
|
-
g << ("%03i|" % x)
|
474
|
-
i.each_with_index{|j, y|
|
475
|
-
g << ("%0#{ws[y]}s|" % j)
|
476
|
-
}
|
477
|
-
g << "\n"
|
478
|
-
}
|
479
|
-
|
480
|
-
gh = ""
|
481
|
-
@g.gh.each_with_index{|i, x|
|
482
|
-
gh << "#{syms[x]}(#{x}) => #{i}\n"
|
483
|
-
}
|
484
|
-
|
485
|
-
warn "** SYMS **\n\n#{s}\n\n" <<
|
486
|
-
"** FIRST1 **\n\n#{f_}\n\n" <<
|
487
|
-
"** Eps Reduce Rule **\n\n#{e}\n\n" <<
|
488
|
-
"*** Grammar ***\n\n#{r}\n\n" <<
|
489
|
-
"** GH **\n\n#{gh}\n\n" <<
|
490
|
-
"*** States ***\n\n#{c}\n\n" <<
|
491
|
-
"*** Action Table ***\n\n#{a}\n" <<
|
492
|
-
"*** Goto Table ***\n\n#{g}\n"
|
420
|
+
@warning_list.each{|i| dp.warning i }
|
421
|
+
|
422
|
+
if $MP_DEBUG
|
423
|
+
require 'depager/lr_put_table.rb'
|
424
|
+
gen_state_info
|
425
|
+
verbose dp if $MP_VERBOSE
|
426
|
+
end
|
493
427
|
end
|
494
428
|
|
495
429
|
def mkset
|
496
|
-
warn '**
|
430
|
+
warn '** LA **' if $MP_DEBUG
|
497
431
|
trn = []
|
498
|
-
@
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
else
|
507
|
-
trn.push [_B, i, _K, _K.goto(_A.dotsym)]
|
508
|
-
end
|
509
|
-
end
|
510
|
-
break
|
511
|
-
end
|
512
|
-
end
|
432
|
+
@states.each do |state|
|
433
|
+
state.items.each do |sitem|
|
434
|
+
sitem.closure1([TLA]).each do |citem|
|
435
|
+
next if citem.n == citem.rule.rhs.size
|
436
|
+
gi = state.goto(citem.dotsym).items
|
437
|
+
i = gi.find{|j| j.rule == citem.rule && j.n == citem.n+1 }
|
438
|
+
trn << [sitem, i] if citem.la.include? TLA
|
439
|
+
i.la.merge!(citem.la).delete(TLA)
|
513
440
|
end
|
514
441
|
end
|
515
442
|
end
|
516
443
|
|
517
|
-
|
518
|
-
#
|
519
|
-
#puts @g.memo_closure1.sort_by{|k,v| k}.map{|k,v| "#{k.inspect}:\n#{v.join("\n")}"}
|
520
|
-
#puts 'mk'; mk.each{|k, v| p "#{k}=>#{v}"}
|
521
|
-
#trn = trn.uniq
|
522
|
-
#puts 'trn',trn.map{|a| "<#{a[2].n}>#{a[0]} => <#{a[3].n}>#{a[1]}"}
|
523
|
-
warn '** mk LALR(1) **' if $MP_DEBUG
|
524
|
-
@c[0].items[0].la = [@g.nssize] # '$'
|
444
|
+
warn '** LALR(1) **' if $MP_DEBUG
|
445
|
+
@states[0].items[0].la = @grammar.symset([grammar.nonterms.size]) # '$'
|
525
446
|
begin
|
526
|
-
|
527
|
-
trn.each do |k, v
|
528
|
-
k.la.
|
529
|
-
|
530
|
-
|
531
|
-
v.la << i
|
532
|
-
end
|
447
|
+
changed = false
|
448
|
+
trn.each do |k, v|
|
449
|
+
unless k.la.subset_of?(v.la)
|
450
|
+
v.la.merge!(k.la)
|
451
|
+
changed
|
533
452
|
end
|
534
453
|
end
|
535
|
-
end while
|
454
|
+
end while changed
|
536
455
|
end
|
537
456
|
end
|
538
457
|
end
|