一个使用递归下降方法实现的cminus编译器,使用nasm作为后端
出于对编译技术的兴趣,小弟在十一期间完成了一个cminus的编译器(Qcc)。没有太大的难度,但还算完成的非常认真,代码可读性较好。希望能与各位大侠一起交流进步。
您可以通过以下方式获取Qcc的源代码
svn checkout http://cminus-compiler.googlecode.com/svn/trunk/ cminus-compiler
下面是关于cminus的一点说明:
关于Qcc:
CMINUS是C语言的一个子集,该语言的语法在《编译原理与实践》第九章附录中有详细的介绍。
C MINUS的语法非常容易使用EBNF进行重写,所以很适合使用递归下降的方法来分析。
写Qcc的初衷:
对编译技术一直很有兴趣,看了不少编译理论方面的书,也看了lcc大部分的源代码,所以一直很想真正的写一个编译器,来巩固一下学过的东西。于是利用十一放假的期间完成了这样一个小编译器。
Qcc的特点:
1,Qcc使用nasm作为后端,也就是说Qcc不直接生成机器代码,它产生能够供nasm使用的汇编代码,然后由nasm生成elf格式的obj文件,再进一步的由ld与glibc连接生成最终的可执行文件。
2,nasm最大的特点是在语法分析的过程中不生成语法树以及任何的中间数据结构,而是直接生成汇编代码。这样做的原因有三个方面:
首先,能够简化cminus的设计,使cminus的源代码非常容易读懂,在c代码和汇编代码中间只隔了薄薄一层的语意处理。如果你有时间去看看cminus的源代码的话,你会发现它非常清晰易懂。
其次,我看过不少编译器,包括lcc都是生成了语法树或者dag(有向无环图),感觉似乎所有的编译器都要去生成这样的中间结构。我不想按部就班的也作同样的事情,于是就进行了一下新的尝试。
最后,生成中间数据结构,最大的作用是为了进行代码优化以及实现跨平台(就像lcc那样)。但是Qcc作为一个简单的演示目的小编译器,并不考虑代码优化的部分,也不考虑能够生成其他平台的汇编代码。所以也就不生成语法树或者dag.
Qcc的实现:
1,Qcc使用lex来生成词法分析程序,请见scanner.l
2,Qcc的语法和语义处理部分在parser.c中。
3,Qcc的符号表管理在symbol.c中
4,Qcc的寄存器分配算法在reg.c中
5,主程序入口在main.c中
6,另外Qcc还包含了计算语法的first和follow集合的两个使用perl完成的脚本:first.pl,follow.pl。
7,关于cminus的EBNF语法请见rules.txt。我们可以使用first.pl和follow.pl来对语法进行处理,生成这个语法对应的first和follow集合。譬如 ./first.pl rules.txt first.txt
8,一些测试例子在sample目录中.
Qcc的使用方法:
make;chmod +x Qcc
./Qcc sample/sort.c
Qcc是一个perl脚本,它将完成目标程序的编译,链接以及执行。
TODO:
语法和语义检查的部分还需要进一步的完善。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
支持一把
很好、很强大,俺也友情支持下!
支持,支持,思路清晰,代码也挺清楚。
很好,这种精神值得学习!~
十一不过7天时间, 就完成了qcc, 可见平时积累的厚重!
看lz列的那些书,没个几年时间我想是看不懂的。可见酝酿多时了
LZ 是牛人,LZ 的贴已经在 C/C++ 置为精华了,这里就不重复操作了。
不错不错
学习一下