编译器设计

**編譯器**（compiler）是一種電腦程式，它會將某種程式語言寫成的原始碼（原始語言）轉換成另一種程式語言（目標語言）。

它主要的目的是將便於人編寫、閱讀、維護的進階電腦語言所寫作的原始碼程式，翻譯為電腦能解讀、執行的低階機器語言的程式，也就是執行檔。編譯器將原始程式（source program）作為輸入，翻譯產生使用目標語言（target language）的等價程式。原始碼一般為高階語言（High-level language），如 Pascal、C、C++、C# 、Java 等，而目標語言則是組合語言或目標機器的目的碼（Object code），有時也稱作機器碼（Machine code）。

一個現代編譯器的主要工作流程如下：

原始碼（source code）→ 預處理器（preprocessor）→ 編譯器（compiler）→ 組譯程式（assembler）→ 目的碼（object code）→ 連結器（linker）→ 執行檔（executables），最後打包好的檔案就可以給電腦去判讀執行了。

## 歷史

早期的電腦軟體都是用組合語言直接編寫的，這種狀況持續了數年。當人們發現為不同類型的中央處理器（CPU）編寫可重用軟體的開銷要明顯高於編寫編譯器時，人們發明了高階程式語言。由於早期的電腦的記憶體很少，當大家實現編譯器時，遇到了許多技術難題。

大約在 20 世紀 50 年代末期，與機器無關的程式語言被首次提出。隨後，人們開發了幾種實驗性質的編譯器。第一個編譯器是由美國女性電腦科學家葛麗絲・霍普（Grace Murray Hopper）於 1952 年為 A-0 系統編寫的。但是 1957 年由任職於 IBM 的美國電腦科學家約翰・巴科斯（John Warner Backus）領導的 FORTRAN 則是第一個被實作出具備完整功能的編譯器。1960 年，COBOL 成為一種較早的能在多種架構下被編譯的語言。

高階語言在許多領域流行起來。由於新的程式語言支援的功能越來越多，電腦的架構越來越複雜，這使得編譯器也越來越複雜。

早期的編譯器是用組合語言編寫的。首個能編譯自己源程式的編譯器是在 1962 年由麻省理工學院的 Hart 和 Levin 製作的。從 20 世紀 70 年代起，實現能編譯自己源程式的編譯器變得越來越可行，不過還是用 Pascal 和 C 語言來實現編譯器更加流行。製作某種語言的第一個能編譯器，要麼需要用其它語言來編寫，要麼就像 Hart 和 Levin 製作 Lisp 編譯器那樣，用直譯器來執行編譯器。

### 教學用的編譯器

編譯器的構造與最佳化是電腦專業的大學課程，課程名稱一般為「編譯原理」或「編譯器」。通常在課程中包含了如何實現一種教學用程式語言的編譯器。一個著名的例子是 20 世紀 70 年代，瑞士計算機科學家尼克勞斯・維爾特（Niklaus Emil Wirth）用於講解編譯器的構造時使用的 PL/0 編譯器。儘管它很簡單，PL/0 編譯器介紹了這個領域的幾個有影響的概念：

1. 逐步求精的程式開發（也是 1971 年 Wirth 的論文的標題）
2. 使用遞迴下降解析器
3. 使用 EBNF 指定語言的語法。
4. 碼產生器產生可攜式 P-code
5. 在自舉問題的正式描述中使用 T-diagram。

## 分類

編譯器的一種分類方式是按照生成代碼所執行的系統平台劃分，這個平台稱為目標平台。

有一些編譯器輸出的代碼，將執行於與編譯器所在相同類型的電腦和作業系統之上，這種編譯器叫做本地編譯器。輸出可以執行於不同的平台之上的編譯器，叫做交叉編譯器。由於嵌入式系統通常沒有軟體開發環境，因此，為這類系統開發軟體時，通常需要使用交叉編譯器。

編譯器所輸出於虛擬機器上執行之代碼，編譯器和編譯器輸出的執行平台有可能相同，也有可能不同。因此，對於這類編譯器，不去區分它是本地編譯器還是交叉編譯器。

