Neha13 commited on
Commit
95fd287
·
verified ·
1 Parent(s): 85e13ec

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +312 -0
app.py ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import copy
2
+ import streamlit as st
3
+
4
+ stateMap = {}
5
+ diction = {}
6
+ start_symbol = ""
7
+ rules = []
8
+ statesDict={}
9
+ stateCount = 0
10
+ separatedRulesList = []
11
+
12
+ def grammarAugmentation(rules, nonterm_userdef, start_symbol):
13
+ newRules = []
14
+ newChar = start_symbol + "'"
15
+ while (newChar in nonterm_userdef):
16
+ newChar += "'"
17
+ newRules.append([newChar, ['.', start_symbol]])
18
+ for rule in rules:
19
+ k = rule.split("->")
20
+ lhs = k[0].strip()
21
+ rhs = k[1].strip()
22
+ multirhs = rhs.split('|')
23
+ for rhs1 in multirhs:
24
+ rhs1 = rhs1.strip().split()
25
+ rhs1.insert(0, '.')
26
+ newRules.append([lhs, rhs1])
27
+ return newRules
28
+
29
+ def findClosure(input_state, dotSymbol):
30
+ global separatedRulesList
31
+
32
+ closureSet = []
33
+
34
+ if isinstance(input_state, int):
35
+ for rule in separatedRulesList:
36
+ if rule[0] == dotSymbol:
37
+ closureSet.append(rule)
38
+ else:
39
+ closureSet = input_state
40
+
41
+ prevLen = -1
42
+ while prevLen != len(closureSet):
43
+ prevLen = len(closureSet)
44
+
45
+ tempClosureSet = []
46
+ for rule in closureSet:
47
+ indexOfDot = rule[1].index('.')
48
+ if rule[1][-1] != '.':
49
+ dotPointsHere = rule[1][indexOfDot + 1]
50
+ for in_rule in separatedRulesList:
51
+ if dotPointsHere == in_rule[0] and in_rule not in tempClosureSet:
52
+ tempClosureSet.append(in_rule)
53
+
54
+ for rule in tempClosureSet:
55
+ if rule not in closureSet:
56
+ closureSet.append(rule)
57
+ return closureSet
58
+
59
+ def compute_GOTO(state):
60
+ global statesDict, stateCount
61
+ generateStatesFor = []
62
+ for rule in statesDict[state]:
63
+ if rule[1][-1] != '.':
64
+ indexOfDot = rule[1].index('.')
65
+ dotPointsHere = rule[1][indexOfDot + 1]
66
+ if dotPointsHere not in generateStatesFor:
67
+ generateStatesFor.append(dotPointsHere)
68
+ if len(generateStatesFor) != 0:
69
+ for symbol in generateStatesFor:
70
+ GOTO(state, symbol)
71
+ return
72
+
73
+ def GOTO(state, charNextToDot):
74
+ global statesDict, stateCount, stateMap
75
+ newState = []
76
+ for rule in statesDict[state]:
77
+ indexOfDot = rule[1].index('.')
78
+ if rule[1][-1] != '.':
79
+ if rule[1][indexOfDot + 1] == charNextToDot:
80
+ shiftedRule = copy.deepcopy(rule)
81
+ shiftedRule[1][indexOfDot] = shiftedRule[1][indexOfDot + 1]
82
+ shiftedRule[1][indexOfDot + 1] = '.'
83
+ newState.append(shiftedRule)
84
+
85
+ addClosureRules = []
86
+ for rule in newState:
87
+ indexDot = rule[1].index('.')
88
+ if rule[1][-1] != '.':
89
+ closureRes = findClosure(newState, rule[1][indexDot + 1])
90
+ for rule in closureRes:
91
+ if rule not in addClosureRules and rule not in newState:
92
+ addClosureRules.append(rule)
93
+
94
+ for rule in addClosureRules:
95
+ newState.append(rule)
96
+
97
+ stateExists = -1
98
+ for state_num in statesDict:
99
+ if statesDict[state_num] == newState:
100
+ stateExists = state_num
101
+ break
102
+
103
+ if stateExists == -1:
104
+ stateCount += 1
105
+ statesDict[stateCount] = newState
106
+ stateMap[(state, charNextToDot)] = stateCount
107
+ else:
108
+ stateMap[(state, charNextToDot)] = stateExists
109
+ return
110
+
111
+ def generateStates(I0):
112
+ global statesDict, stateCount
113
+
114
+ statesDict[0] = I0
115
+ stateCount = 0
116
+ prev_len = -1
117
+ called_GOTO_on = []
118
+ while (len(statesDict) != prev_len):
119
+ prev_len = len(statesDict)
120
+ keys = list(statesDict.keys())
121
+ for key in keys:
122
+ if key not in called_GOTO_on:
123
+ called_GOTO_on.append(key)
124
+ compute_GOTO(key)
125
+ return
126
+
127
+ def first(rule):
128
+ global diction, term_userdef
129
+ if len(rule) != 0 and (rule is not None):
130
+ if rule[0] in term_userdef:
131
+ return rule[0]
132
+ elif rule[0] == '#':
133
+ return '#'
134
+ if len(rule) != 0:
135
+ if rule[0] in list(diction.keys()):
136
+ fres = []
137
+ rhs_rules = diction[rule[0]]
138
+ for itr in rhs_rules:
139
+ indivRes = first(itr)
140
+ if type(indivRes) is list:
141
+ for i in indivRes:
142
+ fres.append(i)
143
+ else:
144
+ fres.append(indivRes)
145
+
146
+ if '#' not in fres:
147
+ return fres
148
+ else:
149
+ newList = []
150
+ fres.remove('#')
151
+ if len(rule) > 1:
152
+ ansNew = first(rule[1:])
153
+ if ansNew != None:
154
+ if type(ansNew) is list:
155
+ newList = fres + ansNew
156
+ else:
157
+ newList = fres + [ansNew]
158
+ else:
159
+ newList = fres
160
+ return newList
161
+ fres.append('#')
162
+ return fres
163
+
164
+ def follow(nt):
165
+ global start_symbol, diction
166
+ solset = set()
167
+ if nt == start_symbol:
168
+ solset.add('$')
169
+ for curNT in diction:
170
+ rhs = diction[curNT]
171
+ for subrule in rhs:
172
+ if nt in subrule:
173
+ while nt in subrule:
174
+ index_nt = subrule.index(nt)
175
+ subrule = subrule[index_nt + 1:]
176
+ if len(subrule) != 0:
177
+ res = first(subrule)
178
+ if '#' in res:
179
+ newList = []
180
+ res.remove('#')
181
+ ansNew = follow(curNT)
182
+ if ansNew != None:
183
+ if type(ansNew) is list:
184
+ newList = res + ansNew
185
+ else:
186
+ newList = res + [ansNew]
187
+ else:
188
+ newList = res
189
+ res = newList
190
+ else:
191
+ if nt != curNT:
192
+ res = follow(curNT)
193
+
194
+ if res is not None:
195
+ if type(res) is list:
196
+ for g in res:
197
+ solset.add(g)
198
+ else:
199
+ solset.add(res)
200
+ return list(solset)
201
+
202
+ def createParseTable(statesDict, stateMap, T, NT):
203
+ global separatedRulesList, diction
204
+
205
+ parse_table = {i: {} for i in range(len(statesDict))}
206
+
207
+ for (state, symbol) in stateMap:
208
+ if symbol in T:
209
+ parse_table[state][symbol] = f'S{stateMap[(state, symbol)]}'
210
+ elif symbol in NT:
211
+ parse_table[state][symbol] = str(stateMap[(state, symbol)])
212
+
213
+ for state in statesDict:
214
+ for item in statesDict[state]:
215
+ if item[1][-1] == '.':
216
+ prod = f"{item[0]} -> {' '.join(item[1][:-1])}"
217
+
218
+ if prod == f"{separatedRulesList[0][0]} -> {separatedRulesList[0][1][1]}":
219
+ parse_table[state]['$'] = 'ACC'
220
+ else:
221
+ rule_index = next(
222
+ (i for i, rule in enumerate(separatedRulesList) if rule == item),
223
+ None
224
+ )
225
+
226
+ if rule_index is None:
227
+ print(f"Warning: Rule for item {item} not found in separatedRulesList.")
228
+ continue
229
+
230
+ for symbol in T + ['$']:
231
+ if symbol not in parse_table[state]:
232
+ parse_table[state][symbol] = f'R{rule_index}'
233
+
234
+ return parse_table
235
+
236
+
237
+ def main():
238
+ st.title("SLR(1) Parser Generator")
239
+
240
+ st.header("Grammar Input")
241
+ rules = st.text_area("Enter the grammar rules (one per line):",
242
+ "E -> E + T | T\nT -> T * F | F\nF -> ( E ) | id")
243
+ rules = rules.split('\n')
244
+
245
+ nonterm_userdef = st.text_input("Enter the non-terminal symbols (separated by space):", "E T F")
246
+ nonterm_userdef = nonterm_userdef.split()
247
+
248
+ term_userdef = st.text_input("Enter the terminal symbols (separated by space):", "id + * ( )")
249
+ term_userdef = term_userdef.split()
250
+
251
+ start_symbol = st.text_input("Enter the start symbol:", "E")
252
+
253
+ if st.button("Generate SLR(1) Parser"):
254
+ st.subheader("Original Grammar Input:")
255
+ for rule in rules:
256
+ st.write(rule)
257
+
258
+ st.subheader("Grammar after Augmentation:")
259
+ global separatedRulesList
260
+ separatedRulesList = grammarAugmentation(rules, nonterm_userdef, start_symbol)
261
+ for rule in separatedRulesList:
262
+ st.write(f"{rule[0]} -> {' '.join(rule[1])}")
263
+
264
+ start_symbol = separatedRulesList[0][0]
265
+ st.subheader("Calculated Closure: I0")
266
+ I0 = findClosure(0, start_symbol)
267
+
268
+ st.write("I0:")
269
+ for rule in I0:
270
+ st.write(f"{rule[0]} -> {' '.join(rule[1])}")
271
+
272
+ generateStates(I0)
273
+
274
+ st.subheader("Generated States:")
275
+ for state, rules in statesDict.items():
276
+ st.write(f"I{state}:")
277
+ for rule in rules:
278
+ st.write(f" {rule[0]} -> {' '.join(rule[1])}")
279
+ st.write("")
280
+
281
+ st.subheader("SLR(1) Parsing Table")
282
+ table = createParseTable(statesDict, stateMap, term_userdef, nonterm_userdef)
283
+
284
+ cols = ['State'] + term_userdef + ['$'] + nonterm_userdef
285
+ table_data = []
286
+ for state in range(len(statesDict)):
287
+ row = [f'I{state}']
288
+ for symbol in term_userdef + ['$'] + nonterm_userdef:
289
+ row.append(table[state].get(symbol, ''))
290
+ table_data.append(row)
291
+
292
+ st.table([cols] + table_data)
293
+
294
+ compact_table = "State`" + '`'.join(term_userdef + ['$'] + nonterm_userdef) + '`'
295
+ for state in range(len(statesDict)):
296
+ compact_table += f"I{state}"
297
+ for symbol in term_userdef + ['$'] + nonterm_userdef:
298
+ compact_table += table[state].get(symbol, '')
299
+ st.subheader("Follow Sets")
300
+ follow_sets = {}
301
+ for nt in nonterm_userdef:
302
+ follow_set = follow(nt)
303
+ follow_sets[nt] = follow_set
304
+ st.write(f"Follow({nt}): {{ {' , '.join(follow_set)} }}")
305
+ compact_follow = "Non-Terminal`Follow Set\n"
306
+ for nt, follow_set in follow_sets.items():
307
+ compact_follow += f"{nt}`{{ {' , '.join(follow_set)} }}\n"
308
+
309
+ st.text_area("Compact Follow Sets Representation:", value=compact_follow, height=300)
310
+
311
+ if __name__ == "__main__":
312
+ main()