什么是AST,CFG,CLANG,我们如何在死码去除算法中使用它?

时间:2011-08-26 13:56:33

标签: c parsing clang abstract-syntax-tree dead-code

我即将使用C语言为我们团队的在线活动编写一个死代码删除算法。

要求是......

  1. 读取C程序源文件,其中包含多种形式的死代码。
  2. 我们的输出应该是一个文件,它没有任何死码。
  3. 在浏览互联网时,我们遇到了SO链接......

    How can I know which parts in the code are never used?

    Dead code detection in legacy C/C++ project

    在看到这些链接之前,我们有了基本的想法......    使用普通文件流逐行读取输入C文件并存储在字符串数组中。    然后分析这些字符串并确定非常基本的死代码,如if(0)和if(1)等。    并制作一个堆栈,用于维护括号。还有更多...

    但是这有一个很大的问题,这个想法将引导我们用字符串操作做更多事情,而不是删除死码。

    但看到这些链接后...... 我们开始了解 Clang库,抽象语法树,控制流图等......

    但我们对这些图书馆和那些概念都是新手。 我们开始知道它们用于解析C代码。

    因此,我们需要一些关于AST,CFG和一些基本指导的基本想法,解释我们如何使用 在我们的代码中...

    我们可以将clang库包含为math.h的普通库吗?

    我们在哪里可以下载该库?

    我们可以在Windows中使用那些Clang库吗?

2 个答案:

答案 0 :(得分:4)

我可以向您解释控制流图的概念,但我对图书馆本身并不熟悉。

这个概念很简单。想象一下任何连续的代码行(没有ifgoto或函数调用或标签)作为图形的一个节点。每个goto或函数调用都会创建从当前节点到goto标签所在节点或其调用函数的方向链接。请记住,函数本身可以是图形而不是简单节点,因为它可能内部有if个或其他函数调用。每个函数调用还会在函数调用之后立即创建从函数的叶节点(函数return s)到包含代码的节点的方向链接。 (这可以创建从函数图中传出的大量链接,因为可以在代码的许多部分调用该函数)

同样,如果您有if,则从当前节点到if部分的else部分和if部分都有两个方向链接(除非您检测到if(0)if(1),就像您说的那样,只有一个指向正确位置的链接)

图表的根目录是main的入口点。现在你必须做的就是找到死代码只是简单地从根位置遍历图形(例如使用DFS或BFS),最后看看哪些节点没有被访问过。这会显示死代码,即代码中的位置,无论程序采用何种方向,它都不会到达这些位置。

如果您想自己实现,可以采用递归方法(类似于解析代码但更简单)。例如,如果您看到if,则说:

typedef char *line;
FlowGraph *get_flow_graph(line *code)
{
    FlowGraph *current_node = malloc(sizeof *current_node);
    current_node->flow_to = malloc(some_maximum * sizeof *current_node->flow_to);
    current_node->flow_to_count = 0;
    ...
    if (is_if_statement(code[0]))
    {
        FlowGraph *if_part = get_flow_graph(code + 1);
        FlowGraph *else_part = get_flow_graph(code + find_matching_else(code));
        current_node->flow_to[current_node->flow_to_count++] = if_part;
        current_node->flow_to[current_node->flow_to_count++] = else_part;
    }
    else
    ...
}

答案 1 :(得分:0)

您可以查看control and data flow提取的DMS Software Reengineering Toolkit图表的示例。

我们使用DMS的数据流分析机器及其C Front End在非常大的应用程序(2600万行C)上完成了这项工作,包括点分析,如果你真的想找到它,这是一个实际需要大型C系统中的死函数。