理解使用GraphViz的gcc -fdump-tree输出

7

我已经按照这里描述的方法创建了一份树形结构转储:如何将由gcc生成的抽象语法树转储到.dot文件中?,针对这个虚拟脚本:

int fact(int n) {
    if (n<=1) {
        return 1;
    }
    return n * fact(n-1);
}

int main(void) {
    int a = 4;
    int res = fact(a);
    return res;
}

我得到的图像如下:

通过 GraphViz 生成的图形

据我所知,使用gcc不是学习AST表示的最佳方式。但无论如何,了解图像的内容是很好的。

特别是这里的 % 符号和一个 FREQ:0 语句是什么意思?

1个回答

5
你提供的链接展示了如何从GCC调试转储中获取控制流图,所以你的图片实际上没有显示语法树。
GCC C前端没有传统意义上的抽象语法树。许多句法结构在解析过程中被降级,通常变成一堆goto。例如,c_finish_loop就是这样的一个例子:
  /* If we have an exit condition, then we build an IF with gotos either
     out of the loop, or to the top of it.  If there's no exit condition,
     then we just build a jump back to the top.  */
  exit = build_and_jump (&LABEL_EXPR_LABEL (top));

if语句被转换为COND_EXPR节点。您可以在.original转储中看到它(其中COND_EXPR节点像C if语句一样打印)。但是,从该过程没有生成.dot文件。一旦编译过程进入中间端,它就是GIMPLE,并且GIMPLE(作为SSA变体)根本不使用高级语言构造(例如forif语句)来表示控制流。

Clang具有更传统的AST,通过clang -Xclang -ast-dump打印。它仍然不适合Graphviz的输入,但至少数据在那里。如果您的目标是理解GCC,请查看C ++前端,在解析器中保留了更丰富的结构。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接