編譯器,近在咫尺卻又遠在天邊,當我們寫下任何非機器語言代碼后,我們都需要借助編譯器將這些代碼變為通過計算機可運行的狀態,但是,就是這樣一個使用率極高的程式,我們對其卻知之甚少,什么是編譯器?編譯器對我們的代碼做了什么?又是怎么做的呢?如果你也懷有這些疑問,想要深入編譯器內部一探究竟的話,那就隨我一起踏上這趟編譯器實作的旅程吧,
1. 什么是編譯器
廣義上,編譯器是這樣一個程式:其讀入A語言代碼,并輸出B語言代碼,如下圖所示:
+-------+
A語言代碼 -> | 編譯器 | -> B語言代碼
+-------+
僅從定義上看,A、B可以是同一種語言,也就是說,如果我們寫了一個只是具有“復制粘貼”功能的程式,其也可以被稱為是一個編譯器,但顯然,這樣的編譯器是無意義的,在實際中,編譯器的輸入一般是高級語言代碼,如C語言、Python語言等,而編譯器的輸出一般是低級語言代碼,如匯編語言、各種位元組碼等,匯編語言代碼經由匯編語言編譯器繼續編譯,最終產生機器語言,以供計算機執行;而位元組碼可由能夠執行此位元組碼的虛擬機執行,這樣,就完成了一個程式從撰寫到執行的程序,
2. 編譯器的結構組成
編譯器的內部并不是一個整體,而是由多個組件分工合作,共同完成編譯功能,這些組件總體上可被分為兩個部分:編譯器前端和編譯器后端,如下圖所示:
+----------+ +----------+
A語言代碼 -> | 編譯器前端 | -> 中間代碼 -> | 編譯器后端 | -> B語言代碼
+----------+ +----------+
由于我們寫下的高級語言代碼并不是編譯器比較喜歡的形式,故編譯器通過編譯器前端讀取、檢查并重新組織源代碼,使之等價變換為編譯器喜歡的形式,即中間代碼;一般來說,語法錯誤也由編譯器前端負責檢查,接下來,編譯器后端就拿著中間代碼進行進一步的檢查、優化,最終生成目標代碼,
事實上,編譯器前后端又分別可以進一步細分為多個組件,這些組件將在我們接下來的旅程中逐一講述,
3. 我們將要實作什么
在這次旅程的終點,我們將實作一個名為CMM(即C Minus Minus)語言的編譯器,這個編譯器的輸出將是由我們自己設計的一套指令集中的指令所構成的指令檔案,所以,我們還將實作一套虛擬機程式,以運行編譯器輸出的指令檔案,
CMM語言是一門將C語言的語法進行縮減后得到的語言,其主要特點如下:
- 只有一種型別:int
- 支持賦值、四則運算與比較運算
- 支持if、while陳述句
- 支持函式
- 支持陣列
- 區分全域作用域與區域作用域
接下來,就讓我們深入編譯器前端一探究竟吧,請看下一章:《編譯器前端概觀》,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/261226.html
標籤:C++
上一篇:徹底理解c++的隱式型別轉換
