1、編譯原理概述
編譯程式(系統)和作業系統一起構建成立計算機中兩大系統軟體;一個是計算機資源的操縱者;另一個是計算機軟體資源的開拓者。
1、我們為什麼需要編譯程式?
- 瞭解它是怎麼將我們編寫的原始碼轉換成可執行程式;
- 為什麼它要這麼設計;
- 為了提升自己 (如 瞭解底層機制,才能有更深入思考問題,以及深層次解決問題的能力,而不是隻能盲目地搜尋答案,從表面解決問題。而學習編譯原理能讓我們從前端的語法維度、程式碼優化的維度、與硬體結合的維度幾個方面,加深對計算機技術的理解,提升自己的競爭力)。
2、什麼是編譯程式?
程式:按照我們編寫的邏輯去執行相應的動作;
編譯程式(compiler):是一種翻譯程式,它特指把某中高階程式設計語言
編譯程式的執行過程包括兩個階段:編譯階段、執行階段。
就好比我們寫的java源程式,首先通過javac編譯成.class位元組碼檔案,之後再通過直譯器java執行此位元組碼檔案。
3、什麼是解釋程式?
解釋程式(interpreter):也是一種翻譯程式,它將源語言書寫的源程式作為輸入,解釋一句後就提交計算機執行一句,並不形成目標程式。
兩者的區別:
- 編譯程式有目標程式;
- 解釋程式無目標程式;
- 編譯程式執行效率高;(我們直接執行目標程式就可以了,不需要完成翻譯的過程)
- 解釋程式便於人機對話;(不斷獲取外界資料,不斷的執行)
4、編譯程式的邏輯結構的6個階段;
詞法分析:識別出有意義的單詞(保留字,識別符號,常量,運算子,分隔符),返回單詞的類別和單詞的值,單詞是組成語言程式的最小單位;
語法分析:在詞法分析的基礎上將單詞序列分解成各類語法短語(如 程式、語句、表示式等)。這種語法短語也稱為語法單位,可表示成語法樹。
語義分析:審查原始碼程式有無語義錯誤,為程式碼生成階段收集型別資訊;(完整性,一致性)
中間程式碼生成:將源程式變成一種內部表示形式,這種內部表示形式叫做中間語言或中間程式碼;
程式碼優化:對前一階段產生的中間程式碼進行變換或進行改造,目的使生成的目的碼更為高效,即省時間和空間;(優化作用,比如 語法合併之類的 java中的三元表示式可以節省if)
目的碼生成:這一階段的任務是把中間程式碼變成特定機器上絕對指令程式碼或可重定位的指令程式碼或彙編指令程式碼;
前端(詞法、語法、語義):將源語言翻譯成一箇中間程式碼的形式;
後端(中間程式碼生成,中間程式碼優化,目的碼生成):將中間程式碼的形式翻譯成目標語言的形式。
5、編譯程式與外文翻譯的類別
I wish you success!
詞法分析 :識別單詞,確認詞類;
語法分析:識別 短語和句型的語法屬性;
語義分析:確認單詞、短語和句型的語義特徵;
中間程式碼生成和程式碼優化:修辭、文字編輯;
目的碼生成:生成譯文;
6、遍
編譯程式對源程式或等價程式從頭到尾掃描的次數。
我通常將整個編譯過程分為兩遍:
-
第一遍:詞法分析、語法分析、語義分析;
-
第二遍:中間程式碼生成、程式碼優化、目的碼輸出;
如:使語法分析器處於核心的位置。當語法分析需要下一個單詞時,就呼叫詞法分析器,識別一個單詞一旦識別出一個語法單位,就呼叫語義分析器,完成語義分析併產生中間程式碼。
7、編譯過程的分析
如下c語言片段程式碼
int a,b;
...
b=a+2*5;
1、詞法分析,識別源程式中的單詞並分類;
(1) 關鍵字(keywords) -- int
(2) 識別符號(identifier) -- a,b
(3) 常數(constant) -- 2,5
(4) 界符(p 這裡有逗號、分號、賦值符號、加號、乘號) -- , ; = + *
2、語法分析:組詞成句及語法錯誤檢查;
b=a+2*5 的分析過程生成的結果是一棵語法樹!
構造句子成功後進行語義分析;
3、語義分析:分析各種語法成分的語義特徵;
-
構建識別符號的語義辭典 -- 符號表
-
構建語句的語義樹 -- 中間語言
如 b = a + 2 * 5
語義樹形式:
四元式形式(中間程式碼生成):語法格式:(運算子,運算物件1,運算物件2,結果)
(1) ( * 2 5 t1 ) //第一條將2*5結果賦給t1 (2) ( + a t1 t2 ) //第二條將a+t1結果賦給t2 (3) ( = t2 _ b ) //第三條將t2的結果賦給b
4、程式碼優化:提高目標程式的質量;
如 b = a + 2 * 5
經常數合併,可分別獲得優化後的中間程式碼;
優化前
中間程式碼:
(1) ( * 2 5 t1 )
(2) ( + a t1 t2 )
(3) ( = t2 _ b )
優化後
中間程式碼:
(1) ( + a 10 t2 )
(2) ( = t2 _ b )
5、目的碼生成;
-
最終,可生成目的碼(彙編指令);
中間程式碼:
(1) ( + a 10 t2 ) (2) ( = t2 _ b )
↓
目的碼:
① LD R,10 //將10這個常量載入到R當中,R為暫存器(指令有取、加、存), LD指取或載入的意思 ② ADD R,a //將a的值加到暫存器當中所儲存的變數的值上面去,結果存在暫存器R當中 ③ ST R,b //將暫存器當中的值存到b所指定的記憶體當中