1
+ from pprint import pprint
2
+ from sys import exit
3
+ def add (listA ,x ):
4
+ if x not in listA : listA .append (x )
5
+ def import_grammar (fileHandle ):
6
+ G ,T ,Nt = [],[],[]
7
+ for lines in fileHandle :
8
+ production = lines .split (' -> ' )
9
+ if production [0 ] not in Nt : Nt .append (production [0 ])
10
+ listStr = list (production [1 ])
11
+ del listStr [- 1 ]
12
+ production [1 ] = '' .join (i for i in listStr )
13
+ for char in production [1 ]:
14
+ if 65 <= ord (char ) and ord (char )<= 90 :
15
+ if char not in Nt : Nt .append (char )
16
+ else :
17
+ if char not in T : T .append (char )
18
+ if production not in G : G .append ((production [0 ],production [1 ]))
19
+ T .append ('$' )
20
+ return G ,T ,Nt
21
+ def first_set (G ,T ,Nt ):
22
+ firstA = {}
23
+ tempA = {}
24
+ for NonT in Nt : firstA [NonT ] = []
25
+ while True :
26
+ for NonT in firstA :
27
+ tempA [NonT ] = [i for i in firstA [NonT ]]
28
+ for i in range (len (G )):
29
+ if G [i ][1 ] == '' : add (tempA [G [i ][0 ]],'' )
30
+ elif G [i ][1 ][0 ] in Nt :
31
+ if '' not in firstA [G [i ][1 ][0 ]]:
32
+ for k in firstA [G [i ][1 ][0 ]]: add (tempA [G [i ][0 ]],k )
33
+ else :
34
+ listA = [ k for k in firstA [G [i ][1 ][0 ]] ]
35
+ r = listA .index ('' )
36
+ del listA [r ]
37
+ for k in listA : add (tempA [G [i ][0 ]],k )
38
+ add (tempA [G [i ][0 ]],'' )
39
+ elif G [i ][1 ][0 ] in T : add (tempA [G [i ][0 ]],G [i ][1 ][0 ])
40
+ flag = True
41
+ for NonT in Nt : flag = flag and (tempA [NonT ] == firstA [NonT ])
42
+ if flag : break
43
+ for NonT in Nt : firstA [NonT ] = [i for i in tempA [NonT ]]
44
+ return firstA
45
+ def closure (I ,G ,T ,Nt ):
46
+ J = [p for p in I ]
47
+ first_set_list = first_set (G ,T ,Nt )
48
+ while True :
49
+ J1 = [x for x in J ]
50
+ for x in J1 :
51
+ handle = list (x [1 ])
52
+ a = x [2 ]
53
+ k = handle .index ('.' )
54
+ if k + 1 != len (handle ):
55
+ if handle [k + 1 ] in Nt :
56
+ for p in G :
57
+ beta = '' .join (handle [m ] for m in range (k + 2 ,len (handle )))
58
+ b1 = list (beta + a )[0 ]
59
+ if p [0 ] == handle [k + 1 ]:
60
+ if b1 in T :
61
+ new_p = (p [0 ],'.' + p [1 ],b1 )
62
+ if new_p not in J1 : J1 .append (new_p )
63
+ elif b1 in Nt :
64
+ for b in first_set_list [b1 ]:
65
+ new_p = (p [0 ],'.' + p [1 ],b if b != '' else '$' )
66
+ if new_p not in J1 : J1 .append (new_p )
67
+ flag = True
68
+ for x in J1 :
69
+ if x not in J :
70
+ flag = False
71
+ J .append (x )
72
+ if flag : break
73
+ return J
74
+ def goto (I ,G ,X ,T ,Nt ):
75
+ W = []
76
+ for x in I :
77
+ handle = list (x [1 ])
78
+ k = handle .index ('.' )
79
+ if k != len (handle )- 1 :
80
+ if handle [k + 1 ] == X :
81
+ S1 = '' .join ([handle [i ] for i in range (k )])
82
+ S2 = '' .join ([handle [i ] for i in range (k + 2 ,len (handle ))])
83
+ W .append ((x [0 ],S1 + X + '.' + S2 ,x [2 ]))
84
+ return closure (W ,G ,T ,Nt )
85
+ def items (G ,T ,Nt ):
86
+ C = [ closure ([(G [0 ][0 ],'.' + G [0 ][1 ],'$' )],G ,T ,Nt ) ]
87
+ action = {}
88
+ goto_k = {}
89
+ reduction_states = {}
90
+ while True :
91
+ C1 = [ I for I in C ]
92
+ for I in C1 :
93
+ for X in T :
94
+ goto_list = goto (I ,G ,X ,T ,Nt )
95
+ if len (goto_list )!= 0 and goto_list not in C1 :
96
+ C1 .append (goto_list )
97
+ if C1 .index (I ) not in action : action [C1 .index (I )] = {}
98
+ if X not in action [C1 .index (I )]:
99
+ action [C1 .index (I )][X ] = C1 .index (goto_list )
100
+ elif goto_list in C1 :
101
+ if C1 .index (I ) not in action : action [C1 .index (I )] = {}
102
+ if X not in action [C1 .index (I )]:
103
+ action [C1 .index (I )][X ] = C1 .index (goto_list )
104
+ for I in C1 :
105
+ for X in Nt :
106
+ goto_list = goto (I ,G ,X ,T ,Nt )
107
+ if len (goto_list )!= 0 and goto_list not in C1 :
108
+ C1 .append (goto_list )
109
+ if C1 .index (I ) not in goto_k : goto_k [C1 .index (I )] = {}
110
+ if X not in goto_k [C1 .index (I )]:
111
+ goto_k [C1 .index (I )][X ] = C1 .index (goto_list )
112
+ elif goto_list in C1 :
113
+ if C1 .index (I ) not in goto_k : goto_k [C1 .index (I )] = {}
114
+ if X not in goto_k [C1 .index (I )]:
115
+ goto_k [C1 .index (I )][X ] = C1 .index (goto_list )
116
+ flag = True
117
+ for x in C1 :
118
+ if x not in C :
119
+ flag = False
120
+ C .append (x )
121
+ if flag : break
122
+ for state in range (len (C )):
123
+ reduction_states [state ] = {}
124
+ for production in C [state ]:
125
+ if production [1 ][len (production [1 ])- 1 ] == '.' :
126
+ rhs = list (production [1 ])
127
+ del rhs [- 1 ]
128
+ rhsStr = '' .join (i for i in rhs )
129
+ Pp = (production [0 ],rhsStr )
130
+ reduction_states [state ][production [2 ]] = Pp
131
+ accept_state = 0
132
+ for x in reduction_states :
133
+ if '$' in reduction_states [x ]:
134
+ if reduction_states [x ]['$' ] == G [0 ]:
135
+ accept_state = x
136
+ break
137
+ return action ,goto_k ,reduction_states ,accept_state
138
+ def driver ():
139
+ fileHandle = open ('grammar14.txt' )
140
+ G ,T ,Nt = import_grammar (fileHandle )
141
+ print T ,Nt
142
+ action_list ,goto_list ,reduction_states ,accept_state = items (G ,T ,Nt )
143
+ print 'Action list'
144
+ pprint (action_list )
145
+ print 'Goto list'
146
+ pprint (goto_list )
147
+ print 'Reduction states'
148
+ pprint (reduction_states )
149
+ print 'Accept state' ,accept_state
150
+ stack = [0 ]
151
+ input_str = raw_input ('Enter some string ' )+ '$'
152
+ i ,top = 0 ,0
153
+ # LR(1) AUTOMATON PARSING
154
+ while True :
155
+ s = stack [top ]
156
+ try :
157
+ print s ,stack ,input_str [i ] if i != len (input_str ) else 'Finish' ,
158
+ if s == accept_state and input_str [i ]== '$' :
159
+ print 'accept'
160
+ break
161
+ elif len (reduction_states [s ]) != 0 and input_str [i ] in reduction_states [s ]:
162
+ A ,beta = reduction_states [s ][input_str [i ]]
163
+ print 'reduce' ,A ,'->' ,beta
164
+ for j in range (len (beta )): del stack [top ]
165
+ t = stack [top ]
166
+ stack .insert (top ,goto_list [t ][A ])
167
+ else :
168
+ a = input_str [i ]
169
+ stack .insert (top ,action_list [s ][a ])
170
+ print 'shift' ,action_list [s ][a ]
171
+ i = i + 1
172
+ except :
173
+ print 'Syntax error'
174
+ break
175
+ driver ()
0 commit comments