• 2009-05-10

    程序员的编译入门教材

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-logs/39193223.html

    提起编译器,很多程序员都会心向往之,但真的动手实现一个编译器,许多人心里就打起了退堂鼓。因为在他们心里,编译器等价于编译原理,而编译原理就意味着一大堆让人找不到北的名词:有限自动机、语法制导翻译、窥孔优化……

    我承认,读书的时侯,我也被这些东西恐吓住了,虽然编译原理这门课我得了一个不错的分数,但还是一脑子浆糊。不过,我相信,如果不能把想学的学生教明白,多半是教材(和老师)有问题。所以,大部分的编译原理教材是不合适的。但合适的在哪里呢?

    之所以这些教材不让人喜欢,主要是这些教材一上来就给扔下一大堆理论。作为一个程序员,我们最喜欢的是代码。所以,如果给我看代码,然后,结合代码给我讲理论,我才可能心情愉悦的接受这些理论。

    有龙书之称的《编译原理》是个不错入门书。我知道,有些人已经开始怀疑我了。只要看一下龙书的目录,就会发现,它和大多数编译原理教材没有本质的区别。不过,这里并不是让你读完整本龙书,我推荐的程序员入门教材只是其中的第二章。

    这一章实现了一个非常简单的编译器,把一个自定义的语言转换成一个中间代码。无论是语言,还是中间代码都非常简单,但这并不妨碍支撑起一个完整的编译器前端框架:定义语言、定义运算符优先级、词法分析、语法分析、建立符号表、代码生成。所有这些东西对于实现一个编译器都是必需的。龙书第二版选择了Java作为第二章的实现语言,而在第一版的实现语言是C,从入门的角度而言,让人有了更多的选择。

    这是一个纯手工打造的编译器,所以,我们可以清晰的看到代码到中间代码的转换过程。之所以强调它的纯手工,是对比于现在很多的编译器前端生成工具而言,比如yacc和Antlr。这样的工具可以极大的程度提高我们的生产率,但是从学习的角度,纯手工编译器可以帮我们理解这些工具运作的机理。了解了纯手工过程之后,如果还想了解依赖工具实现,那就不妨参考有人实现的Antlr版本。唯一的遗憾是,这个版本用的Antlr 2,而不是最新的版本。

    读完了龙书的第二章,我们拥有了编写编译器前端的基础知识,但这些内容还不足以让我们窥见构建程序设计语言的全貌。《Unix编程环境》(The Unix Programming Environment)是我们的下一站。

    放心,同龙书一样,我不会让推荐读完这本看上去和编译器没什么关系的书。我们的选择还是其中的一章,第八章,一个关于程序开发的章节。原本,这是一个介绍如何在Unix上做开发的章节,实现了一个计算器,只不过,随着功能不断丰富,这个计算器最终变成了一个完整的语言(hoc)。同龙书第二章只生成中间代码不同,这个实现真的是一个完整可用的语言。

    这章用了六个阶段进行实现:

    • 第一阶段,实现一个简单计算器
    • 第二阶段,加入变量名和错误恢复
    • 第三阶段,实现任意的变量名,并加入了内部函数
    • 第四阶段,实现一个机器,这便是一个虚拟机的雏型
    • 第五阶段,有了控制流和关系运算符
    • 第六阶段,实现函数、过程和I/O

    我非常喜欢这样的讲解方式,完全是一个循序渐进的过程,功能逐渐丰富,每一步做的事情并不多,让人可以专注于当前讲解的部份。考虑到这是一本诞生于1984年的书,如果再年轻一些,估计我们可以看到一个完整的面向对象语言的实现。

    相比于龙书第二章只给了我们一个前端,这里给我们的是一个完整的语言实现。准确的说,不是一种实现方式,前三阶段的实现只是一个简单的解释器,从第四阶段开始,它变身成一个编译器,因为它要运行在一个自己实现的虚拟机上。虽然这个虚拟机并不像我们现在知道的很多虚拟机那么强大,但它已经很好展示出一个虚拟机的运作方式。在学习编译器之余,我们顺便了解了虚拟机。

    这是一本关于Unix的书,所以,即便是在这一章里面,我们可以处处体会到Unix的文化。这章的讲解方式就是最好的一种体现,把事情做简单。六个阶段,每个阶段都很简单,不知不觉中,一个像样的编译器就呈现在眼前。仔细品味知识的同时,顺便习得Unix的工作方式,何乐不为。

    如果打算动手按照书中的内容一步步把这个编译器实现出来,需要说的是,书里面用到的C语言时很早期的C语言,而不是我们熟悉的现代风格。如果你打算用自己习惯的方式编写,那么就要做好调整代码的准备。实际上,这个语言是在不断发展的,所以,我们可以找到它的现代版本(1234),相对来说,现代版本显得有些复杂了。对比书上的内容和现代版本进行实现,是一个不错的选择。

    这里提及只是一些入门教材,了解了以上的内容之后,并不能让人成为一个编译器专家,但应该可以削除对编译器的恐惧,至少,可以去尝试挑战编译原理那些不合适的教材了。

    分享到:

    历史上的今天:

    引用地址:

    评论

  • 博主的建议非常不错,很有帮助
  • 指路明灯啊,原来我所要寻找的东西在《The Unix Programming Environment》里面。这样就能跟接下来的实践之路《Modern Compiler Implementation in (Java/C/Tiger》和《A Retargetable C Compiler - Design and Implementation》连起来了。努力学习了要