cc1 / app.py
Neha13's picture
Update app.py
2dbf53a verified
raw
history blame
7.58 kB
import streamlit as st
import numpy as np
import pandas as pd
# Function to remove left recursion
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
# Function for Left Factoring
def LeftFactoring(rulesDiction):
newDict = {}
for lhs in rulesDiction:
allrhs = rulesDiction[lhs]
temp = dict()
for subrhs in allrhs:
if subrhs[0] not in 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
# Function to compute the FIRST set
def first(symbol, grammar, first_sets):
if symbol in first_sets:
return first_sets[symbol]
first_set = set()
if symbol not in grammar:
first_set.add(symbol)
else:
for rule in grammar[symbol]:
if rule == ['#']:
first_set.add('#')
else:
for s in rule:
first_set |= first(s, grammar, first_sets)
if '#' not in first(s, grammar, first_sets):
break
first_sets[symbol] = first_set
return first_set
# Function to compute the FOLLOW set
def follow(symbol, grammar, start_symbol, follow_sets, first_sets):
if symbol in follow_sets:
return follow_sets[symbol]
follow_set = set()
if symbol == start_symbol:
follow_set.add('$')
for lhs in grammar:
for rule in grammar[lhs]:
for i, s in enumerate(rule):
if s == symbol:
if i + 1 < len(rule):
follow_set |= first(rule[i + 1], grammar, first_sets) - {'#'}
if i + 1 == len(rule) or '#' in first(rule[i + 1], grammar, first_sets):
follow_set |= follow(lhs, grammar, start_symbol, follow_sets, first_sets)
follow_sets[symbol] = follow_set
return follow_set
# Function to compute all FIRST sets
def computeAllFirsts(grammar):
first_sets = {}
for symbol in grammar:
first(symbol, grammar, first_sets)
return first_sets
# Function to compute all FOLLOW sets
def computeAllFollows(grammar, start_symbol, first_sets):
follow_sets = {}
for symbol in grammar:
follow(symbol, grammar, start_symbol, follow_sets, first_sets)
return follow_sets
# Function to create the LL(1) parsing table
def createParseTable(grammar, first_sets, follow_sets, terminals):
parse_table = {}
for lhs in grammar:
for rule in grammar[lhs]:
first_set = first(rule[0], grammar, first_sets)
for terminal in first_set - {'#'}:
if lhs not in parse_table:
parse_table[lhs] = {}
parse_table[lhs][terminal] = rule
if '#' in first_set:
for terminal in follow_sets[lhs]:
if lhs not in parse_table:
parse_table[lhs] = {}
parse_table[lhs][terminal] = rule
return parse_table
# Function to validate a string using the LL(1) parsing table
def validateStringUsingStackBuffer(parse_table, grammar_is_LL, terminals, input_string, term_userdef, start_symbol):
stack = [start_symbol]
input_string = input_string + ['$']
idx = 0
while stack:
top = stack[-1]
if top == input_string[idx]:
stack.pop()
idx += 1
elif top in parse_table and input_string[idx] in parse_table[top]:
rule = parse_table[top][input_string[idx]]
stack.pop()
if rule != ['#']:
stack.extend(reversed(rule))
else:
return "String is not valid."
if idx == len(input_string):
return "String is valid."
return "String is not valid."
# Main Streamlit App
def main():
st.title("Grammar Analyzer")
st.markdown("This app performs grammar analysis, including left recursion removal, left factoring, FIRST/FOLLOW set calculations, and LL(1) parsing.")
# Input Section
st.sidebar.header("Input Parameters")
start_symbol = st.text_input("Start Symbol (Non-terminal):", "S")
num_rules = st.number_input("Number of Grammar Rules:", min_value=1, value=4)
# Input rules dynamically based on the number of rules
grammar_rules = []
for i in range(num_rules):
rule = st.text_input(f"Rule {i + 1}:", f"S -> A k O")
grammar_rules.append(rule)
non_terminals = st.text_input("Non-Terminals (comma-separated):", "S, A, B, C")
terminals = st.text_input("Terminals (comma-separated):", "a, b, c, d, k, r, O")
# Process the inputs
if st.button("Analyze"):
# Parse the non-terminals and terminals
non_terminals_list = [nt.strip() for nt in non_terminals.split(",")]
terminals_list = [t.strip() for t in terminals.split(",")]
# Parse the grammar rules
grammar_dict = {}
for rule in grammar_rules:
lhs, rhs = rule.split("->")
rhs_options = rhs.split("|")
grammar_dict[lhs.strip()] = [option.strip().split() for option in rhs_options]
# Remove left recursion
grammar_dict = removeLeftRecursion(grammar_dict)
# Apply left factoring
grammar_dict = LeftFactoring(grammar_dict)
# Compute FIRST and FOLLOW sets
first_sets = computeAllFirsts(grammar_dict)
follow_sets = computeAllFollows(grammar_dict, start_symbol, first_sets)
# Generate parsing table
parse_table = createParseTable(grammar_dict, first_sets, follow_sets, terminals_list)
# Display the parsing table
st.subheader("Parsing Table")
st.write(parse_table)
# Validate the input string using the parsing table
input_string = st.text_input("Enter string to validate:", "a c")
validation_result = validateStringUsingStackBuffer(parse_table, True, terminals_list, input_string.split(), terminals_list, start_symbol)
st.write(validation_result)
if __name__ == "__main__":
main()