depager 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/ChangeLog +4 -0
  2. data/README.en +5 -10
  3. data/bin/depager +17 -20
  4. data/examples/c89/c89.tab.rb +5632 -702
  5. data/examples/pl0d/pl0ds.dr +41 -41
  6. data/examples/pl0d/pl0ds.tab.rb +1887 -874
  7. data/examples/sample_calc/calc.action.tab.rb +243 -69
  8. data/examples/sample_calc/{calc.astl.action.dr → calc.ast.action.dr} +7 -7
  9. data/examples/sample_calc/calc.ast.action.tab.rb +755 -0
  10. data/examples/sample_calc/{calc.astl.dr → calc.ast.dr} +7 -7
  11. data/examples/sample_calc/calc.ast.tab.rb +672 -0
  12. data/examples/sample_calc/calc.astdf.dr +5 -5
  13. data/examples/sample_calc/calc.astdf.tab.rb +405 -202
  14. data/examples/sample_calc/calc.atree.tab.rb +243 -69
  15. data/examples/sample_calc/calc.cst.tab.rb +275 -109
  16. data/examples/sample_calc/calc.lex.tab.rb +210 -28
  17. data/examples/sample_calc/calc.nvaction.tab.rb +251 -77
  18. data/examples/sample_calc/calc.tab.rb +210 -28
  19. data/examples/sample_calc/calc_prec.nvaction.tab.rb +224 -50
  20. data/examples/slex_test/divreg.slex.tab.rb +97 -21
  21. data/examples/slex_test/ljoin.slex.tab.rb +128 -35
  22. data/lib/depager.rb +77 -44
  23. data/lib/depager/{ast_base.dr → ast.dr} +56 -18
  24. data/lib/depager/{ast_base.rb → ast.rb} +432 -424
  25. data/lib/depager/astdf.rb +3 -6
  26. data/lib/depager/atree.rb +54 -62
  27. data/lib/depager/cst.dr +2 -2
  28. data/lib/depager/cst.rb +64 -77
  29. data/lib/depager/grammar.rb +225 -66
  30. data/lib/depager/lex.dr +1 -1
  31. data/lib/depager/lex.rb +45 -54
  32. data/lib/depager/lr.rb +181 -262
  33. data/lib/depager/lr_put_table.rb +116 -0
  34. data/lib/depager/nvaction.rb +1 -1
  35. data/lib/depager/parser.rb +23 -2
  36. data/lib/depager/slex.dr +3 -3
  37. data/lib/depager/slex.rb +148 -169
  38. data/lib/depager/srp.rb +1 -1
  39. data/lib/depager/template/ast.erbs +69 -0
  40. data/lib/depager/template/extension_lalr_master.erb +3 -3
  41. data/lib/depager/template/extension_lalr_slave.erb +7 -7
  42. data/lib/depager/template/simple.erb +4 -2
  43. data/lib/depager/template/single_lalr_parser.erb +30 -10
  44. data/lib/depager/utils.rb +10 -9
  45. data/lib/depager/version.rb +2 -8
  46. metadata +10 -11
  47. data/examples/sample_calc/calc.astl.action.tab.rb +0 -593
  48. data/examples/sample_calc/calc.astl.tab.rb +0 -501
  49. data/lib/depager/astl.rb +0 -14
  50. data/lib/depager/template/astdf.erbs +0 -57
  51. data/lib/depager/template/astl.erbs +0 -57
@@ -20,129 +20,123 @@ module Depager::LALR
20
20
  end
21
21
  end
22
22
 
23
- Eps = Depager::ParsingMethodCommon::G::Eps
24
- class Grammar < Depager::ParsingMethodCommon::G
25
- attr_accessor :closure, :memo_closure1
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
- @closure = {}
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
- cnt = false
42
+ changed = false
35
43
  @rulelist.each do |rule|
36
- rl = rule.l
37
- if r0f0e = @f0e[rule.r[0]]
38
- @f0e[rl] = {} unless @f0e[rl]
39
- r0f0e.each do |ern, fst|
40
- unless @f0e[rl][ern]
41
- if fst.include? Eps
42
- @f0e[rl][ern] = fst - [Eps] + first(rule.r[1...rule.r.size])
43
- else
44
- @f0e[rl][ern] = fst
45
- end
46
- cnt = true
47
- else
48
- if fst.include? Eps
49
- tf = fst - [Eps] + first(rule.r[1...rule.r.size])
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 cnt
63
- end
64
- end
65
- class Rule < Depager::ParsingMethodCommon::Rule
66
- def initialize_depend
61
+ end while changed
67
62
  end
68
- def closure1 n, la
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
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
- _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}"
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[_Brule.n] = LRItem[_Brule, 0, b]
97
- _I << li
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
- @g.memo_closure1[key] = _I
103
- _I
95
+
96
+ result.uniq!
97
+ @memo_closure1[key] = result
104
98
  end
105
99
 
106
- def closure n, base=nil
107
- i = 0
108
- j = [base ? base : LRItem[self, n]]
109
- s = {}
110
-
111
- while i < j.size
112
- ji = j[i].rule.r[j[i].n]
113
- if @g.nonterms?(ji) && !s[ji]
114
- s[ji] = true
115
- if @g.closure[ji]
116
- j.concat @g.closure[ji]
117
- else
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
- j
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
- @goto = {}
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
- (@rule.hash % 37) * (@n.hash % 37)
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 = @la.map{|i| @rule.g.syms[i] ? @rule.g.syms[i] : '$'}.join(' ')
154
- r = @rule.r.map{|i| @rule.g.syms[i]}.insert(@n, '_').join(' ')
155
-
156
- "(#{'%03s'%@rule.n}) #{@rule.g.syms[@rule.l]} : #{r} # #{la}"
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.r[@n]
162
+ @rule.rhs[@n]
174
163
  end
