編譯程序(系統)和操作系統一起構建成立計算機中兩大系統軟件;一個是計算機資源的操縱者;另一個是計算機軟件資源的開拓者。
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所指定的內存當中
得到匯編指令后,還需要通過匯編程序翻譯成機器指令,最終才能夠在計算機上執行。