我正在为 Python 程序绘制控制流图,并且想影响不应该跨越哪种边缘。有没有办法做到这一点?
考虑这个简单的 Python 程序:
try:
a += 1
except:
a += 2
else:
a = 3
还有一个点程序来表示通过https://github.com/rocky/python-control-flow/生成的控制流
digraph G {
mclimit=1.5;
rankdir=TD; ordering=out;
graph[fontsize=10 fontname="Verdana"];
color="#efefef";
node[shape=box style=filled fontsize=8 fontname="Verdana" fillcolor="#efefef"];
edge[fontsize=8 fontname="Verdana"];
node_0 [shape = "oval"][label="Basic Block 0\loffsets: 0..12\lflags=entry, block, unconditional, try\ljumps=[34]\l"];
node_1 [label="Basic Block 1\loffsets: 14..30\lflags=except, unconditional\ljumps=[38]\l"];
node_2 [label="Basic Block 2\loffsets: 32..32\lflags=end finally\l"];
node_3 [label="Basic Block 3\loffsets: 34..36\l"];
node_4 [label="Basic Block 4\loffsets: 38..40\lflags=no fallthrough\l"];
node_0 -> node_2 [weight=1][color="red"];
node_3 -> node_4 [weight=10];
node_0 -> node_1 [weight=1][color="red"];
node_2 -> node_3 [weight=10];
node_0 -> node_1 [weight=10][style="invis"];
node_1 -> node_2 [weight=10][style="invis"];
node_1 -> node_4 [weight=1];
node_0 -> node_3 [weight=1];
}
请注意一条线是如何蜿蜒而下并穿过一个直箭头的。相反,我宁愿没有一个笔直的向下箭头会被越过。花键边缘会形成更好的交叉位置。
如果你看点,我有两个不可见的向下边缘,用于对齐。(在字节码中,这些遵循线性指令序列)。
因此,如果需要越过一条向下的直线(而这里不需要),则不可见的边缘将优于可见的边缘。
想法?
编辑
到目前为止,一个很好的答案建议更改定义边缘的顺序,并在某些情况下指定应该进行边缘连接的位置。
在这个应用程序中,我确实有来自支配树的分层嵌套信息,并且我可以对边缘进行分类:循环的边缘、跳转到复合结构末尾的边缘、打破循环的边缘等等。
所以现在问题变成了如何使用这些信息来避免那些蛇形箭头,并确保循环中断优先于跨越边缘而不是说“if”/“else”跳转边缘。
这感觉就像 VLSI 设计:提出一组适用于每种(控制流)结构的模式,然后这些模式将正确嵌套和排序。
我已经尝试过边缘排序和放置,我只是没有直观的感觉什么时候应该早点或晚点放东西。
非常感谢结构化控制流边缘的指导或更好的设计规则。