編譯器實現之旅——第七章 編譯器後端概觀

在前面的旅程中,咱們已經實現了整個的編譯器前端。咱們也知道,前端的目標是將源代碼轉變爲抽象語法樹,以供後端使用。從這一章開始,咱們就要前日後端世界一探究竟了,如今,就讓咱們來看看編譯器後端到底由哪些組件組成,其分別又是在作什麼吧。前端

1. 編譯器後端的結構組成

不一樣於編譯器前端,編譯器後端並非一個嚴格的流水線式結構,我想,用「A服務於B」這樣的形容是更爲貼切的。在CMM編譯器的後端中,主要包含了語義分析器和代碼生成器這兩個組件;此外,因爲虛擬機套件和後端關係密切,故咱們這裏也將其一塊兒展現。請看下圖:編程

+-----------+
    抽象語法樹 -> | 語義分析器 | -> 符號表
        |       +-----------+     |
        |                         |
        |                         v
        |                   +-----------+              +-------+
        +-----------------> | 代碼生成器 | -> 低級指令 -> | 虛擬機 |
                            +-----------+              +-------+

2. 什麼是語義分析器

要回答這個問題,首先要討論的是:什麼是語義?語義,說白了就是「一句話的意思」。在平常生活中,咱們每每會聽到「每一個字我都看得懂,可是我不知道這是在說什麼」這樣的形容,這就是語義出現了問題致使的。在編程語言中也是同樣,有的代碼可能徹底符合語法,但其仍然是錯誤的,好比:將兩個不能相加的類型進行相加,就屬於語義錯誤,由於在語法分析器看來,只要代碼知足「A + B」,而不是「+ A B」、「A B +」或是什麼別的錯誤寫法,就是符合語法的。也就是說,語法分析器對代碼的檢查能力並不能知足編程語言中的所有要求,缺失的部分就須要由語義分析器來彌補。後端

語義分析器不單單是一個用於錯誤檢查的組件,其還負責另外一項很是重要的工做:生成符號表。什麼是符號表呢?符號表就是記錄抽象語法樹中任何你想額外記錄下的東西的表,這主要包括變量名、函數名、數組大小等,以服務於代碼生成器。數組

咱們將在語義分析器的相關章節進一步講述語義分析器和符號表的故事。編程語言

3. 什麼是代碼生成器

代碼生成器,顧名思義:生成代碼的組件。代碼生成器一手拿着前端生成的抽象語法樹,一手拿着語義分析器生成的符號表,揹包裏還裝着諸如語法定義,指令集定義等物品,最終生成了可供虛擬機執行的低級指令。代碼生成器是整個編譯器中實現最爲複雜,須要考慮的方面最多的部分,咱們也將在代碼生成器的相關章節中走過至關長的一段旅程。函數

4. 什麼是虛擬機

代碼生成器生成的代碼多種多樣:對於有的編譯器實現,其代碼生成器直接生成彙編語言代碼;而對於包括CMM編譯器在內的另外一類編譯器,其代碼生成器生成的是編譯器做者自行設計的低級指令,這些低級指令就須要專門的虛擬機來執行。計算機執行機器指令,而虛擬機執行相似於機器指令的另外一套指令,「虛擬機」所以得名。對於一個虛擬機來講,其自身模仿了計算機的硬件結構,也具備和管理寄存器、內存等「物理設備」。在真實的編譯器設計中,虛擬機是一個高度複雜的組件,但在CMM的編譯器實現中,咱們設計了一套極爲精簡的指令集和一個很是簡單的虛擬機。設計

咱們將在虛擬機的相關章節進一步講述指令集和虛擬機的故事。code

5. 給讀者的閱讀建議

不一樣於編譯器前端,編譯器後端的各組件之間相互聯繫,共同完成目標。故編譯器後端各章節的閱讀是沒有嚴格的順序之分的,而更像是一種「並行閱讀」。若是你對某個地方爲何要這樣實現,或爲何須要某個東西不能理解,那就看看其餘組件的相關章節吧。因爲代碼生成器是整個編譯器後端的核心,故出於邏輯順序考慮,本文做者將這部分章節放在了最後講述。內存

接下來,就讓咱們首先來看看語義分析器是怎麼實現的,符號表又是什麼樣子的吧。請看下一章:《實現語義分析器》。編譯器

相關文章
相關標籤/搜索