前言

本书有两大特征:第一,实际动手实现了真正的编译器;第二,涉及了以往编译器相关书籍所不曾涉及的内容。

先说第一点。

本书通篇讲述了“C♭”这种语言的编译器的制作。C♭基本上是C语言的子集,并实现了包括指针运算等在内的C语言的主要部分。因此可以说,本书实现的是实实在在的编译器,而并非有诸多限制的玩具。

更具体地说,本书实现的C♭编译器是以运行在x86系列CPU上的Linux为平台的。之所以选择x86系列的CPU,是因为这是最普及的CPU,相应的硬件非常容易找到。选择Linux是因为从标准库到程序运行环境的代码都是公开的,只要你有心,完全可以自己分析程序的结构。

可能有些作者不喜欢把话题局限于特定的语言或者OS,而笔者却恰恰更倾向于在一开始就对环境进行限定。因为比起一般化的说明,从具体的环境出发,再向一般化扩展的做法要简单、直观得多。笔者赞成最终把话题往一般化的方向扩展,但并不赞成一开始就一定要做到一般化。

再说第二点。

本书并不局限于书名中的“编译器”,对以编译器为中心的编程语言的运行环境,即编译器、汇编器、链接器、硬件、运行时环境都有所涉及。

编译器生成的程序的运行不仅和编译器相关,和汇编器、链接器等软件以及硬件都密切相关。因此,如果想了解编译器以及程序的运行结果,对上述几部分内容的了解当然是必不可少的。不过这里的“当然”现在看起来也逐渐变得没那么绝对了。

只讲编译器或者只讲汇编语言的书已经多得烂大街了,只讲链接器的书也有一些,但是贯穿上述所有内容的书至今还没有。写编译器的书,一涉及具体的汇编语言,就会注上“请参考其他书籍”;写汇编语言的书,对于OS的运行环境问题却只字不提;写链接器的书,如果读者不了解编译器等相关知识,也就只能被束之高阁了。

难道就不可能完整地记述编程语言的运行环境吗?笔者认为是可能的。只要专注于具体的语言、具体的OS以及具体的硬件,就可以对程序运行的所有环节进行说明了。基于这样的想法,笔者进行了稍显鲁莽的尝试,并最终写成了本书。

以上就是本书的基本原则。下面是本书的读者对象。

●想了解编译器和解释器内部结构的人

●想了解C语言程序运行机制的人

●想了解x86 CPU(Pentium或Intel Core、Operon等)的结构的人

●想了解Linux上的链接、加载和程序库的人

●想学习语法分析的人

●想设计新的编程语言的人

综上,本书是一本基于具体的编程语言、具体的硬件平台以及具体的OS环境,介绍程序运行的所有环节的书。因此,从单纯对编译器感兴趣的读者到以实用为目的的读者,都适合阅读本书。

必要的知识

本书的读者需要具备以下知识。

●Java语言的基础知识

●C语言的基础知识

●Linux的基础知识

本书中制作的C♭编译器是用Java来实现的,所以能读懂Java代码是阅读本书的前提条件。不只是语言,书中对集合等基本库也都没有任何说明,因此需要读者具备相关的知识储备。

本书所使用的Java版本是5.0。关于泛化(generics)和foreach语句等Java 5特有的功能,在第一次出现时会进行简单的说明。

另外,之所以需要读者具有C语言的基础知识,是因为C♭语言是C语言的子集,另外,以C语言的知识为基础,对汇编器的理解也将变得容易得多。不过读者不需要深究细节,只要能够理解指针和结构体可以组合使用这种程度就足够了。

最后,关于shell的使用方法以及Linux方面的常识,这里也不作介绍。例如cd、ls、cp、mv等基本命令的用法,都不会进行说明。

不必要的知识

本书的读者不需要具备以下知识。

●编译器和解释器的构造

●解析器生成器的使用方法

●操作系统的详细知识

●汇编语言

●硬件知识

即使读者对编译器和解释器的构造一无所知,也没有关系,本书会对此进行详尽的说明。

另外,OS及CPU相关的前提知识也基本不需要。能用Linux的shell进行文件操作,用gcc命令编译C语言的“Hello, World”程序,这样就足够了。

本书的结构

本书由以下章节构成。

编译器自身也是一款程序,它将程序的代码逐次进行转换,最终生成可以运行的文件。因此前面章节的内容会成为后续章节的前提,推荐从头开始依次阅读本书的所有章节。

但是,如果你对编译器有一定程度的了解,并且只对特定的话题感兴趣,也可以选取相应的章节来阅读。本书做成的C♭编译器可以显示每个阶段生成的数据结构,因此你也可以实际运行一下C♭编译器,一边确认前一阶段生成的结果,一边往下阅读。

例如,即使跳过语法分析的章节,只要用--dump-ast选项显示前一阶段生成的抽象语法树,就可以理解下一阶段的语义分析和中间代码的相关内容。同样,还可以用--dump-ir选项显示中间代码,用--dump-sam选项显示汇编代码。

致谢

首先感谢RHG读书会的成员阅读了第2部分之前的草稿,并提出了很多宝贵意见。感谢笹田、山下、酒井、向井、shelarcy、志村、岸本、丰福、佐野。

还要感谢3年来一直耐心地等待笔者交稿的SB Creative株式会社的杉山,以及在短时间内对本书600余页的稿件进行编辑的Top Studio Corporation株式会社的武藤。非常感谢!

最后,感谢为本书出版付出努力的各位,以及所有维护Linux和GNU工具等自由软件的人。正是因为有了你们,本书才得以出版。

青木峰郎