-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLL(1)_parsingTable_Parser.py
132 lines (92 loc) · 3.54 KB
/
LL(1)_parsingTable_Parser.py
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
#!/usr/bin/env python
# coding: utf-8
# In[154]:
#for printing terminals, non_terminals and their entries in Parsing_table
def print_(table):
ffs.print_rules(rules);
ffs.print_FFset(firstSet,True);
ffs.print_FFset(followSet,False);
terminals=set()
for nt in rules.keys():
terminals=terminals.union(firstSet[nt])
terminals=terminals.union(followSet[nt])
terminals.discard('eps')
print("\nNon Terminals:\n",rules.keys())
print("\nTerminals:\n",terminals)
print("\n\nTable entries are:\n")
for row,col in table.items():
print(row,':',col)
print()
return
def get_parsing_table(firstSet,followSet,rules):
parsing_table=defaultdict()
table=defaultdict() #just for printing in good way (can be done by parsing_table too)
for key,rule in rules.items():
for sub_rule in rule:
symbol = sub_rule[0]
if ffs.isNonTerminal(symbol,rules):
for ter in firstSet[symbol]-{'eps'}:
parsing_table[key,ter]={key:sub_rule}
table[key,ter]=key+'-> '+' '.join(i for i in sub_rule)
elif symbol=="eps" or symbol in deepcopy(firstSet[symbol]):
for ter in followSet[key]:
parsing_table[key,ter] = {key:['eps']}
table[key,ter]=key+'-> '+'eps'
else:
parsing_table[key,symbol]={key:sub_rule}
table[key,symbol]=key+'-> '+' '.join(i for i in sub_rule)
print_(table) #for printing terminals, non_terminals and their entries in Parsing_table
return parsing_table
# In[155]:
def parser(p_table,start_state):
expr = list(map(str,input("Enter expression for prasing(Plz enter space between 2 entry)\n").split()))
if expr[-1] != '$':
print("\nPlease add '$' at the end of expression. Try again")
return
print("\nyour expression is",expr)
stack=['$'];stack.append(start_state)
inp=0
while(stack and expr[inp]):
popped = stack.pop()
while (popped=='eps'): #when popped is epsilon then again pop
popped = stack.pop()
if popped != expr[inp]:
if p_table.get((popped,expr[inp])): #for checking, this entry is in table or not ?
rule = p_table.get((popped,expr[inp])).get(popped) # 2D dict table is again 1D dict with that rule
for x in range(len(rule)):
stack.append(rule[-x-1]) # minus for reversing
else:
print("\nError, the expression is wrong. Try again")
return
else:
inp+=1
if stack[0]==expr[inp]:
flag=True
break
if flag:
print("\nExpression accepted")
else:
print("\nExpression rejected, it can't be generated from this grammar")
return
# In[156]:
import First_Follow_sets as ffs
from collections import defaultdict
from copy import deepcopy
if __name__=="__main__":
rules,start_state=ffs.get_rules()
firstSet = ffs.get_first_set(rules)
followSet = ffs.get_follow_set(rules,deepcopy(firstSet),start_state)
parsing_table = get_parsing_table(deepcopy(firstSet),deepcopy(followSet),rules)
parser(parsing_table,start_state)
# print(parsing_table)
# In[157]:
parser(parsing_table,start_state)
# In[159]:
parser(parsing_table,start_state)
# In[161]:
parser(parsing_table,start_state)
# In[162]:
parser(parsing_table,start_state)
# In[163]:
parser(parsing_table,start_state)
# In[ ]: