最近编译原理课写了一个小的编译器,项目周期持续了将近1个月,纯代码的话将近2000行(?没算,github里面显示是由5500+不过有各种文档、测试啥的)。主要按时间顺序经历了以下几个阶段:
- scanner:按需生成token
- parser:
- LL parse table generator
- LL(1) parser
- parse树生成
- 错误处理
- scanner直接报错并继续scan直到生成一个正确的token,或者scan结束
- parser根据同步集合进行错误恢复
- 语义分析与符号表生成
- 是的,因为没有类型,只用判断变量使用前是否定义。。。
- 代码生成
- parse树 -> ast树
- ast树 -> 三地址码
- 虚拟机执行
- 1个pc,所有操作是内存到内存,这样就不用寄存器分配了啊😂
- qt图形化界面魔改
自己还算比较满意的点:
- 设计文档写的还蛮多的,基本上各个阶段都是设计文档写完再编码,确实正确率和速度都快了不少。(这是去了ucb一趟收获的hh,go bears~)
- 命令行版本用makefile管理,自动化测试
- 用了”learn c the hard way”中的单元测试框架,测试自己写的数据结构库和scanner很舒服
- 参考了南大编译原理课的实验手册。。。[ps: 不得不说人家连实验手册写的都那么详细,唉,各种设计tradeoff考虑,加分项的设计,错误信息的格式,而且可以学到实践方面(比如用c的union以及一些奇奇怪怪的数据结构)很多东西。反观我们的spec,抄某个不知名大学(可能是以色列某个?)就不说了,信息量几乎为0,而且前后矛盾、grammar不一致等等。。。让我想到了如何把大象放入冰箱的那个算法,首先找到一头大象,然后打开冰箱门,在把大象放入冰箱,最后关上冰箱门。。。这不说了根没说没啥区别吗。。。而且评分基本只关注用户交互,这是卷都卷得没啥特色。。。]
一些急需提升或者学习的:
- 一个是git多人协作的一些工作流。一个人用的话还好,最后几个人都提交的时候就有点崩。
- 另一个是github的CI/CD,这个是最近看空间里学长有在用,而且企业里一般都会用(不过一般是gitlab)。
- 还有就是一些设计模式的学习,很可惜,软件工程专业没有软件工程课,真的悲哀。因为最后代码量多了之后,几种ir的转换,反正都是树遍历然后生成感觉变成差别不大的糊代码过程😂,一天糊个几百行,然后糊完了。。。
- 然后是c的一些最佳实践之类的,我的内存管理处理的非常不好,我觉得肯定是由泄露的地方的。。。而且最后和gui交互的时候因为懒,堆了不少全局变量。。。
- 此外,感觉别人中等项目一般都用CMake,得去学一波。
- 最后,软件工程还是要去学一波的。。。可能要到研究生再去专门上这门课了。。。(但愿不要失学)