01 / 導讀
導讀
引用
Aho, A. V., Lam, M. S., Sethi, R., & Ullman, J. D. (2006). Compilers: Principles, Techniques, and Tools (2nd ed.). Pearson.
章節概要
第二版約1,000頁,共十二章與兩個附錄。每章以小結結束,多數章還有參考文獻一節。Pearson稱這一版經過全面修訂,新增了三章(第10至12章),分別討論指令層級平行、面向平行與區域性的最佳化,以及程序間分析。作者指出,很少有讀者會真正去建構編譯器,因此本書仍著眼於軟體設計與開發中更廣泛的問題。
第1章:Introduction
語言處理器、編譯器的結構、程式語言的演進、建構編譯器的科學,以及程式語言基礎。它給出了後文依序展開的各個階段。
第2章:A Simple Syntax-Directed Translator
一個小而完整的前端:語法定義、語法導向翻譯、語法分析、簡單運算式的翻譯器、詞法分析、符號表與中間碼產生。在後面各章深入討論各階段之前,先給出一個能執行的整體概覽。
第3章:Lexical Analysis
詞法分析器的作用、輸入緩衝、記號的規格與辨識、Lex產生器、有限自動機、從正規表示式到自動機、詞法分析器產生器的設計,以及基於DFA的模式比對器的最佳化。
第4章:Syntax Analysis
上下文無關文法、文法的撰寫、由上而下分析、由下而上分析、簡單LR分析、更強大的LR分析器、歧義文法的使用,以及分析器產生器。
第5章:Syntax-Directed Translation
語法導向定義、求值順序、語法導向翻譯的應用、翻譯方案,以及L屬性定義的實作。
第6章:Intermediate-Code Generation
語法樹的變體、三位址碼、型別與宣告、運算式的翻譯、型別檢查、控制流程、回填、switch敘述,以及程序的中間碼。
第7章:Run-Time Environments
儲存組織、堆疊上的空間配置、對非區域資料的存取、堆積管理,以及四個關於垃圾回收的小節:入門、基於追蹤的回收、短暫停頓回收與進階主題。
第8章:Code Generation
程式碼產生器的設計問題、目標語言、目標碼中的位址、基本區塊與流程圖、基本區塊的最佳化、簡單程式碼產生器、窺孔最佳化、暫存器配置與指派、透過樹重寫進行指令選擇,以及用動態規劃為運算式產生最佳程式碼。
第9章:Machine-Independent Optimizations
最佳化的主要來源、資料流分析入門及其基礎、常數傳播、部分冗餘消除、流程圖中的迴圈、基於區域的分析與符號分析。
第10–12章:Instruction-Level Parallelism;Optimizing for Parallelism and Locality;Interprocedural Analysis
第二版的新增章節。第10章討論處理器架構、程式碼排程限制、基本區塊排程與全域排程,以及軟體管線化。第11章展開基本概念、作為深入範例的矩陣乘法、迭代空間、仿射陣列索引、資料重用、陣列資料相依分析、無需同步的平行性,以及區域性最佳化。第12章談程序間分析,包括資料流的邏輯表示、指標分析(上下文不敏感與上下文敏感),以及以BDD實作的Datalog。
附錄
附錄A A Complete Front End列出來源語言、主程式、詞法分析器、符號表與型別、運算式的中間碼、布林運算式的跳躍碼、敘述的中間碼、語法分析器,以及前端的建立。附錄B討論如何求線性獨立的解。
核心概念
第1–5章:前端
- 正規表示式與有限自動機:規格化與辨識記號的工具。
- 上下文無關文法與LR分析:形式體系與主要的由下而上分析演算法。
- 語法導向定義:把計算附加到文法產生式上。
第6–8章:中間碼與後端
- 三位址碼:第6章的中間表示。
- 垃圾回收:回收堆積儲存,共用四個小節討論。
- 暫存器配置與指令選擇:第8章的程式碼產生決策。
第9–12章:最佳化與分析
- 資料流分析:沿流程圖推理程式性質的架構。
- 軟體管線化與迭代空間:面向平行與區域性的排程與迴圈轉換思想。
- 程序間分析與指標分析:跨程序邊界的分析,以Datalog表達。
評析
優點
- 貫通始終的涵蓋。 十二章從詞法分析經語法分析、翻譯、程式碼產生直到最佳化,沿著編譯器的流程展開,附錄中還有前端程式碼。
- 分析與最佳化部分分量足。 第9至12章共四章,專門談資料流分析、平行性、區域性與程序間分析。
- 產生器與理論並重。 Lex與分析器產生器和其背後的自動機與文法理論並置。這種搭配適合實驗課既使用lex、yacc等工具、又要求手寫LL(1)與SLR(1)分析器的課程。
- 結構一致。 每章以小結與參考文獻結束,第二版又為現代架構新增三章。
局限
- 對第一個專案而言,前端與理論偏重。 在到達程式碼產生之前,書中先建立了大量自動機與語法分析理論,想盡快做出能執行的編譯器的學生可能更適合專案式教材。
- 後端主題較艱深。 第10至12章討論指令層級平行、仿射迴圈分析與基於Datalog的指標分析,比前面各章要吃力得多。
- 受版本所限。 第二版出版於2006年,距初版二十年,此後語言與處理器方面的發展未被涵蓋。
- 需與課程工具並行學習。 若課程以COOL、LLVM等工具為核心(如下文的UT Austin課程),宜把本書的概念學習與課程自身的工具材料分開安排、並行進行。
在課程中的定位
Dragon Book是編譯器課程中經典、理論豐富的教材。Nystrom的Crafting Interpreters是讀者動手建構兩個直譯器的入門讀物,是在讀本書之前接觸詞法分析、語法分析與虛擬機器的較溫和途徑。Thain的Introduction to Compilers and Language Design是圍繞一個專案、適合一學期課程且可免費取得的精簡教材。Cooper與Torczon的Engineering a Compiler對詞法與語法分析著墨較少,而把更多篇幅給了中間表示、最佳化、指令選擇、排程與暫存器配置,因此是大學部課程中最接近的替代選擇;下文介紹的UT Austin課程把兩者列為選用的替代教材,並未排出高下。Pierce的Types and Programming Languages是型別系統的研究所教材,對型別系統的論述遠比第6章中的型別檢查一節詳盡。
如何使用本書
本書適合資料結構紮實、了解基本自動機與文法、並接觸過一些組合語言層級程式設計的大學部高年級與研究所一年級學生。舉一個具體參照:下文的UT Austin課程要求先修計算機組織與程式設計課程(例如CS429與CS312,或對應的ECE課程),並期望學生具備機器組織、組合語言概念、C++與基本物件導向程式設計能力。
實用的閱讀方案:
- 第一門課的核心: 第1至8章,先把第2章當作一個小而完整的編譯器來讀。
- 最佳化: 第9章作為資料流分析入門,也是第10至12章的基礎。
- 選讀與進階: 第10至12章,以及提供可執行前端程式碼的附錄A。
- 垃圾回收: 7.5至7.8節可以暫時擱置,或作為獨立單元閱讀。
閱讀時搭配一個小型編譯器專案;附錄A中的前端展示了完整編譯器的樣貌。
課程中的使用方式
以下兩門課的現有課程文件都沒有列出具體章節或頁碼的指定閱讀,因此宜把本書當作選擇性參考書,而非從頭讀到尾的指定讀物。
- 流程導向且附實驗課的課程之參考書。 IIT Kharagpur資工系網站上的一個編譯器理論與實驗課程頁面(頁面上的公告與作業標註2025年日期;課程頁面)將本書列於Books and References之下,並未標示為必讀。同一清單還有Holub的Compiler Design in C、Appel的Modern Compiler Implementation in C、Muchnick的Advanced Compiler Design and Implementation,以及一本lex/yacc參考書。其實驗作業包括Lex、LL(1)與SLR(1)分析、lex/yacc整合、L屬性文法、指派敘述的中間碼,以及回填。本書在第3至6章討論這些主題,但課程頁面並未把作業對應到教科書章節。
- 以最佳化為重心之課程的選用教材。 UT Austin的ECE479K Compilers(2025年秋季;課程大綱)沒有必讀教科書。大綱把本書(第2版)與Cooper和Torczon的Engineering a Compiler(第3版,2022)列為選用的替代教材,並指出學生不太可能兩本都需要。課程先講前端,之後集中於中間表示、執行期環境、控制流程與資料流分析、最佳化、暫存器配置、指令選擇與指令排程。實驗以COOL與LLVM為基礎,從語法分析、中間碼產生、資料流最佳化,一路到後端程式碼產生與暫存器配置。在這類課程中,書中最對應的是第6至9章,以及第10章的排程內容;閱讀這些章節時,可搭配課程的工具材料一起學習。
版本說明
兩門課列的都是第二版,也就是本頁介紹的版本。ECE479K標示為Addison-Wesley,2006年9月。IIT Kharagpur頁面標示為Addison-Wesley,2006年,並另列Pearson的2014年印度版。該2014年印本仍是同一個第二版,並非新的版次。
