depager 0.3.0.b20160729 → 0.3.0.b20250423
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 +5 -5
- data/.rubocop.yml +44 -0
- data/.simplecov +5 -0
- data/Gemfile +12 -0
- data/LICENSE.gpl +339 -0
- data/Manifest.txt +73 -0
- data/README.en +4 -3
- data/README.ja +4 -47
- data/Rakefile +31 -0
- data/bin/depager +3 -38
- data/examples/action_pl0d/pl0d.action.dr +4 -4
- data/examples/action_pl0d/test.pl0ds +2 -3
- data/examples/c89/c89.dr +4 -4
- data/examples/c89/test.c89 +1 -1
- data/examples/extension/astdf.rb +4 -5
- data/examples/extension/atree.dr +3 -3
- data/examples/extension/calc.atree.dr +4 -4
- data/examples/extension/calc.simple_action.dr +3 -3
- data/examples/extension/paction.dr +3 -3
- data/examples/extension/pactiontest.dr +3 -3
- data/examples/extension/simple_action.rb +26 -24
- data/examples/pl0d/pl0ds.dr +5 -5
- data/examples/pl0d/test.pl0ds +2 -2
- data/examples/rie_calc/calc.rie.dr +4 -4
- data/examples/rie_dcuse/dcuse.rie.dr +4 -4
- data/examples/rie_pl0/pl0.rie.dr +3 -3
- data/examples/slex_test/divreg.slex.dr +5 -5
- data/examples/slex_test/ljoin.slex.dr +5 -5
- data/examples/{sample_calc → tiny_calc}/calc.action.dr +4 -4
- data/examples/{sample_calc → tiny_calc}/calc.ast.action.dr +20 -9
- data/examples/{sample_calc → tiny_calc}/calc.ast.dr +19 -7
- data/examples/{sample_calc → tiny_calc}/calc.cst.dr +12 -7
- data/examples/{sample_calc → tiny_calc}/calc.dr +1 -1
- data/examples/{sample_calc → tiny_calc}/calc.lex.dr +2 -2
- data/examples/{sample_calc → tiny_calc}/calc_prec.action.dr +4 -4
- data/lib/depager/cli.rb +44 -0
- data/lib/depager/grammar.rb +72 -75
- data/lib/depager/lr.rb +169 -154
- data/lib/depager/parser.rb +90 -103
- data/lib/depager/plugins/_rie_debug.rb +63 -0
- data/lib/depager/plugins/action.rb +47 -0
- data/lib/depager/{ruby/plugins → plugins}/ast.dr +20 -17
- data/lib/depager/{ruby/plugins → plugins}/ast.rb +266 -304
- data/lib/depager/{ruby/plugins → plugins}/cst.dr +18 -16
- data/lib/depager/{ruby/plugins → plugins}/cst.rb +152 -148
- data/lib/depager/{ruby/plugins → plugins}/lex.dr +7 -7
- data/lib/depager/{ruby/plugins → plugins}/lex.rb +72 -69
- data/lib/depager/{ruby/plugins → plugins}/rie.dr +12 -10
- data/lib/depager/{ruby/plugins → plugins}/rie.rb +224 -263
- data/lib/depager/{ruby/plugins → plugins}/slex.dr +13 -14
- data/lib/depager/{ruby/plugins → plugins}/slex.rb +183 -194
- data/lib/depager/plugins/srp.rb +46 -0
- data/lib/depager/ruby/templates/extension_lalr_master.erb +6 -12
- data/lib/depager/ruby/templates/extension_lalr_slave.erb +31 -17
- data/lib/depager/ruby/templates/single_lalr_parser.erb +35 -26
- data/lib/depager/utils.rb +56 -46
- data/lib/depager/version.rb +1 -2
- data/lib/depager.rb +166 -176
- metadata +38 -33
- data/lib/depager/ruby/plugins/_rie_debug.rb +0 -35
- data/lib/depager/ruby/plugins/action.rb +0 -53
- data/lib/depager/ruby/plugins/srp.rb +0 -56
- /data/examples/{sample_calc → tiny_calc}/test.calc +0 -0
data/lib/depager/lr.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
require 'depager/grammar.rb'
|
1
|
+
require "depager/grammar"
|
3
2
|
|
4
3
|
module Depager::LALR
|
5
4
|
class ParserGenerator < Depager::ParserGenerator
|
6
|
-
def initialize
|
5
|
+
def initialize(d_parser)
|
7
6
|
super
|
8
7
|
@parsing_method = Depager::LALR
|
9
8
|
end
|
@@ -14,7 +13,7 @@ module Depager::LALR
|
|
14
13
|
end
|
15
14
|
|
16
15
|
class ExtensionGenerator < Depager::ExtensionGenerator
|
17
|
-
def initialize
|
16
|
+
def initialize(d_parser)
|
18
17
|
super
|
19
18
|
@parsing_method = Depager::LALR
|
20
19
|
end
|
@@ -33,6 +32,7 @@ module Depager::LALR
|
|
33
32
|
|
34
33
|
class Grammar < Depager::Grammar
|
35
34
|
attr_accessor :memo_closure
|
35
|
+
|
36
36
|
def initialize_depend
|
37
37
|
@first1[TLA] = [TLA]
|
38
38
|
@sym_mask[TLA] = (1 << @sym_mask.size)
|
@@ -52,14 +52,15 @@ module Depager::LALR
|
|
52
52
|
@rulelist.each do |rule|
|
53
53
|
next unless @f0e[rule.rhs[0]]
|
54
54
|
|
55
|
-
lhs
|
55
|
+
lhs = rule.lhs
|
56
|
+
rhs = rule.rhs
|
56
57
|
@f0e[lhs] ||= {}
|
57
58
|
@f0e[rhs[0]].each do |n, fst|
|
58
|
-
@f0e[lhs][n] ||= symset
|
59
|
+
@f0e[lhs][n] ||= symset
|
59
60
|
if fst.include? EPS
|
60
61
|
fst = fst.dup
|
61
62
|
fst.delete(EPS)
|
62
|
-
fst.merge!(first(rhs[1
|
63
|
+
fst.merge!(first(rhs[1..]))
|
63
64
|
end
|
64
65
|
unless fst.subset_of? @f0e[lhs][n]
|
65
66
|
@f0e[lhs][n].merge! fst
|
@@ -70,27 +71,28 @@ module Depager::LALR
|
|
70
71
|
end while changed
|
71
72
|
end
|
72
73
|
|
73
|
-
def closure1
|
74
|
+
def closure1(rule, n, la)
|
74
75
|
key = [rule.n, n, la]
|
75
76
|
return @memo_closure1[key] if @memo_closure1[key]
|
76
77
|
|
77
|
-
result = [
|
78
|
+
result = [LRItem[rule, n, symset(la)]]
|
78
79
|
memo = n == 0 ? { result[0].rule.n => result[0] } : {}
|
79
80
|
memo2 = {}
|
80
81
|
i = 0
|
81
82
|
while i < result.size
|
82
|
-
ri = result[i]
|
83
|
+
ri = result[i]
|
84
|
+
i += 1
|
83
85
|
dotsym = ri.dotsym
|
84
86
|
next unless nonterm? dotsym
|
85
87
|
|
86
88
|
b = first(ri.dotrest)
|
87
89
|
if b.delete(EPS) then b.merge! ri.la
|
88
|
-
elsif memo2[
|
90
|
+
elsif memo2[ri] then next
|
89
91
|
end
|
90
|
-
memo2[
|
92
|
+
memo2[ri] = true
|
91
93
|
|
92
94
|
lhs_to_rule[dotsym].each do |rule|
|
93
|
-
if li = memo[rule.n]
|
95
|
+
if (li = memo[rule.n])
|
94
96
|
unless b.subset_of? li.la
|
95
97
|
li.la.merge! b
|
96
98
|
result << li
|
@@ -106,9 +108,10 @@ module Depager::LALR
|
|
106
108
|
@memo_closure1[key] = result
|
107
109
|
end
|
108
110
|
|
109
|
-
def closure
|
110
|
-
i = 0
|
111
|
-
|
111
|
+
def closure(rule, n, base = nil)
|
112
|
+
i = 0
|
113
|
+
appended = {}
|
114
|
+
result = [base || LRItem[rule, n]]
|
112
115
|
memo = memo_closure
|
113
116
|
|
114
117
|
while i < result.size
|
@@ -134,51 +137,60 @@ module Depager::LALR
|
|
134
137
|
|
135
138
|
class LRItem
|
136
139
|
attr_accessor :rule, :n, :la
|
137
|
-
|
140
|
+
|
141
|
+
def initialize(rule, n, la = nil)
|
138
142
|
@rule = rule
|
139
143
|
@n = n
|
140
|
-
@la = la || rule.grammar.symset
|
144
|
+
@la = la || rule.grammar.symset
|
141
145
|
@_hash = nil
|
142
146
|
end
|
143
|
-
|
147
|
+
|
148
|
+
def self.[](rule, n, la = nil)
|
144
149
|
LRItem.new rule, n, la
|
145
150
|
end
|
146
151
|
|
147
152
|
def hash
|
148
153
|
return @_hash if @_hash
|
149
|
-
|
154
|
+
|
155
|
+
@_hash = [@rule, @n].hash
|
150
156
|
end
|
151
|
-
|
152
|
-
|
157
|
+
|
158
|
+
def eql?(other)
|
159
|
+
@rule == other.rule && @n == other.n
|
153
160
|
end
|
154
161
|
alias == eql?
|
155
162
|
|
156
163
|
def to_s
|
157
|
-
la = @la.map{|i| @rule.grammar.symname i}.sort.join(
|
164
|
+
la = @la.map { |i| @rule.grammar.symname i }.sort.join(" ")
|
158
165
|
lhs = @rule.grammar.symname @rule.lhs
|
159
|
-
rhs = @rule.rhs.map{|i| @rule.grammar.symname i}.insert(@n,
|
166
|
+
rhs = @rule.rhs.map { |i| @rule.grammar.symname i }.insert(@n, "_").join(" ")
|
160
167
|
|
161
|
-
str = "(#{'%03s'
|
168
|
+
str = "(#{format('%03s', @rule.n)}) #{lhs} : #{rhs}"
|
162
169
|
str << "\n # #{la}" if Depager.debug_mode?(:l)
|
163
|
-
|
170
|
+
str
|
164
171
|
end
|
165
|
-
|
172
|
+
|
173
|
+
def closure1(la)
|
166
174
|
@rule.grammar.closure1 @rule, @n, la
|
167
175
|
end
|
176
|
+
|
168
177
|
def closure
|
169
178
|
@rule.grammar.closure @rule, @n, self
|
170
179
|
end
|
180
|
+
|
171
181
|
def dotsym
|
172
182
|
@rule.rhs[@n]
|
173
183
|
end
|
184
|
+
|
174
185
|
def dotrest
|
175
|
-
@rule.rhs[@n+1
|
186
|
+
@rule.rhs[@n + 1..]
|
176
187
|
end
|
177
188
|
end
|
178
189
|
|
179
190
|
class State
|
180
191
|
attr_accessor :items, :n
|
181
|
-
|
192
|
+
|
193
|
+
def initialize(items, n = nil)
|
182
194
|
@items = items
|
183
195
|
@goto = {}
|
184
196
|
@n = n
|
@@ -188,55 +200,60 @@ module Depager::LALR
|
|
188
200
|
|
189
201
|
def hash
|
190
202
|
return @_hash if @_hash
|
203
|
+
|
191
204
|
@_hash = @items.hash
|
192
205
|
end
|
193
|
-
|
194
|
-
|
206
|
+
|
207
|
+
def eql?(other)
|
208
|
+
@items == other.items
|
195
209
|
end
|
196
210
|
alias == eql?
|
197
211
|
|
198
212
|
def to_s
|
199
|
-
("I%03i = \n"
|
213
|
+
format("I%03i = \n", n) << @items.map(&:to_s).join("\n").lines.map { |i| " #{i}" }.join
|
200
214
|
end
|
215
|
+
|
201
216
|
def empty?
|
202
217
|
@items.empty?
|
203
218
|
end
|
204
|
-
|
219
|
+
|
220
|
+
def self.[](items = [])
|
205
221
|
State.new items
|
206
222
|
end
|
223
|
+
|
207
224
|
def closure
|
208
225
|
return @closure if @closure
|
226
|
+
|
209
227
|
r = []
|
210
228
|
@items.each do |i|
|
211
229
|
r |= i.closure
|
212
230
|
end
|
213
231
|
@closure = r
|
214
232
|
end
|
233
|
+
|
215
234
|
def gg
|
216
235
|
@goto
|
217
236
|
end
|
237
|
+
|
218
238
|
def mkgoto
|
219
|
-
r = Hash.new{|h,k| h[k]=[]}
|
239
|
+
r = Hash.new { |h, k| h[k] = [] }
|
220
240
|
closure.each do |c|
|
221
|
-
if c.n < c.rule.rhs.size
|
222
|
-
r[c.dotsym].push LRItem[c.rule, c.n+1]
|
223
|
-
end
|
241
|
+
r[c.dotsym].push LRItem[c.rule, c.n + 1] if c.n < c.rule.rhs.size
|
224
242
|
end
|
225
|
-
|
226
|
-
|
227
|
-
rg.push [k, (@goto[k] = State.new(v))]
|
243
|
+
r.map do |k, v|
|
244
|
+
[k, (@goto[k] = State.new(v.sort_by { |it| [it.rule.n, it.n] }))]
|
228
245
|
end
|
229
|
-
rg
|
230
246
|
end
|
231
|
-
|
232
|
-
|
247
|
+
|
248
|
+
def goto(x)
|
249
|
+
@goto[x] || State.new([])
|
233
250
|
end
|
234
251
|
end
|
235
252
|
|
236
253
|
class Table
|
237
|
-
attr_accessor :grammar, :action_table, :goto_table, :states
|
238
|
-
|
239
|
-
def initialize
|
254
|
+
attr_accessor :grammar, :action_table, :goto_table, :states, :defred_table, :defred_after_shift_table
|
255
|
+
|
256
|
+
def initialize(grammar)
|
240
257
|
@grammar = grammar
|
241
258
|
@states = nil
|
242
259
|
@warning_list = []
|
@@ -247,16 +264,16 @@ module Depager::LALR
|
|
247
264
|
end
|
248
265
|
|
249
266
|
def items
|
250
|
-
warn
|
267
|
+
warn "** LR(0) **" if Depager.debug_mode?
|
251
268
|
n = 0
|
252
269
|
m = 0
|
253
|
-
states = [
|
254
|
-
memo = {states[0] => m}
|
270
|
+
states = [State.new([LRItem[grammar[0], 0]], 0)]
|
271
|
+
memo = { states[0] => m }
|
255
272
|
|
256
273
|
while n < states.size
|
257
274
|
states[n].mkgoto.each do |x, a|
|
258
275
|
unless a.empty?
|
259
|
-
if memo_a = memo[a]
|
276
|
+
if (memo_a = memo[a])
|
260
277
|
states[n].gg[x] = states[memo_a]
|
261
278
|
else
|
262
279
|
m += 1
|
@@ -275,7 +292,7 @@ module Depager::LALR
|
|
275
292
|
def resolveconf(sh, rd)
|
276
293
|
precs = grammar.precs
|
277
294
|
psh = precs[sh]
|
278
|
-
mrt = grammar[rd].rhs.reverse.find{|i| grammar.term?(i) }
|
295
|
+
mrt = grammar[rd].rhs.reverse.find { |i| grammar.term?(i) }
|
279
296
|
prd = grammar[rd].prec || precs[mrt]
|
280
297
|
|
281
298
|
if psh && prd
|
@@ -294,17 +311,17 @@ module Depager::LALR
|
|
294
311
|
end
|
295
312
|
end
|
296
313
|
|
297
|
-
def checkconf
|
314
|
+
def checkconf(newv, oldv, key, g = nil)
|
298
315
|
return newv unless oldv
|
299
316
|
|
300
317
|
rl = grammar.rulelist
|
301
318
|
syms = grammar.syms
|
302
|
-
if oldv ==
|
319
|
+
if oldv == "ACC"
|
303
320
|
@warning_list << "'ACC' conflict #{g}."
|
304
321
|
return oldv
|
305
322
|
end
|
306
323
|
# warn "\n-- N:#{newv} O:#{oldv} K:#{grammar.syms[key]} "
|
307
|
-
if newv < 0
|
324
|
+
if (newv < 0) && (oldv > 0)
|
308
325
|
# warn "-:shift #{grammar.syms[key]} go to #{oldv}"
|
309
326
|
r = resolveconf(key, -newv)
|
310
327
|
if r > 0
|
@@ -315,32 +332,32 @@ module Depager::LALR
|
|
315
332
|
newv
|
316
333
|
else
|
317
334
|
@warning_list <<
|
318
|
-
("shift/reduce conflict #{syms[key]}.\n #{g}\n"
|
319
|
-
|
320
|
-
|
335
|
+
("shift/reduce conflict #{syms[key]}.\n #{g}\n " \
|
336
|
+
"shift : #{syms[key]}\n " \
|
337
|
+
"reduce: #{rl[-newv]}")
|
321
338
|
oldv
|
322
339
|
end
|
323
|
-
elsif newv > 0
|
340
|
+
elsif (newv > 0) && (oldv < 0)
|
324
341
|
r = resolveconf(key, -oldv)
|
325
342
|
if r > 0
|
326
343
|
# warn "shift"
|
327
344
|
newv
|
328
|
-
elsif r <0
|
345
|
+
elsif r < 0
|
329
346
|
# warn "reduce"
|
330
347
|
oldv
|
331
348
|
else
|
332
349
|
@warning_list <<
|
333
|
-
("shift/reduce conflict #{syms[key]}.\n #{g}\n"
|
334
|
-
|
335
|
-
|
350
|
+
("shift/reduce conflict #{syms[key]}.\n #{g}\n " \
|
351
|
+
"shift : #{syms[key]}\n " \
|
352
|
+
"reduce: #{rl[-oldv]}")
|
336
353
|
newv
|
337
354
|
end
|
338
|
-
elsif newv < 0
|
355
|
+
elsif (newv < 0) && (oldv < 0)
|
339
356
|
unless newv == oldv
|
340
357
|
@warning_list <<
|
341
|
-
("reduce/reduce conflict #{syms[key]}.\n #{g}\n"
|
342
|
-
|
343
|
-
|
358
|
+
("reduce/reduce conflict #{syms[key]}.\n #{g}\n " \
|
359
|
+
"reduce: #{rl[-newv]}\n " \
|
360
|
+
"reduce: #{rl[-oldv]}")
|
344
361
|
newv
|
345
362
|
end
|
346
363
|
else
|
@@ -350,27 +367,28 @@ module Depager::LALR
|
|
350
367
|
end
|
351
368
|
|
352
369
|
def mktable
|
353
|
-
warn
|
354
|
-
taction = (0...@states.size).map{ Array.new(grammar.syms.size - grammar.nonterms.size) }
|
355
|
-
tgoto = (0...@states.size).map{ Array.new(grammar.nonterms.size - 1) }
|
370
|
+
warn "** TABLE **" if Depager.debug_mode?
|
371
|
+
taction = (0...@states.size).map { Array.new(grammar.syms.size - grammar.nonterms.size) }
|
372
|
+
tgoto = (0...@states.size).map { Array.new(grammar.nonterms.size - 1) }
|
356
373
|
|
357
374
|
@states.each_with_index do |c, i|
|
358
375
|
c.gg.each do |k, j|
|
359
376
|
next unless k
|
377
|
+
|
360
378
|
if grammar.term? k
|
361
379
|
key = k - grammar.nonterms.size
|
362
|
-
taction[i][key] = checkconf(j.n, taction[i][key], k, c
|
380
|
+
taction[i][key] = checkconf(j.n, taction[i][key], k, c)
|
363
381
|
else
|
364
382
|
tgoto[i][k - 1] = j.n
|
365
383
|
end
|
366
384
|
end
|
367
385
|
c.items.each do |j|
|
368
|
-
if j.n == j.rule.rhs.size
|
386
|
+
if (j.n == j.rule.rhs.size) && (j.rule.lhs != 0) # $start
|
369
387
|
j.la.each do |u|
|
370
388
|
key = u - grammar.nonterms.size
|
371
389
|
taction[i][key] = checkconf(-j.rule.n, taction[i][key], u, c)
|
372
390
|
end
|
373
|
-
elsif efs = grammar.f0e[j.dotsym]
|
391
|
+
elsif (efs = grammar.f0e[j.dotsym])
|
374
392
|
efs.each do |rn, ef|
|
375
393
|
ef.each do |es|
|
376
394
|
fst = grammar.symset
|
@@ -384,70 +402,61 @@ module Depager::LALR
|
|
384
402
|
end
|
385
403
|
end
|
386
404
|
end
|
387
|
-
if j.rule == grammar[0] && j.n == 1 # $start : ...
|
388
|
-
taction[i][0] = 'ACC'
|
389
|
-
end
|
405
|
+
taction[i][0] = "ACC" if j.rule == grammar[0] && j.n == 1 # $start : ...
|
390
406
|
end
|
391
407
|
end
|
392
408
|
|
393
409
|
@defred_table = []
|
394
410
|
taction.each_with_index do |l, x|
|
395
|
-
rs = l.select{|i| i.is_a? Integer}.uniq.compact
|
396
|
-
rs = rs.select{|i| i < 0 }
|
397
|
-
if rs.size == 1
|
398
|
-
@defred_table[x] = rs[0]
|
399
|
-
else
|
400
|
-
@defred_table[x] = nil
|
401
|
-
end
|
411
|
+
rs = l.select { |i| i.is_a? Integer }.uniq.compact
|
412
|
+
rs = rs.select { |i| i < 0 }
|
413
|
+
@defred_table[x] = (rs[0] if rs.size == 1)
|
402
414
|
end
|
403
415
|
|
404
416
|
@defred_after_shift_table = []
|
405
417
|
taction.each_with_index do |l, x|
|
406
|
-
rs = l.select{|i| i.is_a? Integer}.uniq.compact
|
407
|
-
if rs.size == 1
|
408
|
-
@defred_after_shift_table[x] = rs[0]
|
409
|
-
else
|
410
|
-
@defred_after_shift_table[x] = nil
|
411
|
-
end
|
418
|
+
rs = l.select { |i| i.is_a? Integer }.uniq.compact
|
419
|
+
@defred_after_shift_table[x] = (rs[0] if (rs.size == 1) && (rs[0] < 0))
|
412
420
|
end
|
413
421
|
|
414
|
-
taction.each_with_index do |l, x|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
422
|
+
taction.each_with_index do |l, x| # rubocop:disable Style/CombinableLoops
|
423
|
+
next unless @defred_table[x]
|
424
|
+
|
425
|
+
l.size.times do |i|
|
426
|
+
l[i] = nil if l[i] && l[i] < 0
|
419
427
|
end
|
420
428
|
end
|
421
429
|
|
422
|
-
@action_table=taction
|
423
|
-
@goto_table=tgoto
|
430
|
+
@action_table = taction
|
431
|
+
@goto_table = tgoto
|
424
432
|
end
|
425
433
|
|
426
|
-
def check_table
|
427
|
-
@warning_list.each{|i| dp.warning i }
|
434
|
+
def check_table(dp)
|
435
|
+
@warning_list.each { |i| dp.warning i }
|
428
436
|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
437
|
+
return unless Depager.debug_mode?
|
438
|
+
|
439
|
+
gen_state_info
|
440
|
+
verbose dp if Depager.verbose_mode?
|
433
441
|
end
|
434
442
|
|
435
443
|
def mkset
|
436
|
-
warn
|
444
|
+
warn "** LA **" if Depager.debug_mode?
|
437
445
|
trn = []
|
438
446
|
@states.each do |state|
|
439
447
|
state.items.each do |sitem|
|
440
448
|
sitem.closure1([TLA]).each do |citem|
|
441
449
|
next if citem.n == citem.rule.rhs.size
|
450
|
+
|
442
451
|
gi = state.goto(citem.dotsym).items
|
443
|
-
i = gi.find{|j| j.rule == citem.rule && j.n == citem.n+1 }
|
452
|
+
i = gi.find { |j| j.rule == citem.rule && j.n == citem.n + 1 }
|
444
453
|
trn << [sitem, i] if citem.la.include? TLA
|
445
454
|
i.la.merge!(citem.la).delete(TLA)
|
446
455
|
end
|
447
456
|
end
|
448
457
|
end
|
449
458
|
|
450
|
-
warn
|
459
|
+
warn "** LALR(1) **" if Depager.debug_mode?
|
451
460
|
@states[0].items[0].la = @grammar.symset([grammar.nonterms.size]) # '$'
|
452
461
|
begin
|
453
462
|
changed = false
|
@@ -463,60 +472,62 @@ module Depager::LALR
|
|
463
472
|
end
|
464
473
|
|
465
474
|
class Depager::LALR::Table
|
466
|
-
|
467
|
-
@state_info
|
468
|
-
end
|
475
|
+
attr_reader :state_info
|
469
476
|
|
470
477
|
def gen_state_info
|
471
478
|
g = grammar
|
472
479
|
@state_info = []
|
473
|
-
@action_table.each_with_index
|
474
|
-
shi
|
475
|
-
|
480
|
+
@action_table.each_with_index do |s, x|
|
481
|
+
shi = ""
|
482
|
+
red = ""
|
483
|
+
acc = ""
|
484
|
+
s.each_with_index do |t, y|
|
476
485
|
next unless t
|
477
|
-
|
478
|
-
|
486
|
+
|
487
|
+
hd = format(" %-15s", g.symname(y + g.nonterms.size))
|
488
|
+
if t == "ACC"
|
479
489
|
acc = "#{hd} accept"
|
480
490
|
elsif t < 0
|
481
491
|
red << "#{hd} reduce using rule #{-t} (#{g.symname g[-t].lhs})\n"
|
482
492
|
else
|
483
493
|
shi << "#{hd} shift, and goto to state #{t}\n"
|
484
494
|
end
|
485
|
-
|
486
|
-
if t = @defred_table[x]
|
495
|
+
end
|
496
|
+
if (t = @defred_table[x])
|
487
497
|
as = @defred_after_shift_table[x] ? " [after shift]" : ""
|
488
|
-
red << (" %-15s"
|
498
|
+
red << format(" %-15s", "$default") <<
|
489
499
|
"reduce using rule #{-t} (#{g.symname g[-t].lhs}) #{as}"
|
490
500
|
end
|
491
501
|
|
492
502
|
@state_info << (@states[x].to_s << "\n\n#{shi}\n#{red}\n#{acc}").strip
|
493
|
-
|
503
|
+
end
|
494
504
|
end
|
495
505
|
|
496
|
-
def verbose
|
497
|
-
g
|
506
|
+
def verbose(dp)
|
507
|
+
g = grammar
|
508
|
+
output = []
|
498
509
|
|
499
510
|
if Depager.debug_mode?(:f)
|
500
511
|
output << "** FIRST1 **"
|
501
|
-
str = g.first1.map
|
502
|
-
"#{g.symname k} => #{v.map{|i| g.symname i}.join(' ')}"
|
503
|
-
|
512
|
+
str = g.first1.map do |k, v|
|
513
|
+
"#{g.symname k} => #{v.map { |i| g.symname i }.join(' ')}"
|
514
|
+
end.join("\n")
|
504
515
|
output << "#{str}\n\n"
|
505
516
|
end
|
506
517
|
|
507
518
|
if Depager.debug_mode?(:e)
|
508
519
|
output << "** Empty Reduction **"
|
509
|
-
str = g.f0e.map
|
510
|
-
"#{g.symname k} =>\n" << v.map
|
511
|
-
" #{rulelist[n]} ? #{f.map{|i| g.symname i}.join(' ')}"
|
512
|
-
|
513
|
-
|
520
|
+
str = g.f0e.map do |k, v|
|
521
|
+
"#{g.symname k} =>\n" << v.map do |n, f|
|
522
|
+
" #{rulelist[n]} ? #{f.map { |i| g.symname i }.join(' ')}"
|
523
|
+
end.join("\n")
|
524
|
+
end.join("\n")
|
514
525
|
output << "#{str}\n\n"
|
515
526
|
end
|
516
527
|
|
517
528
|
if Depager.debug_mode?(:s)
|
518
529
|
output << "** SYMBOLS **"
|
519
|
-
str = g.syms.map{|k,_| "#{
|
530
|
+
str = g.syms.map { |k, _| "#{format('%03i', k)} #{g.symname k}" }.sort.join("\n")
|
520
531
|
output << "#{str}\n\n"
|
521
532
|
end
|
522
533
|
|
@@ -535,40 +546,44 @@ class Depager::LALR::Table
|
|
535
546
|
nssize = g.nonterms.size
|
536
547
|
if Depager.debug_mode?(:t)
|
537
548
|
output << "*** Action Table ***"
|
538
|
-
ws = (nssize...g.syms.size).map
|
549
|
+
ws = (nssize...g.syms.size).map do |i|
|
550
|
+
j = g.symname(i).size
|
551
|
+
[j, 6].max
|
552
|
+
end
|
539
553
|
str = " |"
|
540
|
-
(nssize...g.syms.size).each_with_index
|
541
|
-
str << ("%0#{ws[x]}s|"
|
542
|
-
|
543
|
-
|
544
|
-
@action_table.each_with_index
|
545
|
-
str << ("%03i|"
|
546
|
-
i.each_with_index
|
547
|
-
str << ("%0#{ws[y]}s|"
|
548
|
-
|
549
|
-
str << ("%04s,%04s|\n"
|
550
|
-
|
554
|
+
(nssize...g.syms.size).each_with_index do |i, x|
|
555
|
+
str << format("%0#{ws[x]}s|", g.symname(i))
|
556
|
+
end; str << " $default|\n"
|
557
|
+
|
558
|
+
@action_table.each_with_index do |i, x|
|
559
|
+
str << format("%03i|", x)
|
560
|
+
i.each_with_index do |j, y|
|
561
|
+
str << format("%0#{ws[y]}s|", j)
|
562
|
+
end
|
563
|
+
str << (format("%04s,%04s|\n", @defred_table[x], @defred_after_shift_table[x]))
|
564
|
+
end
|
551
565
|
output << "#{str}\n\n"
|
552
566
|
|
553
|
-
output <<
|
554
|
-
ws = (1...nssize).map
|
567
|
+
output << "*** Goto Table ***"
|
568
|
+
ws = (1...nssize).map do |i|
|
569
|
+
j = g.symname(i).size
|
570
|
+
[j, 6].max
|
571
|
+
end
|
555
572
|
str = " |"
|
556
|
-
(1...nssize).each_with_index
|
557
|
-
str << ("%0#{ws[x]}s|"
|
558
|
-
|
559
|
-
|
560
|
-
@goto_table.each_with_index
|
561
|
-
str << ("%03i|"
|
562
|
-
i.each_with_index
|
563
|
-
str << ("%0#{ws[y]}s|"
|
564
|
-
|
573
|
+
(1...nssize).each_with_index do |i, x|
|
574
|
+
str << format("%0#{ws[x]}s|", g.symname(i))
|
575
|
+
end; str << "\n"
|
576
|
+
|
577
|
+
@goto_table.each_with_index do |i, x|
|
578
|
+
str << format("%03i|", x)
|
579
|
+
i.each_with_index do |j, y|
|
580
|
+
str << format("%0#{ws[y]}s|", j)
|
581
|
+
end
|
565
582
|
str << "\n"
|
566
|
-
|
583
|
+
end
|
567
584
|
output << "#{str}\n\n"
|
568
585
|
end
|
569
586
|
|
570
|
-
File.
|
571
|
-
f.write output.join("\n")
|
572
|
-
}
|
587
|
+
File.write("#{File.basename(dp.file.path, '.dr')}.output", output.join("\n"))
|
573
588
|
end
|
574
589
|
end
|