我正在以一种非常简单的方式做一个刺激的死代码移除器。
我的想法是,
步骤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;},这肯定是不必要的检查。我如何解决这个表达式来简化代码为{打印你好;}
第4步:字符串将被搜索if(0),while(0)等,并使用堆栈,删除操作块。If(0){//这将被删除*/}
第五步: foo()函数 (){/**/} ...如果(0)foo ();…删除所有无效代码后,将检查函数表中的foo()条目,以获得它在代码中被引用的次数。如果为0,则必须使用相同的堆栈方法删除该函数。
步骤6:在剩下的函数中,除了'}'之外,返回语句下面的行(如果有的话)都被删除了。这种移除一直持续到函数结束。函数的结束是通过stack来确定的。
第7步:我假设我的无死区代码现在已经准备好了。将链表或数组存储在输出文件中。
我的问题是…1.我的想法是否有意义?或者它是可以实现的吗?如何我能改进这个算法吗?
2。虽然我试图实现这个想法,我不得不处理更多的字符串操作,而不是删除死代码。有办法减少吗
不要这样做。 C是一种自由形式的语言,尝试逐行处理它将导致支持C的一个子集,这个子集是如此荒谬地限制,以至于它不配拥有这个名字。
您需要做的是编写一个适当的解析器。关于这方面有大量的文献。找出你所在学校的编译器构建课程使用的教科书,然后通读它——或者直接上这门课!只有在掌握了解析器之后,才应该开始考虑语义。然后在抽象语法树而不是字符串上做你的工作。或者,找到一个已经编写并测试过的C解析器,您可以重用(但是您仍然需要学习很多东西,以便将其与您自己的处理集成)。
如果您最终自己编写解析器,并且只是为了您自己的启发,请考虑使用比C更简单的语言作为您的主题。尽管C语言的核心是相当紧凑的语言,但是要正确处理声明语法的所有细节是非常棘手的,并且可能会使您偏离真正感兴趣的内容。预处理器的存在本身就是一个问题,它会使设计有意义的源到源转换变得非常困难。
顺便说一下,您所描绘的转换在行业中被称为"恒定传播",或者(在更雄心勃勃的变体中,当函数和循环体具有不同的恒定输入时,它们将克隆它们)"部分评估"。在谷歌上搜索这些词可能会很有趣。