手把手教你做一個 C 語言編譯器(0):前言

jopen 8年前發布 | 14K 次閱讀 編譯器 C/C++開發

“手把手教你構建 C 語言編譯器” 這一系列教程將帶你從頭編寫一個 C 語言的編譯器。希望通過這個系列,我們能對編譯器的構建有一定的了解,同時,我們也將構建出一個能用的 C 語言編譯器,盡管有許多語法并不支持。

在開始進入正題之前,本篇是一些閑聊,談談這個系列的初衷。如果你急切地想進入正篇,請跳過本章。

前言

為什么要學編譯原理

如果要我說計算機專業最重要的三門課,我會說是《數據結構》、《算法》和《編譯原理》。在我看來,能不能理解“遞歸”像是程序員的第一道門檻,而會不會寫編譯器則是第二道。

(當然,并不是說是沒寫過編譯器就不是好程序員,只能說它是一個相當大的挑戰吧)

以前人們會說,學習了編譯原理,你就能寫出更加高效的代碼,但隨著計算機性能的提升,代碼是否高效顯得就不那么重要了。那么為什么要學習編譯原理呢?

原因只有一個:裝B。

好吧,也許現在還想學習編譯原理的人只可能是因為興趣了。一方面想了解它的工作原理;另一方面希望挑戰一下自己,看看自己能走多遠。

理論很復雜,實現也很復雜?

我對編譯器一直心存敬佩。所以當學校開《編譯原理》的課程后,我是抱著滿腔熱情去上課的,但是兩節課后我就放棄了。原因是太復雜了,聽不懂。

一般編譯原理的課程會說一些:

  1. 如何表示語法(BNF什么的)
  2. 詞法分析,用什么有窮自動機和無窮自動機
  3. 語法分析,遞歸下降法,什么  LL(k) ,LALR 分析。
  4. 中間代碼的表示
  5. 代碼的生成
  6. 代碼優化

我相信絕大多數(98%)的學生頂多學到語法分析就結束了。并且最重要的是,學了這么多也沒用!依舊幫助不了我們學習編譯器!這其中最主要的原因是《編譯原理》試圖教會我們的是如何構造“編譯器生成器”,即構造一個工具,根據文法來生成編譯器(如 lex/yacc)等等。

這些理論試圖教會我們如何用通用的方法來自動解決問題,它們有很強的實際意義,只是對于一般的學生或程序員來說,它們過于強大,內容過于復雜。如果你嘗試閱讀 lex/yacc (或 flex/bison)的代碼,就會發現太可怕了。

然而如果你能跟我一樣,真正來實現一個簡單的編譯器,那么你會發現,比起可怕的《編譯原理》,這點復雜度還是不算什么的(因為好多理論根本用不上)。

項目的初衷

有一次在 Github 上看到了一個項目(當時很火的),名叫 c4 ,號稱用 4 個函數來實現了一個小的 C 語言編譯器。它最讓我震驚的是能夠自舉,即能自己編譯自己。并且它用很少的代碼就完成了一個功能相當完善的 C 語言編譯器。

一般的編譯器相關的教程要么就十分簡單(如實現四則運算),要么就是借助了自動生成的工具(如 flex/bison)。而 c4 的代碼完全是手工實現的,不用外部工具。可惜的是它的代碼初衷是代碼最小化,所以寫得很亂,很難懂。所以本項目的主要目的:

  1. 實現一個功能完善的 C 語言編譯器
  2. 通過教程來說明這個過程。

c4 大致500+行。重寫的代碼歷時一周,總共代碼加注釋1400行。項目地址: Write a C Interpreter

聲明:本項目中的代碼邏輯絕大多數取自 c4 ,但確為自己重寫。

預警

在寫編譯器的時候會遇到兩個主要問題:

  1. 麻煩,會有許多類似的代碼,寫起來很無聊。
  2. 難以調試,一方面沒有很好的測試用例,另一方面需要對照生成的代碼來調試(遇到的時候就知道了)。

所以我希望你有足夠的耐心和時間來學習,相信當你真正完成的時候會像我一樣,十分有成就感。

PS. 第一篇完全沒有正題相關的內容也是希望你能有所心理準備再開始學習。

參考資料

最后想介紹幾個資料:

  1. Let’s Build a Compiler  很好的初學者教程,英文的。
  2. Lemon Parser Generator ,一個語法分析器生成器,對照《編譯原理》觀看效果更佳。

祝你學得愉快。

來自: http://blog.jobbole.com/97332/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!