编译技术实验总结感想
《编译技术》实验总结感想
1. 实验总结
这个学期的编译实验一共分为文法解读、词法分析、语法分析、语义分析、代码生成、代码优化几个部分。总体来说,难度依次递增。
我选择的编程语言是Java,这也是我最喜欢的一种语言。在实验开始前,我还在庆幸不用像上学期的OS一样整天跟C语言打交道,又能愉快地编写最喜欢的Java了。
在最初的词法分析和语法分析中,我还体验着迭代开发Java、欣赏自己的设计模式的乐趣中。虽然语法分析的工作量相比于词法分析陡增,但是我个人觉得我的类设计还是比较清晰的,因此写完之后也算是非常有成就感了。
之后的语义分析其实就是建立符号表并处理语义错误,因此比较简单。但完成这里的时候,我深感对于类设计等的欠缺,几乎把面向对象的语言写成了面向过程的语言。而后面的中端代码生成是在语义分析的基础上做的,因此我总体的设计在此后也变得不忍直视。
代码生成我选择的是LLVM IR+MIPS。此时能给予我帮助的只有指导书了,然而我觉得指导书并不全面,只提供了最基本的介绍,具体实现大部分都是我自己摸索出来的。比如在LLVM IR生成中,指导书并没有说符号表到底存什么东西,我最后想的是存地址对应的虚拟寄存器,如果存值的话,还需要考虑分支合并时的phi指令等,如果指导书直接说明phi指令建议在后面优化时实现,可能我会花更少的时间了。
在MIPS的生成时,也有类似情况。我一开始理解错了LLVM IR中”虚拟寄存器“的概念,以为虚拟寄存器就必须得分配一个物理寄存器,所以我直接将后面优化部分的寄存器分配在生成MIPS时就写了,这耗费了我大量的时间。而后来我几乎快完成的时候经同学的提醒,才意识到虚拟寄存器也就是一个变量而已了,完全可以全部放在栈上。
在代码生成的那段时间,特别是MIPS生成,是整个过程最难、耗费时间最长的、最觉得无助的。中间代码和目标代码生成都花费了我快2周时间。一开始我以为MIPS生成就是简单的逐条指令翻译,但是我直接将寄存器分配纳入,使得整个过程非常坎坷,各种bug、各种问题……那时真的是最想放弃的一瞬。
好在直接实现了寄存器分配,使我竞速排序的排名不算太靠后。同时由于耗费了太多时间,我也无力做工作量巨大的复杂优化了(比如LLVM IR mem2reg)。但是我本身也无意去卷竞速排名,我感觉我能做出MIPS并在排名里有一席之地就足够了。最后的最后,我尽我所能地实现了一些比较简单的优化,也算是给整个编译实验画上了一个圆满的句号吧。
2. 感想
完成整个编译实验是我个人第一次独立完成工作量和复杂度这么庞大的项目了,最后看了一下总共有9216行代码。但肯定不是代码行数越多就越好,我在中后期里类和方法设计方面比较欠缺,代码的质量也不算太高。虽然每次作业都是”万事开头难“,但是每次点击IDEA的”新建类“按钮都满怀着期待,期待着这个类的设计能够足够完美,而足够完美的设计在方便使用的同时真的能给人自豪感;虽然每次编码、debug过程都非常艰辛,但是每次看到AC通过的赏心悦目的绿色时,会感觉一切都值了。
3. 一点建议
希望指导书可以给一些总体的编码实现思路(但是太具体也不行,否则大家都写成一样的了),毕竟从无到有的开发如果没有参考还是很有难度的,而且容易走弯路。