自己動手開發編譯器(一)編譯器的模組化工程

來源:互聯網
上載者:User

本系列的第一篇,我想概述一下編譯器的構造,同時協助大家瞭解編譯器中各個組成部分的用途。想必大家看別的編譯原理書籍,大都在第一章或者序言之類的地方,將編譯器分成許多模組,然後每一個模組負責編譯的特定階段,最後串起來組成完整的編譯器。比如下面這張圖就是虎書(Modern Compiler by Andrew W. Appel)第一章中出現的編譯器階段:

那麼,為什麼要將編譯器拆成一個個階段,一個個模組呢?答案是,為了更加容易設計和理解。一個完成編譯器怎麼也算是一項大工程,如果不將其分解,將是非常難以編寫和維護的。而編譯器的模組劃分得越清晰,工作就越簡單。比如在詞法分析階段將輸入的字元流轉化成單詞(token)流,就大大減少了文法分析階段需要判斷的輸入種類,在簡化設計的同時還有助於提高效能。此外模組化還將編譯器各個階段的工作盡量獨立開。比如編譯器可以進行與具體CPU無關的最佳化,也可以針對某種CPU進行特定的最佳化,都可以分別獨立進行而不用重新設計整個系統。

 

有個事實可能會令人感到驚訝,編譯器的各個階段和模組如何設計,甚至跟這種程式設計語言的文法有關。比如早期的程式設計語言Fortran,在設計當初人們還沒有掌握現在這麼多編譯原理的理論,它的文法就不能像當今的語言一樣清晰地分成詞法分析和文法分析等階段。因為Fortran的文法並不包含可以用自動機獨立處理的詞法結構。於是,Fortran語言的編譯器在文法分析方面就比較繁雜。有一些曆史背景的語言也可能會具有這種複雜化的文法,比如Visual Basic也屬於不能用獨立的、基於自動機的詞法分析器來掃描的語言。因此VB的文法分析器就要比諸如C#等思路較新語言的難寫很多。另外一個例子是早期的Pascal語言和某些C語言允許用一些特定的文法來指定某變數為寄存器變數(也許在近期的Delphi中仍然存在,求證)。這是因為當時還沒有非常有效寄存器分配演算法,需要程式員憑自己的經驗來決定。在今天如果一種語言還允許顯式指定某個變數是寄存器變數,就會干擾寄存器分配模組的設計。綜上所述我想給各位未來的編譯器設計師們一個建議,好好設計你們的文法,就能大大簡化編譯器的設計!

 

除了簡化設計之外,將編譯器的各個階段模組化還有更大的價值。原先我們認為編譯器只要把源檔案編譯成最終的目標代碼就好了。但是隨著各種各樣的開發工具出現——編輯器、自動完成、調試器、重構工具、測試覆蓋率檢測、效能剖析器…… 人們發現編譯器編譯過程中,各個階段產生的結果都可能是非常有價值的。將編譯器內部結構和中間結果暴露給使用者是必然的趨勢。比如Visual Studio下一代產品中將提供的Compiler as a Service特性,其做法就是將編譯器的內部模組暴露給使用者成為一種服務。我舉幾個例子可以讓大家看到編譯器模組的輸出有哪些可能的用途:

 

編譯器的階段

產生的結果

用途

詞法分析

單詞流

文法高亮

文法分析

抽象文法樹

文法高亮;代碼格式化;程式碼摺疊功能

語義分析

帶類型資訊和符號表的抽象文法樹

重新命名;重構;代碼自動產生;代碼自動改寫

資料流分析

控制流程圖、衝突圖

編輯後繼續運行(Edit and Continue)

這裡我只是舉幾個簡單的例子,以上結果的用途當然不會僅限於此。我相信將編譯器的內部模組暴露給使用者還能產生無數有趣和有價值的應用。

 

上述編譯器的各個階段還可以根據其用途分成兩個大階段:詞法分析、文法分析和語義分析重點在處理程式設計語言的符號系統上,統稱為編譯器的前端(front-end),而中間代碼產生、正常化、指令選擇、控制流程分析、資料流分析、寄存器分配、指令流出、彙編、連結等著重處理代碼計算邏輯的階段統稱為編譯的後端(back-end)。應該說現代編譯器研究的工作重點是編譯器的後端,因為前端的技術已經相對非常成熟。但是前端的技術對我們日常開發來講可能更有機會用到,而且通常更具趣味。所以我也會花較多時間在前端技術上。當大家完成一種編譯器的前端後,有幾種實現後端的選擇:

  1. 使用CLR或Java虛擬機器作為後端。因為這些大型虛擬機器的抽象程度極高,這種方法是最容易的。非常適合動態語言和指令碼。
  2. 採用可靠的開源或商業後端架構。比如著名的LLVM(http://llvm.org/)。這樣可以直接利用LLVM的效能最佳化成果,以及跨平台等特性。
  3. 自己實現後端。要做的事情比較多,但更有助於理解翻譯和最佳化代碼的技術。
  4. 解釋執行。不解釋。。。

我將展示的例子miniSharp雖然是C#文法的子集,但是並沒有限定必須運行在CLR之上。我會將它設定成一個可重新導向的語言,即可以針對多種後端。這樣就可以用一個例子示範儘可能多的技術。我也會視我自己的能力範圍和工作進度動態調整本系列的內容。也希望大家繼續關注VBF.Compilers項目(https://github.com/Ninputer/VBF)和我的微博(http://weibo.com/ninputer)!敬請期待下一篇。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.