前言
大多數書籍都會有前言部分,作為一本書的鋪墊或介紹。讀者往往會忽略這部分文字,或者一掠而過,并不細細閱讀。本書的前言雖有點啰唆,卻希望讀者在閱讀正文之前費點工夫讀一讀。其原因和目的是希望讀者了解本書的特點,更重要的是讓讀者明白本書的某種局限性和討論的范疇。
在信息技術行業,編譯器(compiler)是編程人員在工作中不可或缺的一種軟件工具。這種軟件工具的出現,使得編程人員能使用更適合閱讀、理解的高級語言進行程序設計。它的存在,極大地提高了編程效率,降低了操作和設計的門檻,使軟件維護和修改調試變得更容易。這一切,或許將成為計算機應用得到迅猛發展的原因。
也正是如此,很多人對編譯器的設計感到好奇:編譯器究竟是如何將編程人員編寫的高級語言(源程序)“翻譯”成計算機能直接運行的機器語言(目標程序)的。自然,各類計算機編程語言的制定、語法規范等細節設計都需要考慮編譯器的設計因素,避免在編譯過程中因為出現諸如語法的多義性而無法正確應對的情況。編譯器的設計過程是復雜和艱難的。其中的困難不僅是語言的“翻譯”不得“走樣”(不遺失指定的操作細節,不增添額外的運算),而且要保證源程序指定的運算順序。此外,這種“翻譯”其實是將源程序中二維(甚至更多維)的數據結構、算法概念等轉換成一維的二進制形式的計算機指令編碼,供目標處理器直接運行。
編譯器是一種基本軟件工具,也是設計、制作應用軟件時所使用的工具。編譯器本身的設計也屬于軟件設計,同樣需要使用編譯器。本書論述的小型C語言編譯器的設計過程,使用的是流行的GNU C/C++工具鏈(GNU C/C++tool chain)。這個設計過程就像是使用一把成品的榔頭來打造一把更小巧的榔頭。
編譯器的設計不容易,困難之處在于涉及復雜的數據結構,以及函數之間可能存在遞歸和交叉遞歸的調用關系,從而給調試帶來難度。此外,編譯器設計的龐大工作量或缺乏經濟效益都容易使人難以堅持。另一方面,編譯器的設計或許并不如想象得那么神秘或難以企及:首先,編譯器的處理對象和本身的運行都屬于靜態處理過程,作為處理對象的源程序不會在運行中發生變化,沒有實時概念;然后,開發環境(如Windows、Linux和macOS)日臻完美,使用的工具不僅免費,而且功能完善。以作者的體會來說,編譯器的設計過程既充滿挑戰,也富有樂趣:眼見自己親手打造的編譯器在運行后輸出了盼望的結果(有時甚至優于預期),并在目標機上順利運行,不免讓人產生成就感!
本書著力敘述具體的設計、編程細節,不側重探究編譯器的設計理論。需要說明的是,作者雖然是計算機專業出身,并長期在企業從事應用軟件設計工作,但是對編譯器的設計卻純屬業余愛好。書中論述的算法、數據結構等大都為個人閉門造車的結果,很可能與業界的主流有別。
本書以目前較為流行的加強型 PIC16Fxxxx為目標處理器(RISC 系統結構,小端式體系),論述開發、設計相應的C語言編譯器工具包(如解析器、匯編器和連接器)的詳細過程。由于受篇幅限制,本書未能將同樣流行的STM8微處理器的設計內容包括在內,實屬遺憾。
為了便于理解和敘述,本書對C語言編譯器的功能進行了適度的削減和弱化,具體如下。
? 基本變量只限于整數類型,即char、int、short、long。
? 不支持struct/union結構中位域(bit-field)的定義和使用。
? 針對函數指針的語法識別進行某些簡化。
? 只支持有限的預處理(語句)功能。
? 采用較為簡單的優化算法和流程。
? 有限且簡單的報錯、警示功能。
相信讀者能在理解的基礎上,逐步添加功能,完善上述不足。希望本書能起到拋磚引玉的功效。
本書所設計的C語言編譯器包含4個可執行文件或命令,具體如下。
? 預處理器(pre-processor):C語言源程序預處理操作。
? 編譯解析器(parser):將C語言源程序轉換成目標處理器的匯編語言(文件)。
? 匯編器(assembler):將目標處理器的匯編語言轉換成可浮動目標代碼(文件)。
? 連接器(linker):將整個目標應用程序的目標代碼和編譯系統庫函數鏈接并定位,生成最終可運行的二進制代碼(文件)。
此外,一個完整的編譯系統還包括系統(基本)函數庫和相應的頭文件(header file)。所有這一切,本書均將一一闡述。
本書敘述的設計過程是在 Windows 環境下完成的,采用了 C/C++語言混合編程,力求所使用的語句簡單、易懂。其中,C++語言部分僅使用了類(class)的最基本功能(函數重載),相信具備一般C語言編程基礎的讀者都能理解。由于所使用的C/C++工具由Linux操作系統移植而來,因此所有代碼均可不進行任何修改即可在Linux環境中順利編譯、運行。至于MAX OS環境,也只需極微小的修改便可。
本書設計的編譯器是以控制臺命令方式運行的,與目前業界流行的圖形化集成開發環境(IDE)相比顯得原始、落伍。這是因為在集成化開發環境下嵌入的各類插件、工具,會使編譯工具的功能、效率,以及用戶體驗度得到最大的改善和提升。所有這些,都期待有心者逐步實踐、完善。
讀者可通過掃描下方的二維碼查看或下載本書中的程序源代碼。讀者如有批評、建議及疑問,可通過郵件與作者聯系。
蘇孟晉
聯系方式:diycompiler@gmail.com

程序源代碼
- 在最好的年紀學Python:小學生趣味編程
- vSphere High Performance Cookbook
- Apache Mesos Essentials
- Serverless架構
- 從Excel到Python:用Python輕松處理Excel數據(第2版)
- Hands-On Functional Programming with TypeScript
- C語言程序設計
- ServiceNow:Building Powerful Workflows
- 愛上micro:bit
- 一本書講透Java線程:原理與實踐
- Angular應用程序開發指南
- AV1視頻編解碼標準:原理與算法實現
- 深入解析Java編譯器:源碼剖析與實例詳解
- Hadoop Blueprints
- SAP HANA Cookbook