免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 19248 | 回复: 41
打印 上一主题 下一主题

一个使用递归下降方法实现的cminus编译器,使用nasm作为后端 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-16 11:51 |只看该作者 |正序浏览
本来是放在cpu与编译器版的,但是那里太冷清了,故借贵宝地易用,希望能对大家有点用处:

出于对编译技术的兴趣,小弟在十一期间完成了一个cminus的编译器(Qcc)。没有太大的难度,但还算完成的非常认真,代码可读性较好。希望能与各位大侠一起交流进步。
您可以通过以下方式获取Qcc的源代码
svn checkout http://cminus-compiler.googlecode.com/svn/trunk/ cminus-compiler

下面是关于cminus的一点说明:

关于Qcc:
CMINUS是C语言的一个子集,该语言的语法在《编译原理与实践》第九章附录中有详细的介绍。
C MINUS的语法非常容易使用EBNF进行重写,所以很适合使用递归下降的方法来分析。

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:
语义检查的部分还需要进一步的完善。

onlyflyer@gmail.com

论坛徽章:
0
42 [报告]
发表于 2012-05-04 09:46 |只看该作者
请问在windows平台下怎么运行啊!!!!????急求

论坛徽章:
0
41 [报告]
发表于 2007-11-08 18:54 |只看该作者

大概看了,不错,不过......

这位老兄不错,也喜欢玩编译器啊,同好同好。
时间不够,匆匆看了下,主要关注些核心问题,发现你也没有解决:
1、你生成的是nasm汇编,那么对if、while等需要回填技术的语句翻译,你可以用标号来实现,这样就回避了麻烦的回填。不过作为程序员,是否应该追求完美,直接翻译为机器码,逼着自己用回填技术呢?
2、寄存器饱和时,你用的是push到栈里去(我还见到过YC++生成的不用寄存器调度而狂用pop、push的恐怖代码呢),不过VC这样的编译器似乎是当作临时分配变量存于堆里的,堆似乎要比栈安全些,也更优雅些。
3、函数声明部分,你没考虑旧式的C语法,虽然旧(我不知道ANSI去掉它了没),不过许多现存程序都用这种语法,但这个分析是很麻烦的一件事,我搞了很长时间都没有个漂亮的解决方案。
说实话,虽然我们现在做到的程度其实还是很初级的语法语义分析,但很大一部分精力都得去适应标准,还有一些奇怪的语法,我感觉得用80%的精力去分析20%的语法,这部分其实蛮有挑战性的。后端的编译优化不知什么时候才能做了。
不过毕竟是C-minus嘛,能做到现在这样已经很不错了,而且代码清晰,不错不错不错!
做编译器是件极其耗费脑力的事情,只有心无杂念才能有进展,希望你能继续做下去,有空多交流交流啊

论坛徽章:
0
40 [报告]
发表于 2007-10-19 20:56 |只看该作者

增加了read功能,修正一个bug

最新更改:
1,增加了read功能
2,修正了一个bug.
3,修改了Qcc脚本,Qcc不在去执行生成的可执行文件,而只是完成编译链接的任务。

使用示例:
./Qcc sample/sort.c
./sort
然后输入十个整数
23
25
20
10
9
8
7
7
6
5
得到输出:
5
6
7
7
8
9
10
20
23
25

论坛徽章:
0
39 [报告]
发表于 2007-10-19 16:28 |只看该作者
好邪恶,好强大哦!

论坛徽章:
0
38 [报告]
发表于 2007-10-17 22:28 |只看该作者
楼主真牛

论坛徽章:
0
37 [报告]
发表于 2007-10-17 20:23 |只看该作者
哦,那我说的的没错.

论坛徽章:
0
36 [报告]
发表于 2007-10-17 20:20 |只看该作者
原帖由 edccu 于 2007-10-17 20:18 发表
我理解是, 使用nasm作为后端 就是LZ没有直接编译成机器代码, 而是编译成汇编指令然后借用了nasm编译成机器代码, 不知对不对?

楼上的没看楼主的帖子

论坛徽章:
0
35 [报告]
发表于 2007-10-17 20:18 |只看该作者
我理解是, 使用nasm作为后端 就是LZ没有直接编译成机器代码, 而是编译成汇编指令然后借用了nasm编译成机器代码, 不知对不对?

论坛徽章:
0
34 [报告]
发表于 2007-10-17 20:11 |只看该作者
原帖由 edccu 于 2007-10-17 20:07 发表
使用nasm作为后端 什么意思?

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP