
语法规则:
- E → E * B
- E → E + B
- E → B
- B → 0
- B → 1
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/python
# LR(0) Parsing:
# Rule:
# (1) E -> E * B
# (2) E -> E + B
# (3) E -> B
# (4) B -> 0
# (5) B -> 1
################################################################
import sys
from pprint import pprint
DEBUG = 1
def print_table(tbl):
for i in tbl:
print ' -> '.join(i)
rules = [
('S' , 'E'), # Rule 0 : S -> E
('E' , 'E*B'), # Rule 1 : E -> E * B
('E' , 'E+B'), # Rule 2 : E -> E + B
('E' , 'B'), # Rule 3 : E -> B
('B' , '0'), # Rule 4 : B -> 0
('B' , '1'), # Rule 5 : B -> 1
]
goto_table = [
{'E' : 3, 'B' : 4}, #S0
{'E' : -1, 'B' : -1}, #S1 -1 indicate an error occured
{'E' : -1, 'B' : -1}, #S2
{'E' : -1, 'B' : -1}, #S3
{'E' : -1, 'B' : -1}, #S4
{'E' : -1, 'B' : 7}, #S5
{'E' : -1, 'B' : 8}, #S6
{'E' : -1, 'B' : -1}, #S7
{'E' : -1, 'B' : -1}, #S8
]
action_table = [
{'*' : 'er', '+' : 'er', '0' : 's1', '1' : 's2', '$' : 'er'}, #S0
{'*' : 'r4', '+' : 'r4', '0' : 'r4', '1' : 'r4', '$' : 'r4'}, #S1
{'*' : 'r5', '+' : 'r5', '0' : 'r5', '1' : 'r5', '$' : 'r5'}, #S2
{'*' : 's5', '+' : 's6', '0' : 'er', '1' : 'er', '$' : 'ac'}, #S3
{'*' : 'r3', '+' : 'r3', '0' : 'r3', '1' : 'r3', '$' : 'r3'}, #S4
{'*' : 'er', '+' : 'er', '0' : 's1', '1' : 's2', '$' : 'er'}, #S5
{'*' : 'er', '+' : 'er', '0' : 's1', '1' : 's2', '$' : 'er'}, #S6
{'*' : 'r1', '+' : 'r1', '0' : 'r1', '1' : 'r1', '$' : 'r1'}, #S7
{'*' : 'r2', '+' : 'r2', '0' : 'r2', '1' : 'r2', '$' : 'r2'}, #S8
]
# initial:
rpt = 0 # input read pointer
state = 0
stack = [0]
def shift(s):
global rpt
global state
state = s
stack.append(s)
rpt += 1
if DEBUG:
print "shift", s, '[stack:]', stack, '[rpt:]', rpt
def reduce(r):
global state
rule = rules[r]
if DEBUG : print 'rule[%d]: %s' % (r, rule)
left, right = rule
for i in range(len(right)):
stack.pop()
state = stack[-1]
if DEBUG : print 'GOTO[%d][%s] :=> %d' % (state, left, goto_table[state][left])
state = goto_table[state][left]
if state < 0 : err(); sys.exit(1)
stack.append(state)
if DEBUG:
print "reduce", r, '[stack:]', stack, '[rpt:]', rpt
def accept():
global rpt
rpt += 1
print 'accept', '[stack:]', stack, '[rpt:]', rpt
def err():
global rpt
rpt += 1
print 'Error', '[stack:]', stack, '[rpt:]', rpt
def lr_parse(inputs) :
global rpt
global state
global stack
state = 0
stack = [0]
rpt = 0
while rpt <= len(inputs):
if rpt == len(inputs) : token = '$'
else : token = inputs[rpt]
print '-'*64
if DEBUG : print 'state: ', state, 'token:', token
action = action_table[state][token]
if DEBUG : print 'action: ', action
if action[0] == 's' : # shift
shift( int(action[1]) )
elif action[0] == 'r' : # reduce
reduce( int(action[1]) )
elif action == 'ac' : # accept
accept()
break
elif action == 'er' : # error
err()
break
else :
err()
break
if __name__ == '__main__':
print "rules = "
print_table(rules)
print "action_table = "
pprint(action_table)
print "ngoto_table = "
pprint( goto_table)
lr_parse('1+1')
print '*'*64
lr_parse("1+0*1")




近期评论