Files
Construction-of-Compilers/Project-02/syntax.py
Jan-Niclas Loosen 7ac8889a1d Finish refactoring
2025-11-20 19:19:52 +01:00

183 lines
5.0 KiB
Python

class EXPRESSION:
pp_count = 0
def __init__(self):
self.pp = EXPRESSION.pp_count
EXPRESSION.pp_count += 1
@staticmethod
def copy():
return EXPRESSION()
def children(self):
"""Return a list of (name, childNode)."""
out = []
for key, value in self.__dict__.items():
if key == "pp":
continue
if isinstance(value, EXPRESSION):
out.append((key, value))
elif isinstance(value, list):
for i, elem in enumerate(value):
if isinstance(elem, EXPRESSION):
out.append((f"{key}{i}", elem))
return out
def to_dot(self, visited=None, root=True):
if visited is None:
visited = set()
# Prevent infinite recursion
if id(self) in visited:
return ""
visited.add(id(self))
parts = []
# Add a header at the root node
if root:
parts.append("digraph AST {\n")
# Append to label
label = type(self).__name__
if hasattr(self, "operator"):
label += f"({self.operator})"
if hasattr(self, "name"):
label += f"({self.name})"
if hasattr(self, "value"):
label += f"({self.value})"
parts.append(f' node{self.pp} [label="{label}"];\n')
# Draw edges
for edge_name, child in self.children():
parts.append(f' node{self.pp} -> node{child.pp} [label="{edge_name}"];\n')
parts.append(child.to_dot(visited, root=False))
# Add footer at the root node
if root:
parts.append("}\n")
return "".join(parts)
class LET(EXPRESSION):
def __init__(self, decls, body):
super().__init__()
self.decl = decls
self.body = body
def __str__(self):
return "let " + ", ".join(str(d) for d in self.decl) + " in " + str(self.body)
class DECL(EXPRESSION):
def __init__(self, f_name, params, body):
super().__init__()
self.f_name = f_name
self.params = params
self.body = body
def __str__(self):
return f"{self.f_name}({self.params}) {{ {self.body} }}"
class CALL(EXPRESSION):
def __init__(self, f_name, args):
super().__init__()
self.f_name = f_name
self.arg = args
def __str__(self):
return self.f_name + "(" + ",".join(str(a) for a in self.arg) + ")"
class ID(EXPRESSION):
def __init__(self, name):
super().__init__()
self.name = name
def __str__(self):
return self.name
class CONST(EXPRESSION):
def __init__(self, value):
super().__init__()
self.value = value
def __str__(self):
return str(self.value)
class AOP(EXPRESSION):
def __init__(self, operator, arg1, arg2):
super().__init__()
self.operator = operator
self.arg1 = arg1
self.arg2 = arg2
def __str__(self):
return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")"
class EQOP(EXPRESSION):
def __init__(self, operator, arg1, arg2):
super().__init__()
self.operator = operator
self.arg1 = arg1
self.arg2 = arg2
def __str__(self):
return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")"
class COMP(EXPRESSION):
def __init__(self, operator, arg1, arg2):
super().__init__()
self.operator = operator
self.arg1 = arg1
self.arg2 = arg2
def __str__(self):
return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")"
class LOP(EXPRESSION):
def __init__(self, operator, arg1, arg2):
super().__init__()
self.operator = operator
self.arg1 = arg1
self.arg2 = arg2
def __str__(self):
return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")"
class ASSIGN(EXPRESSION):
def __init__(self, var, expr):
super().__init__()
self.var = var
self.expr = expr
def __str__(self):
return self.var.name + " = " + str(self.expr)
class SEQ(EXPRESSION):
def __init__(self, exp1, exp2):
super().__init__()
self.exp1 = exp1
self.exp2 = exp2
def __str__(self):
return str(self.exp1) + "; " + str(self.exp2)
class IF(EXPRESSION):
def __init__(self, cond, exp1, exp2):
super().__init__()
self.cond = cond
self.exp1 = exp1
self.exp2 = exp2
def __str__(self):
return "if (" + str(self.cond) + ") then { " + str(self.exp1) + " } else { " + str(self.exp2) + " }"
class WHILE(EXPRESSION):
def __init__(self, cond, body):
super().__init__()
self.cond = cond
self.body = body
def __str__(self):
return "while (" + str(self.cond) + ") do { " + str(self.body) + " }"