cc1 / app.py
Neha13's picture
Create app.py
4290b1a verified
raw
history blame
7.19 kB
import streamlit as st
rules = []
nonterm_userdef = []
term_userdef = []
diction = {}
firsts = {}
follows = {}
start_symbol = None
def removeLeftRecursion(rulesDiction):
store = {}
for lhs in rulesDiction:
alphaRules = []
betaRules = []
allrhs = rulesDiction[lhs]
for subrhs in allrhs:
if subrhs[0] == lhs:
alphaRules.append(subrhs[1:])
else:
betaRules.append(subrhs)
if len(alphaRules) != 0:
lhs_ = lhs + "'"
while lhs_ in rulesDiction.keys() or lhs_ in store.keys():
lhs_ += "'"
for b in range(len(betaRules)):
betaRules[b].append(lhs_)
rulesDiction[lhs] = betaRules
for a in range(len(alphaRules)):
alphaRules[a].append(lhs_)
alphaRules.append(['#'])
store[lhs_] = alphaRules
for left in store:
rulesDiction[left] = store[left]
return rulesDiction
def LeftFactoring(rulesDiction):
newDict = {}
for lhs in rulesDiction:
allrhs = rulesDiction[lhs]
temp = dict()
for subrhs in allrhs:
if subrhs[0] not in list(temp.keys()):
temp[subrhs[0]] = [subrhs]
else:
temp[subrhs[0]].append(subrhs)
new_rule = []
tempo_dict = {}
for term_key in temp:
allStartingWithTermKey = temp[term_key]
if len(allStartingWithTermKey) > 1:
lhs_ = lhs + "'"
while lhs_ in rulesDiction.keys() or lhs_ in tempo_dict.keys():
lhs_ += "'"
new_rule.append([term_key, lhs_])
ex_rules = []
for g in temp[term_key]:
ex_rules.append(g[1:])
tempo_dict[lhs_] = ex_rules
else:
new_rule.append(allStartingWithTermKey[0])
newDict[lhs] = new_rule
for key in tempo_dict:
newDict[key] = tempo_dict[key]
return newDict
def first(rule):
if len(rule) != 0 and rule[0] in term_userdef:
return rule[0]
elif len(rule) != 0 and rule[0] == '#':
return '#'
if len(rule) != 0 and rule[0] in diction:
fres = []
rhs_rules = diction[rule[0]]
for itr in rhs_rules:
indivRes = first(itr)
if type(indivRes) is list:
fres.extend(indivRes)
else:
fres.append(indivRes)
if '#' not in fres:
return fres
else:
newList = fres
fres.remove('#')
if len(rule) > 1:
ansNew = first(rule[1:])
if ansNew is not None:
if type(ansNew) is list:
newList = fres + ansNew
else:
newList = fres + [ansNew]
fres.append('#')
return fres
def follow(nt):
solset = set()
if nt == start_symbol:
solset.add('$')
for curNT in diction:
rhs = diction[curNT]
for subrule in rhs:
if nt in subrule:
while nt in subrule:
index_nt = subrule.index(nt)
subrule = subrule[index_nt + 1:]
if len(subrule) != 0:
res = first(subrule)
if '#' in res:
res.remove('#')
res += follow(curNT)
else:
if nt != curNT:
res = follow(curNT)
solset.update(res if type(res) is list else [res])
return list(solset)
def computeAllFirsts():
global firsts
for y in diction.keys():
firsts[y] = set()
for sub in diction[y]:
result = first(sub)
if result is not None:
firsts[y].update(result if type(result) is list else [result])
def computeAllFollows():
global follows
for NT in diction.keys():
follows[NT] = set(follow(NT))
def createParseTable():
global term_userdef, firsts, follows
table = {}
grammar_is_LL = True
for lhs in diction.keys():
table[lhs] = {}
for term in term_userdef + ['$']:
table[lhs][term] = ""
for lhs in diction:
for rule in diction[lhs]:
first_res = first(rule)
if '#' in first_res:
first_res.remove('#')
follow_res = follows[lhs]
first_res.update(follow_res)
for term in first_res:
if table[lhs][term] == "":
table[lhs][term] = f"{lhs} -> {' '.join(rule)}"
else:
grammar_is_LL = False
return table, grammar_is_LL
def validateStringUsingStackBuffer(parse_table, input_string):
stack = [start_symbol, '$']
buffer = ['$'] + input_string.split()[::-1]
while stack:
top_stack = stack.pop(0)
top_buffer = buffer.pop()
if top_stack in term_userdef:
if top_stack != top_buffer:
return "Invalid String"
elif top_stack == top_buffer:
continue
else:
rule = parse_table.get(top_stack, {}).get(top_buffer, None)
if rule:
rule_rhs = rule.split('->')[1].strip().split()
stack = rule_rhs + stack
else:
return "Invalid String"
return "Valid String"
st.title("LL(1) Grammar Analyzer")
st.subheader("Grammar Rules Input")
start_symbol = st.text_input("Enter Start Symbol (Non-terminal)")
num_rules = st.number_input("Number of Grammar Rules", min_value=1, step=1)
rules = []
for i in range(num_rules):
rule = st.text_input(f"Rule {i+1}")
if rule:
rules.append(rule)
nonterm_userdef = st.text_input("Enter Non-Terminals (comma-separated)").split(',')
term_userdef = st.text_input("Enter Terminals (comma-separated)").split(',')
if st.button("Analyze Grammar"):
diction.clear()
firsts.clear()
follows.clear()
for rule in rules:
lhs, rhs = rule.split("->")
lhs = lhs.strip()
rhs_list = [x.strip().split() for x in rhs.split("|")]
diction[lhs] = rhs_list
st.subheader("Grammar After Removing Left Recursion")
diction = removeLeftRecursion(diction)
st.write(diction)
st.subheader("Grammar After Left Factoring")
diction = LeftFactoring(diction)
st.write(diction)
computeAllFirsts()
st.subheader("FIRST Sets")
st.write(firsts)
computeAllFollows()
st.subheader("FOLLOW Sets")
st.write(follows)
parse_table, grammar_is_LL = createParseTable()
st.subheader("Parse Table")
st.write(parse_table)
if grammar_is_LL:
st.success("The grammar is LL(1)")
else:
st.error("The grammar is not LL(1)")
input_string = st.text_input("Enter String to Validate (space-separated)")
if input_string:
result = validateStringUsingStackBuffer(parse_table, input_string)
st.subheader("Validation Result")
st.write(result)