前言
本書有兩大特征:第一,實際動手實現了真正的編譯器;第二,涉及了以往編譯器相關書籍所不曾涉及的內容。
先說第一點。
本書通篇講述了“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工具等自由軟件的人。正是因為有了你們,本書才得以出版。
青木峰郎