2

我正在以一种非常简单的方式刺激死代码去除器。

为此,我的想法是,

步骤1:逐行读取输入的C程序并将其存储在双向链表或数组中。(因为删除和插入比文件操作更容易)。

怀疑:我的方法正确吗?如果是这样,如何最小化每次遍历链表。

第 2 步:将并行分析读取的字符串,并创建表以维护变量名称及其详细信息、函数及其调用等,

第 3 步:将对变量表中的每个条目进行搜索,并将变量替换为其当时的值(因为它有)。(例如)

i=0;
if(i==3) will be replaced by if(0==3).

但是在这样的情况下..

get(a);
i=a;
if(i){} 

在这里,'i' 不会被替换,因为它取决于另一个变量。'a' 不会被替换,因为它取决于用户输入。

怀疑:如果用户输入的是 if(5*5+6){print hello;} ,那肯定是不必要的检查。我如何解决这个表达式以将代码简化为 { print hello; }

第 4 步:将在字符串中搜索 if(0)、while(0) 等,并使用堆栈移除操作块。if(0){//这将被删除*/}

第 5 步:(例如)函数 foo(){/**/} ... if(0) foo(); ...,一旦删除了所有死代码,就会检查函数表中 foo() 的条目,以获取它在代码中被引用的次数。如果为 0,则必须使用相同的堆栈方法删除该函数。

第 6 步:在其余函数中,除了“}”之外,return 语句(如果有)下面的行被删除。这种移除一直持续到函数结束。函数的结尾使用堆栈来标识。

第 7 步:我假设我的无死代码现在已经准备好了。将链表或数组存储在输出文件中。

我的问题是.. 1.我的想法是否有意义?还是可以实施?我该如何改进这个算法?

2.当我试图实现这个想法时,我必须更多地处理字符串操作而不是删除死代码。有什么方法可以减少此算法中的字符串操作。

4

1 回答 1

7

不要这样做。C 是一种自由格式的语言,尝试逐行处理它会导致支持 C 的一个子集,该子集被限制得如此荒谬,以至于它不配得这个名字。

您需要做的是编写一个适当的解析器。那里有大量关于这方面的文献。找出您的学校在其编译器构建课程中使用的教科书,并完成它 - 或者只是参加课程!只有当你关闭了解析器时,你才应该开始考虑语义。然后在抽象语法树而不是字符串上做你的工作。或者,找到一个已经编写和测试过的 C 解析器,您可以重用(但是您仍然需要学习很多东西才能将它与您自己的处理集成)。

如果您最终自己编写解析器,并且它只是为了您自己的启迪,请考虑使用比 C 更简单的语言作为您的主题。尽管随着语言的发展,C at is core 相当紧凑,但要正确获取声明语法的所有细节却出人意料地棘手,并且可能会使您偏离您真正感兴趣的内容。预处理器的存在本身就是一个问题这使得设计有意义的源到源转换变得非常困难。

顺便说一句,您绘制的转换在业内被称为“恒定传播”,或者(在更雄心勃勃的变体中,当它们具有不同的恒定输入时将克隆函数和循环体)“部分评估”。谷歌搜索这些术语可能很有趣。

于 2011-08-27T19:22:23.703 回答