gpt4 book ai didi

graphviz - 我怎样才能影响 Graphviz/dot 通过消除蛇形和更好的边交叉来制作更好的控制流图?

转载 作者:行者123 更新时间:2023-12-05 04:03:42 25 4
gpt4 key购买 nike

我正在为 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];
}

上面dot生成的图像是enter image description here

注意一条线是如何蜿蜒曲折并向下穿过直箭头的。相反,我宁愿没有一个直线向下的箭头被越过。样条边会成为更好的交叉点。

如果你看一下这个点,我有两个不可见的向下边缘用于对齐。 (在字节码中,这些遵循线性指令序列)。

因此,如果需要穿过一条向下的直线(这里不需要),则不可见的边缘比可见的边缘更受欢迎。

想法?

编辑

到目前为止,一个很好的答案是建议更改边的定义顺序,并在某些情况下指定应该制作边附件的位置。

在这个应用程序中,我确实有来自支配树的层次嵌套信息,我可以对边进行分类:那些循环的,那些跳到复合结构末尾的,那些打破循环的,等等.

所以现在问题变成了如何使用这些信息来避免那些蛇形箭头,并确保跳出循环优先于跨越边缘而不是说“if”/“else”跳转边缘。

这感觉就像 VLSI 设计:提出一组适用于每种(控制流)结构的模式,然后这些模式将正确嵌套和排序。

我已经尝试过边缘排序和放置,但我对何时将某些东西放得更早或更晚没有直觉。

指导,或者更好的是,结构化控制流边缘的设计规则将不胜感激。

最佳答案

你需要做两件事来改善这种情况:

  • 先绘制(其中一条)您想控制的边,
  • 告诉 graphviz 您希望将它们连接到哪里(北、东...)

我已经相应地编辑了你的代码

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_3:nw [weight=1]; /* moved up and added directions*/
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:se -> node_4:ne [weight=1]; /* added directions */
}

这给了你

enter image description here

这里涉及一些试验和错误,但我相信这应该有所帮助。

关于graphviz - 我怎样才能影响 Graphviz/dot 通过消除蛇形和更好的边交叉来制作更好的控制流图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53468814/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com