First try
This commit is contained in:
48
Project-02-03-04/cfg/CFG.py
Normal file
48
Project-02-03-04/cfg/CFG.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from .CFG_Node import *
|
||||
|
||||
|
||||
class CFG:
|
||||
def __init__(self, in_node: CFG_Node, out_node: CFG_Node):
|
||||
self.in_node = in_node
|
||||
self.out_node = out_node
|
||||
|
||||
def to_dot(self) -> str:
|
||||
visited = set()
|
||||
lines = ["digraph CFG {"]
|
||||
|
||||
# optionale Defaults
|
||||
lines.append(' node [fontname="Helvetica"];')
|
||||
|
||||
def node_label(node: CFG_Node) -> str:
|
||||
# Basislabel aus dem Knoten
|
||||
base = node.dot_label() if hasattr(node, "dot_label") else ""
|
||||
|
||||
# semantisches Label aus AST
|
||||
if node.ast_node is not None:
|
||||
semantic = str(node.ast_node)
|
||||
return f"{base}\\n{semantic}" if base else semantic
|
||||
|
||||
return base
|
||||
|
||||
def node_shape(node: CFG_Node) -> str:
|
||||
return node.dot_shape() if hasattr(node, "dot_shape") else "box"
|
||||
|
||||
def visit(node: CFG_Node):
|
||||
if node.id in visited:
|
||||
return
|
||||
visited.add(node.id)
|
||||
|
||||
label = node_label(node)
|
||||
shape = node_shape(node)
|
||||
|
||||
lines.append(
|
||||
f' n{node.id} [label="{label}", shape={shape}];'
|
||||
)
|
||||
|
||||
for child in sorted(node.children, key=lambda n: n.id):
|
||||
lines.append(f" n{node.id} -> n{child.id};")
|
||||
visit(child)
|
||||
|
||||
visit(self.in_node)
|
||||
lines.append("}")
|
||||
return "\n".join(lines)
|
||||
67
Project-02-03-04/cfg/CFG_Node.py
Normal file
67
Project-02-03-04/cfg/CFG_Node.py
Normal file
@@ -0,0 +1,67 @@
|
||||
class CFG_Node:
|
||||
__counter = 1
|
||||
|
||||
def __init__(self, ast_node = None):
|
||||
self.ast_node = ast_node
|
||||
self.children = set()
|
||||
self.parents = set()
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class CFG_START(CFG_Node):
|
||||
def dot_shape(self):
|
||||
return "circle"
|
||||
|
||||
def dot_label(self):
|
||||
return "START"
|
||||
|
||||
|
||||
class CFG_END(CFG_Node):
|
||||
def dot_shape(self):
|
||||
return "doublecircle"
|
||||
|
||||
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"
|
||||
0
Project-02-03-04/cfg/__init__.py
Normal file
0
Project-02-03-04/cfg/__init__.py
Normal file
Reference in New Issue
Block a user