blob: 948d8c1077ed42d6468d0b51887c2369b3aa1ac4 (
plain)
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#!/usr/bin/env ruby
class Item
attr_accessor :word, :type, :link
def initialize word, type
@word = word
@type = type
@link = nil
end
end
class MockShiftReduceParser
attr_accessor :state
def initialize
@state = nil
@a = {}
@a[nil] = {}
@a[nil][nil] = 'S'
@a[nil]['f'] = 'S'
@a[nil]['l'] = 'S'
@a[nil]['r'] = 'illegal'
@a['f'] = {}
@a['f']['f'] = 'S' # FIXME conflict
@a['f']['l'] = 'S'
@a['f']['r'] = 'R'
@a['l'] = {}
@a['l']['f'] = 'L'
@a['l']['l'] = 'S'
@a['l']['r'] = 'illegal'
@a['r'] = {}
@a['r']['f'] = 'illegal'
@a['r']['l'] = 'illegal'
@a['r']['r'] = 'illegal'
end
def advance type
if !@state
@state = type
puts "-/- -> S -> #{@state}"
return
end
action = @a[@state][type]
prev_state = @state
if action == 'S'
@state = type
elsif action == 'L' or action == 'R'
@state = 'f'
end
puts "#{prev_state}/#{type} -> #{action} -> #{@state}"
return action
end
end
parser = MockShiftReduceParser.new
items = []
head = nil
stack = []
while line = STDIN.gets
word, type = line.split
item = Item.new word, type
items << item
stack << item
head = item if !head
action = parser.advance item.type
if action == "S"
head = item
elsif action == "R"
_ = stack.pop
_.link = head
elsif action == "L"
head = item
puts stack.size
del = []
stack.each_with_index { |i,j|
if i.type == 'l'
i.link = head
del << j
end
}
del.reverse.each { |d| stack.delete_at(d) }
puts stack.size
end
end
stack.each { |i| i.link = head }
puts "---"
items.each { |j| if j.link then puts "#{j.word} #{j.link.word}" else puts "#{j.word} ?" end }
|