## 參考文獻

## 延伸閱讀

* LLVM community. The LLVM Target-Independent Code Generator. LLVM Documentation. [17 June 2016]. （原始內容存檔於 2021-05-01）.
* Compiler textbook references A collection of references to mainstream Compiler Construction Textbooks
* Aho, Alfred V.; Sethi, Ravi; Ullman, Jeffrey D. Compilers: Principles, Techniques, and Tools 1st. Addison-Wesley. 1986. ISBN 9780201100884.
* Allen, Frances E. A History of Language Processor Technology in IBM. IBM Journal of Research and Development (IBM). September 1981, **25** (5): 535–548. doi:10.1147/rd.255.0535.
* Allen, Randy; Kennedy, Ken. Optimizing Compilers for Modern Architectures. Morgan Kaufmann Publishers. 2001. ISBN 978-1-55860-286-1.
* Appel, Andrew Wilson. Modern Compiler Implementation in Java 2nd. Cambridge University Press. 2002. ISBN 978-0-521-82060-8.
* Appel, Andrew Wilson. Modern Compiler Implementation in ML. Cambridge University Press. 1998 [2020-01-11]. ISBN978-0-521-58274-2. （原始內容存檔於 2021-04-27）.
* Bornat, Richard. Understanding and Writing Compilers: A Do It Yourself Guide (PDF). Macmillan Publishing. 1979 [2020-01-11]. ISBN978-0-333-21732-0. （原始內容 (PDF) 存檔於 2007-06-15）.
* Cooper, Keith Daniel; Torczon, Linda. Engineering a compiler 2nd. Amsterdam: Elsevier/Morgan Kaufmann. 2012: 8. ISBN 9780120884780. OCLC 714113472.
* McKeeman, William Marshall; Horning, James J.; Wortman, David B. A Compiler Generator. Englewood Cliffs, NJ: Prentice-Hall. 1970. ISBN 978-0-13-155077-3.
* Muchnick, Steven. Advanced Compiler Design and Implementation. Morgan Kaufmann Publishers. 1997 [2020-01-11]. ISBN978-1-55860-320-2. （原始內容存檔於 2021-02-23）.
* Scott, Michael Lee. Programming Language Pragmatics 2nd. Morgan Kaufmann. 2005 [2020-01-11]. ISBN978-0-12-633951-2. （原始內容存檔於 2021-04-27）.
* Srikant, Y. N.; Shankar, Priti. The Compiler Design Handbook: Optimizations and Machine Code Generation. CRC Press. 2003 [2020-01-11]. ISBN978-0-8493-1240-3. （原始內容存檔於 2021-04-27）.
* Terry, Patrick D. Compilers and Compiler Generators: An Introduction with C++. International Thomson Computer Press. 1997 [2020-01-11]. ISBN978-1-85032-298-6. （原始內容存檔於 2015-09-14）.
* Wirth, Niklaus. Compiler Construction (PDF). Addison-Wesley. 1996 [2020-01-11]. ISBN978-0-201-40353-4. （原始內容 (PDF) 存檔於 2017-02-17）.

## 參見

* 連結器
* 直譯器

## 外部連結

* 開放目錄專案中的「Compilers」
* Incremental Approach to Compiler Construction （頁面存檔備份，存於網際網路檔案館） – a PDF tutorial
* Compile-Howto （頁面存檔備份，存於網際網路檔案館）
* Basics of Compiler Design，存檔於網際網路檔案館（存檔日期 2018-05-15）
* YouTube 上的 Short animation explaining the key conceptual difference between compilers and interpreters
* YouTube 上的 Syntax Analysis & LL1 Parsing
* Let's Build a Compiler （頁面存檔備份，存於網際網路檔案館）, by Jack Crenshaw
* Forum about compiler development，存檔於網際網路檔案館（存檔日期 2014-10-10）
* Difference Between Compiler and Interpreter （頁面存檔備份，存於網際網路檔案館）