Anul 3 Semestrul 1
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from Parser import RecursiveDescentParser
|
||||
from ParserOutput import TreeNode, ParserOutput
|
||||
|
||||
|
||||
class Grammar:
|
||||
def __init__(self):
|
||||
self.nonterminals = set()
|
||||
self.terminals = set()
|
||||
self.productions = defaultdict(list)
|
||||
self.start_symbol = None
|
||||
|
||||
def read_from_file(self, filename):
|
||||
|
||||
with open(filename, 'r') as file:
|
||||
lines = file.readlines()
|
||||
|
||||
|
||||
grammar_header = lines[0].strip()
|
||||
match = re.match(r"G\s*=\s*\(\s*\{([^}]*)\}\s*,\s*\{([^}]*)\}\s*,\s*P\s*,\s*([^)]+)\s*\)", grammar_header)
|
||||
|
||||
if not match:
|
||||
raise ValueError("Invalid grammar format in the first line.")
|
||||
|
||||
self.nonterminals = set([x.strip() for x in set(match.group(1).split(', '))])
|
||||
self.terminals = set([x.strip() for x in set(match.group(2).split(', '))])
|
||||
self.start_symbol = match.group(3)
|
||||
|
||||
# Parse the productions
|
||||
for line in lines[1:]:
|
||||
line = line.strip()
|
||||
if line.startswith("P :"):
|
||||
line = line[3:].strip()
|
||||
if "->" in line:
|
||||
lhs, rhs = line.split('->')
|
||||
lhs = lhs.strip()
|
||||
self.nonterminals.add(lhs)
|
||||
for production in rhs.split('|'):
|
||||
production = production.strip()
|
||||
self.productions[lhs].append(production.strip())
|
||||
|
||||
def print_nonterminals(self):
|
||||
print("Nonterminals:", self.nonterminals)
|
||||
|
||||
def print_terminals(self):
|
||||
print("Terminals:", self.terminals)
|
||||
|
||||
def print_productions(self):
|
||||
for lhs, rhs in self.productions.items():
|
||||
print(f"{lhs} -> {' | '.join(rhs)}")
|
||||
|
||||
def get_productions_for(self, nonterminal):
|
||||
return self.productions.get(nonterminal, [])
|
||||
|
||||
def is_cfg(self):
|
||||
for lhs, rhs_list in self.productions.items():
|
||||
|
||||
if lhs not in self.nonterminals:
|
||||
print(f"Invalid nonterminal: {lhs}")
|
||||
return False
|
||||
|
||||
for rhs in rhs_list:
|
||||
rhs_symbols = rhs.split()
|
||||
|
||||
for symbol in rhs_symbols:
|
||||
if symbol not in self.terminals and symbol not in self.nonterminals:
|
||||
print(f"Invalid symbol in RHS: {symbol}")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def menu():
|
||||
g = Grammar()
|
||||
#g.read_from_file("g2.txt")
|
||||
parser = None
|
||||
while True:
|
||||
print("1. Read grammar from file")
|
||||
print("2. Print nonterminals")
|
||||
print("3. Print terminals")
|
||||
print("4. Print productions")
|
||||
print("5. Get productions for a nonterminal")
|
||||
print("6. Check if the grammar is CFG")
|
||||
print("7. Parse input string")
|
||||
print("0. Exit")
|
||||
input_command = input("Enter your command: ")
|
||||
match input_command:
|
||||
case "1":
|
||||
filename = input("Enter the filename: ")
|
||||
g.read_from_file(filename)
|
||||
case "2":
|
||||
g.print_nonterminals()
|
||||
case "3":
|
||||
g.print_terminals()
|
||||
case "4":
|
||||
g.print_productions()
|
||||
case "5":
|
||||
nonterminal = input("Enter the nonterminal: ")
|
||||
print(g.get_productions_for(nonterminal))
|
||||
case "6":
|
||||
print(g.is_cfg())
|
||||
case "7":
|
||||
input_string = input("Enter the input string: ")
|
||||
parser = RecursiveDescentParser(g, input_string)
|
||||
if parser.parse():
|
||||
print(parser.print_parse_tree())
|
||||
parser.save_parse_tree("out1.txt")
|
||||
|
||||
else:
|
||||
print("The input string is not in the language")
|
||||
print(parser.stack)
|
||||
print(parser.parsed_stack)
|
||||
case "0":
|
||||
return
|
||||
case _:
|
||||
print("Invalid command")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
menu()
|
||||
# g = Grammar()
|
||||
# g.read_from_file("g1.txt")
|
||||
# parser = RecursiveDescentParser(g, "a a b")
|
||||
# parser.expand("S", 0)
|
||||
# print(parser.current_pos)
|
||||
# print(parser.stack)
|
||||
# print(parser.parsed_stack)
|
||||
# parser.advance()
|
||||
# print(parser.current_pos)
|
||||
# print(parser.stack)
|
||||
# print(parser.parsed_stack)
|
||||
# parser.expand("A", 1)
|
||||
# print(parser.current_pos)
|
||||
# print(parser.stack)
|
||||
# print(parser.parsed_stack)
|
||||
# parser.advance()
|
||||
# print(parser.current_pos)
|
||||
# print(parser.stack)
|
||||
# print(parser.parsed_stack)
|
||||
# parser.back()
|
||||
# print(parser.current_pos)
|
||||
# print(parser.stack)
|
||||
# print(parser.parsed_stack)
|
||||
# parser.another_try("A",1)
|
||||
# print(parser.current_pos)
|
||||
# print(parser.stack)
|
||||
# print(parser.parsed_stack)
|
||||
# parser.advance()
|
||||
# print(parser.current_pos)
|
||||
# print(parser.stack)
|
||||
# print(parser.parsed_stack)
|
||||
# parser.advance()
|
||||
# print(parser.current_pos)
|
||||
# print(parser.stack)
|
||||
# print(parser.parsed_stack)
|
||||
# print(parser.success())
|
||||
# print(parser.current_pos)
|
||||
# print(parser.stack)
|
||||
# print(parser.parsed_stack)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user