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 self.dot_shape = 'box' self.dot_style = '' 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 dot_label(self): # Prioritize custom label if self.label is not None: return self.label # Build label from AST node if self.ast_node is not None: return str(self.ast_node) return None def is_filled(self): return not self.is_empty() def is_empty(self): # Node is empty if it has no label and no related AST node if self.label is None or self.label == "None": if self.ast_node is not None: # Node belongs to a ast node return False return True # Node is required for the control flow return False class CFG_START(CFG_Node): def __init__(self, ast_node=None): super().__init__(ast_node) self.dot_shape = "ellipse" self.dot_style = 'style=filled, color=green' self.label = "START" class CFG_END(CFG_Node): def __init__(self, ast_node=None): super().__init__(ast_node) self.dot_shape = "ellipse" self.dot_style = 'style=filled, color=green' self.label = "END" class CFG_DIAMOND(CFG_Node): def __init__(self, ast_node=None): super().__init__(ast_node) self.dot_shape = "diamond" self.label = "" class CFG_CALL(CFG_Node): def __init__(self, ast_node=None): super().__init__(ast_node) self.dot_style = 'style=filled, color=orange' self.dot_shape = "box" class CFG_RETURN(CFG_Node): def __init__(self, ast_node=None): super().__init__(ast_node) self.dot_style = 'style=filled, color=orange' self.dot_shape = "box"