Anul 3 Semestrul 1
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
import string
|
||||
|
||||
|
||||
class TreeNode:
|
||||
def __init__(self, value, father=None):
|
||||
self.value = value # Grammar symbol (terminal/nonterminal)
|
||||
self.father = father # Parent node
|
||||
self.sibling = None # Sibling node
|
||||
self.children = [] # List of children for easy access
|
||||
|
||||
def add_child(self, child):
|
||||
"""Adds a child to the current node."""
|
||||
if self.children:
|
||||
# Set sibling for the last child
|
||||
self.children[-1].sibling = child
|
||||
self.children.append(child)
|
||||
|
||||
def __str__(self):
|
||||
"""String representation of the node."""
|
||||
return self.value
|
||||
|
||||
|
||||
class ParserOutput:
|
||||
def __init__(self, terminal, nonterminal):
|
||||
self.root = None # Root of the parse tree
|
||||
self.terminal = terminal
|
||||
self.nonterminal = nonterminal
|
||||
|
||||
def build_tree(self, production_sequence):
|
||||
"""
|
||||
Builds the parse tree from a sequence of productions.
|
||||
:param production_sequence: List of (nonterminal, production) tuples
|
||||
"""
|
||||
if not production_sequence:
|
||||
return None
|
||||
|
||||
stack = [] # Stack for constructing the tree
|
||||
for nonterminal, production in production_sequence:
|
||||
if not self.root:
|
||||
# Create the root node
|
||||
self.root = TreeNode(nonterminal)
|
||||
stack.append(self.root)
|
||||
current = stack.pop()
|
||||
symbols = production.split()
|
||||
for symbol in symbols:
|
||||
child = TreeNode(symbol, current)
|
||||
current.add_child(child)
|
||||
if symbol in self.nonterminal: # Nonterminal
|
||||
stack.append(child)
|
||||
else:
|
||||
# Create nodes based on production
|
||||
current = stack.pop()
|
||||
symbols = production.split()
|
||||
for symbol in symbols:
|
||||
child = TreeNode(symbol, current)
|
||||
current.add_child(child)
|
||||
if symbol in self.nonterminal: # Nonterminal
|
||||
stack.append(child)
|
||||
|
||||
def transform_representation(self, node=None, level=0):
|
||||
if node is None:
|
||||
node = self.root
|
||||
|
||||
result = "-" * level + str(node) + "\n"
|
||||
for child in node.children:
|
||||
result += self.transform_representation(child, level + 1)
|
||||
return result
|
||||
|
||||
def print_to_screen(self):
|
||||
print(self.print_table())
|
||||
|
||||
def print_table(self):
|
||||
"""
|
||||
Prints a table representation of the parse tree.
|
||||
"""
|
||||
rows = []
|
||||
index_map = {}
|
||||
|
||||
def traverse(node, index=1, parent_index=None):
|
||||
current_index = len(rows)
|
||||
index_map[node] = current_index
|
||||
|
||||
# Determine right sibling
|
||||
sibling_index = None
|
||||
if node.sibling:
|
||||
sibling_index = len(rows) + 1 # Right sibling will be the next node added
|
||||
|
||||
rows.append((current_index, node.value, parent_index, sibling_index))
|
||||
|
||||
for child in node.children:
|
||||
traverse(child, len(rows), current_index)
|
||||
|
||||
traverse(self.root)
|
||||
|
||||
# Print the table
|
||||
s = ""
|
||||
s += "+-------+-------+--------+---------------+" + "\n"
|
||||
s += "| Index | Value | Parent | Right Sibling |" + "\n"
|
||||
s += "+-------+-------+--------+---------------+" + "\n"
|
||||
for index, value, parent, sibling in rows:
|
||||
s += f"| {index:<3} | {value:<3} | {parent + 1 if parent is not None else '0':<4} | {sibling if sibling is not None else '0':<11} |" + "\n"
|
||||
|
||||
s += "+-------+-------+--------+---------------+" + "\n"
|
||||
return s
|
||||
|
||||
|
||||
def save_to_file(self, filename):
|
||||
with open(filename, 'w') as file:
|
||||
file.write(self.print_table())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user