Improve code maintainability
This commit is contained in:
184
Project-02-03/syntax.py
Normal file
184
Project-02-03/syntax.py
Normal file
@@ -0,0 +1,184 @@
|
||||
class EXPRESSION:
|
||||
pp_count = 0
|
||||
|
||||
def __init__(self):
|
||||
self.pp = EXPRESSION.pp_count
|
||||
EXPRESSION.pp_count += 1
|
||||
|
||||
@staticmethod
|
||||
def copy():
|
||||
return EXPRESSION()
|
||||
|
||||
# Returns a list of tuples (edge_name, child_expression)
|
||||
def children(self):
|
||||
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
|
||||
|
||||
# Export AST to dot format
|
||||
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) + " }"
|
||||
Reference in New Issue
Block a user