175
164
  def dotrest
176
- @rule.r[@n+1 .. -1]
165
+ @rule.rhs[@n+1 .. -1]
177
166
  end
178
167
  end
179
168
 
180
- class I
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 @hash if @hash
192
- @hash = @items.hash
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"+" "*7)
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
- I.new items
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.r.size
224
- r[c.rule.r[c.n]].push LRItem[c.rule, c.n+1]
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] = I.new(v))]
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] || I.new([])
222
+ return @goto[x] || State.new([])
235
223
  end
236
224
  end
237
225
 
238
226
  class Table
239
- attr_accessor :g, :action_table, :goto_table
227
+ attr_accessor :grammar, :action_table, :goto_table, :states
240
228
  attr_accessor :defred_table, :defred_after_shift_table
241
- def initialize g
242
- @g = g
243
- @c = nil
244
- @warnings = []
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 '** mk LR(0) **' if $MP_DEBUG
240
+ warn '** LR(0) **' if $MP_DEBUG
256
241
  n = 0
257
242
  m = 0
258
- c = [ I.new([ LRItem[@g[0], 0] ], 0) ]
259
- h = {c[0] => m}
243
+ states = [ State.new([ LRItem[grammar[0], 0] ], 0) ]
244
+ memo = {states[0] => m}
260
245
 
261
- while n < c.size
262
- c[n].mkgoto.each do|x, a|
246
+ while n < states.size
247
+ states[n].mkgoto.each do |x, a|
263
248
  unless a.empty?
264
- if ha = h[a]
265
- c[n].gg[x] = c[ha]
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
- c[m] = a
270
- h[a] = m
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
- @c = c
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 = @g.precs
266
+ precs = grammar.precs
282
267
  psh = precs[sh]
283
- mrt = @g[rd].r.reverse.find{|i| @g.terms?(i) }
284
- prd = @g[rd].prec || precs[mrt]
268
+ mrt = grammar[rd].rhs.reverse.find{|i| grammar.terms?(i) }
269
+ prd = grammar[rd].prec || precs[mrt]
285
270
 
286
- # warn "#{@g.syms[sh]} #{psh.inspect}"
287
- # warn "#{@g[rd]} #{prd.inspect}"
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
- @warnings << "'ACC' conflict #{g}."
296
+ @warning_list << "'ACC' conflict #{g}."
309
297
  return oldv
310
298
  end
311
- # warn "\n-- N:#{newv} O:#{oldv} K:#{@g.syms[key]} "
299
+ # warn "\n-- N:#{newv} O:#{oldv} K:#{grammar.syms[key]} "
312
300
  if newv < 0 and oldv > 0
313
- # warn "-:shift #{@g.syms[key]} go to #{oldv}"
301
+ # warn "-:shift #{grammar.syms[key]} go to #{oldv}"
314
302
  r = resolveconf(key, -newv)
315
303
  if r > 0
316
- # warn "+:shift #{@g.syms[key]} go to #{oldv}"
304
+ # warn "+:shift #{grammar.syms[key]} go to #{oldv}"
317
305
  oldv
318
306
  elsif r < 0
319
- # warn "+:reduce #{@g[-newv]}"
307
+ # warn "+:reduce #{grammar[-newv]}"
320
308
  newv
321
309
  else
322
- @warnings << "shift/reduce conflict '#{@g.syms[key]}'\n#{g}."
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
- @warnings << "shift/reduce conflict\n#{g}."
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
- if newv == oldv
339
- warn "?? newv == oldv == #{newv}."
340
- newv
341
- else
342
- @warnings << "reduce/reduce conflict\n#{g}."
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 '** mk TABLE **' if $MP_DEBUG
353
- taction = (0...@c.size).map{ Array.new(@g.syms.size - @g.nssize) }
354
- tgoto = (0...@c.size).map{ Array.new(@g.nssize - 1) }
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
- @c.each_with_index do |c, i|
350
+ @states.each_with_index do |c, i|
357
351
  c.gg.each do |k, j|
358
352
  next unless k
359
- if @g.terms? k
360
- key = k - @g.nssize
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.r.size and j.rule.l != 0 # $start
361
+ if j.n == j.rule.rhs.size and j.rule.lhs != 0 # $start
368
362
  j.la.each do |u|
369
- key = u - @g.nssize
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 = @g.f0e[j.rule.r[j.n]]
366
+ elsif efs = grammar.f0e[j.dotsym]
373
367
  efs.each do |rn, ef|
374
368
  ef.each do |es|
375
- #fst = @g.first([es] + j.rule.r[j.n+1 ... j.rule.r.size] + [j.la])
376
- _h = [es].concat(j.rule.r[j.n+1 ... j.rule.r.size]).push(j.la)
377
- @g.first(_h).each do |u|
378
- key = u - @g.nssize
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 == @g[0] && j.n == 1 # $start : ...
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
- @warnings.each{|i| dp.warning i }
426
- end
427
-
428
- def put_table
429
- syms, first1, f0e, rulelist = @g.syms, @g.first1, @g.f0e, @g.rulelist
430
-
431
- s = syms.map{|i| "#{"%03i"%i[0]} #{i[1].inspect}"}.sort.join("\n")
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 '** cal LA **' if $MP_DEBUG
430
+ warn '** LA **' if $MP_DEBUG
497
431
  trn = []
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)]
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
- #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")}"}
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
- change = false
527
- trn.each do |k, v, _|
528
- k.la.each do |i|
529
- unless v.la.include? i
530
- change = true
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 change
454
+ end while changed
536
455
  end
537
456
  end
538
457
  end