80 lines
1.8 KiB
Python
80 lines
1.8 KiB
Python
class CFG_Node:
|
|
__counter = 1
|
|
|
|
def __init__(self, ast_node=None):
|
|
self.ast_node = ast_node
|
|
self.children = set()
|
|
self.parents = set()
|
|
self.label = None # Optional label for the node
|
|
|
|
self.id = CFG_Node.__counter
|
|
CFG_Node.__counter += 1
|
|
|
|
def get_children(self):
|
|
return self.children
|
|
|
|
def get_parents(self):
|
|
return self.parents
|
|
|
|
def add_child(self, child: 'CFG_Node', propagate=True):
|
|
if propagate:
|
|
child.parents.add(self)
|
|
self.children.add(child)
|
|
|
|
def add_parent(self, parent: 'CFG_Node', propagate=True):
|
|
if propagate:
|
|
parent.add_child(self)
|
|
self.parents.add(parent)
|
|
|
|
def remove_child(self, child: 'CFG_Node', propagate=True):
|
|
if propagate:
|
|
child.parents.remove(self)
|
|
self.children.remove(child)
|
|
|
|
def remove_parent(self, parent: 'CFG_Node', propagate=True):
|
|
if propagate:
|
|
parent.children.remove(self)
|
|
self.parents.remove(parent)
|
|
|
|
def __str__(self):
|
|
if self.label:
|
|
return f"CFG_Node({self.id}, label='{self.label}')"
|
|
elif self.ast_node:
|
|
return f"CFG_Node({self.id}, ast={type(self.ast_node).__name__})"
|
|
else:
|
|
return f"CFG_Node({self.id})"
|
|
|
|
def __repr__(self):
|
|
return self.__str__()
|
|
|
|
|
|
class CFG_START(CFG_Node):
|
|
def dot_shape(self):
|
|
return "box"
|
|
|
|
def dot_label(self):
|
|
return "START"
|
|
|
|
|
|
class CFG_END(CFG_Node):
|
|
def dot_shape(self):
|
|
return "box"
|
|
|
|
def dot_label(self):
|
|
return "END"
|
|
|
|
|
|
class CFG_DIAMOND(CFG_Node):
|
|
def dot_shape(self):
|
|
return "diamond"
|
|
|
|
|
|
class CFG_CALL(CFG_Node):
|
|
def dot_shape(self):
|
|
return "box"
|
|
|
|
|
|
class CFG_RETURN(CFG_Node):
|
|
def dot_shape(self):
|
|
return "box"
|