什么是AST、CFG、CLANG,我们如何在死码删除算法中使用它?
我准备用C语言为我们团队的一个在线活动编写一个死代码删除算法 这些要求是什么是AST、CFG、CLANG,我们如何在死码删除算法中使用它?,c,parsing,clang,abstract-syntax-tree,dead-code,C,Parsing,Clang,Abstract Syntax Tree,Dead Code,我准备用C语言为我们团队的一个在线活动编写一个死代码删除算法 这些要求是 读取一个C程序源文件,其中有许多形式的死代码 我们的输出应该是一个没有死代码的文件 在网上冲浪的时候,我们遇到了这么多的链接 在看到这些链接之前,我们有了基本的想法。。。 使用普通文件流逐行读取输入C文件,并存储在字符串数组中。 然后分析这些字符串并确定非常基本的死代码,如if(0)和if(1)等。。 以及制作一个堆栈,用于维护括号。还有更多 但这有一个很大的问题,这个想法将引导我们更多地使用字符串操作,而不是删除死代
我们可以在windows中使用那些铿锵的库吗?我可以向您解释控制流图的概念,但我对库本身并不熟悉 这个概念很简单。将任何连续的代码行(即没有
if
、goto
或函数调用或标签)想象为图形的一个节点。每次goto
或函数调用都会创建从当前节点到goto
标签所在节点或其调用函数的定向链接。请记住,函数本身可以是一个图,而不是一个简单的节点,因为它内部可能有if
s或其他函数调用。每个函数调用还创建从函数的叶节点(其中函数return
s)到函数调用后包含代码的节点的定向链接。(这可以创建许多从函数图传出的链接,因为函数可以在代码的许多部分中调用)
同样,如果您有一个if
,那么您有两个从当前节点到if
部分和if
语句的else
部分的方向链接(除非您检测到if(0)
或if(1)
,就像您所说的那样,在这种情况下,只有一个到正确位置的链接)
图形的根是main
的入口点。现在,要找到死代码,您必须做的是从根位置(例如使用DFS或BFS)简单地遍历图,最后查看哪些节点没有被访问。这会显示死掉的代码,也就是说,无论程序朝哪个方向运行,它都不会到达这些位置
如果您想自己实现这一点,可以采用递归方法(类似于解析代码,但更简单)。例如,如果你看到一个如果你说:
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
...
}
我可以向您解释控制流图的概念,但我不熟悉库本身
这个概念很简单。将任何连续的代码行(即没有if
、goto
或函数调用或标签)想象为图形的一个节点。每次goto
或函数调用都会创建从当前节点到goto
标签所在节点或其调用函数的定向链接。请记住,函数本身可以是一个图,而不是一个简单的节点,因为它内部可能有if
s或其他函数调用。每个函数调用还创建从函数的叶节点(其中函数return
s)到函数调用后包含代码的节点的定向链接。(这可以创建许多从函数图传出的链接,因为函数可以在代码的许多部分中调用)
同样,如果您有一个if
,那么您有两个从当前节点到if
部分和if
语句的else
部分的方向链接(除非您检测到if(0)
或if(1)
,就像您所说的那样,在这种情况下,只有一个到正确位置的链接)
图形的根是main
的入口点。现在,要找到死代码,您必须做的是从根位置(例如使用DFS或BFS)简单地遍历图,最后查看哪些节点没有被访问。这会显示死掉的代码,也就是说,无论程序朝哪个方向运行,它都不会到达这些位置
如果您想自己实现这一点,可以采用递归方法(类似于解析代码,但更简单)。例如,如果你看到一个如果你说:
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
...
}
您可以看到由提取的图的示例
我们已经使用DMS的数据流分析机器和its在非常大的应用程序(2600万行C)上完成了这项工作,包括分析点,如果您真的想在大型C系统中找到死函数,这是一种实际的必要性。您可以看到由
我们已经使用DMS的数据流分析机器和its在非常大的应用程序(2600万行C)上完成了这项工作,包括分析点,如果您真的想在大型C系统中找到死函数,这是一个实际的必要条件。只是为了得到这个想法:尝试使用以下链(假设你已经安装了llvm和clang二进制文件)clang-cc1yourfile.c;opt-O3-globaldce-dce yourfile.bc-o optfile.bc;llc-march=c optfile.bc
。什么样的“在线活动”建议把它作为没有经验的人的任务?。。