編譯原理的地位
- 是軟件技術的基礎
- 是計算機專業的基礎課程,是專業必修課
編譯原理的作用
- 編譯原理是介紹如何將高級語言程序變換成低級語言程序的方法。
- 其理論基礎堅實,其形式化系統不僅用於編譯程序,還大量用於人工智能、多媒體技術、數據庫等領域。
程序設計語言
低級程序語言
- 特定的計算機系統所固有的語言
- 即:機器語言、彙編語言
- 特點:執行效率高、編制效率低
高級程序語言
- 與自然語言比較接近的語言
- 過程式語言:C, Pascal, Fortran,
- ADA 對象式語言:Java, C++ 等
- 函數式語言:LISP
- 邏輯式語言:Prolog
- 特點:執行效率低、編制效率高
1.1 什麼是編譯程序
一、編譯程序(又稱“編譯器”)
- 是語言的翻譯器
- 功能:高級語言的源程序低級語言的目標程序
- 重要性:使編程者不必考慮與機器有關的細節
- 本課程主要研究:順序過程式語言的編譯原理和技術
二、高級語言程序的處理過程
三、編譯程序的分類
- 一趟編譯
- 多趟編譯
- 具有調試、優化功能的編譯
都使用相同的基本編譯技術!!
四、編譯程序的歷史和發展
- 20世紀50年代早期:將計算公式翻譯成機器碼
- 20世紀50年代中期:出現了FORTRAN等一批高級語言
(也就出現了相應的編譯程序) - 20世紀50年代後期:出現了編譯程序的編譯程序
(即編譯程序的自動生成工具,如:LEX、YACC) - 20世紀60年代:用自展技術構造編譯程序
(用被編譯語言書寫其自身的編譯程序,1971年PASCAL的成功) - 並行技術與並行語言的發展:——發展方向
並行語言的並行編譯
自動並行編譯技術(將串行程序轉換成並行程序)
1.2 編譯過程和編譯程序的結構
一、編譯過程
1 詞法分析
任務:
從左到右讀入源程序的每個字符,對構成源程序的字符流進行掃描和分解,從而識別出一個個單詞(也叫單詞符號或符號)。
單詞是具有獨立意義的最小語法單位。
如:標識符、保留字(關鍵字或基本字)、算符、界符、常數等。
例. 某源程序片斷如下:
begin
var sum , first , count : real ;
sum := first + count * 10
end.
- 保留字 begin
- 保留字 var
- 標識符 sum
- 逗號 ,
- 標識符 first
- 逗號 ,
- 標識符 count
- 冒號 :
- 保留字 real
- 分號 ;
- 標識符 sum
- 賦值號 :=
- 標識符 first
- 加號 +
- 標識符 count
- 乘號 *
- 整數 10
- 保留字 end
- 界符 .
2 語法分析
任務:
- 依據語言的語法規則,確定源程序的輸入串是否構成一個語法上正確的程序。
- 最終將單詞序列分解成各類語法短語(也叫語法單位),如“程序”、“語句”、“表達式”等。
語法:由程序語言基本符號組成程序中各個語法成分的一組規則。
- 一般語法規則 :由單詞符號構成語法成分的規則;
- 詞法規則 :由基本符號構成的符號書寫規則。
程序結構的遞歸表示
表達式的表示:
1)任何標識符是表達式。
2)任何常數(整常數、實常數)是表達式。
3)若表達式1和表達式2都是表達式,那麼
表達式1+表達式2
表達式1*表達式2
(表達式1)
都是表達式。
語句的表示:
1)標識符:=表達式 是語句
2)while (表達式) do 語句 是語句
3)if(表達式) then 語句 else 語句 是語句
3 語義分析
任務:審查源程序有無語義錯誤,爲代碼生成階段收集類型信息。
主要功能:類型檢查、報語義錯誤、類型轉換等
語義:是程序設計語言中按語法規則構成的各個語法成分的意義。
- 靜態語義:編譯時刻即可確定的語法成分含義。
- 動態語義:運行時刻才能確定的語法成分含義。
4 中間代碼生成
任務:
在語法和語義分析之後,將源程序變成一種“內部表示形式”。
中間代碼:一種結構簡單、含義明確的記號系統。
特徵:
1)結構簡單、含義明確
2)複雜性介於源語言和機器語言之間
3)容易生成;
4)容易將它翻譯成目標代碼。
四元式:
(運算符,運算對象1,運算對象2,結果)
5 代碼優化
任務:對中間代碼進行變換或改造,使之更爲高效(時間、空間)。
6 目標代碼生成
任務:
把中間代碼變換成特定機器上的絕對指令代碼或可重定位的機器指令代碼或彙編指令代碼。
特點:
1)與硬件系統結構和指令含義有關,涉及到硬件系統功能部件的運用、機器指令的選擇、各種數據類型變量的存儲空間分配以及寄存器和後緩寄存器的調度等。
2)高級語言低級語言轉換是基於語義的等價變換,不是結構上的變換。
表格管理
任務:用於保存源程序的各種信息。因爲上述各階段工作均需要查找、更新、構造表格。
出錯處理
任務:報告源程序中錯誤的性質、地點,將錯誤所造成的影響限制在儘可能小的範圍。有些編譯程序還可以自動糾錯。
一個程序是正確的,包括兩層含義:
1)書寫正確(合乎語法規則)
2)含義正確(合乎語義規則)
注意:
多數實用的編譯程序都採用以上幾個階段的工作過程。
有些編譯程序沒有“中間代碼生成”和“代碼優化”。
二、編譯程序的結構
三、編譯階段的組合
前端:主要依賴於源語言而與目標機器無關的編譯階段。如:詞法分析、語法分析、語義分析、中間代碼生成、部分代碼優化、與前端有關的出錯處理工作和表格管理工作。
後端:依賴於目標機而一般不依賴於源語言,只與中間代碼有關的編譯階段。如:目標代碼生成,以及相關出錯處理和表格處理。
遍(趟):對源程序或其等價的中間語言程序從頭到尾掃視並完成規定任務的過程。每一遍掃視可完成編譯的一個階段或多個階段工作。
- 多遍編譯:佔內存少,邏輯結構清晰,耗時長
- 一遍編譯:佔內存多,邏輯結構不清晰,耗時短
1.3 解釋程序和一些軟件工具
一、解釋程序
接受高級語言程序,並立即運行這個源程序。
例如:BASIC語言解釋程序,LISP解釋程序,SQL解釋程序,Java語言中的BYTECODE解釋程序
二、解釋程序與編譯程序的比較
編譯與解釋的根本區別:是否生成目標代碼。
三、解釋程序的優、缺點
優點:可移植性較好。
缺點:(1)速度慢
(2)空間開銷大
有些語言既有編譯程序,又有解釋程序。如java
四、處理源程序的軟件工具
1 語言的結構化編輯器
正文編輯、修改
對源程序正文進行分析(檢查用戶輸入是否正確、自動提供關鍵字、檢查括號的匹配情況)
2 語言程序的調試工具
瞭解程序執行的結果與編程人員的意圖是否一致
允許用戶一行一行跟蹤程序,查看變量值的變化
3 程序格式化工具
分析源程序,並使程序結構變得清晰可讀(如縮排)
4 語言程序測試工具
靜態分析器:不運行源程序,就可以發現其中潛藏的錯誤或異常。
動態分析器:對源程序進行分析,把記錄和顯示程序執行軌跡的語句或函數插入源程序,將運行結果與期望結果進行比較和分析。
5 程序理解工具
對程序進行分析,確定模塊間的調用關係,並畫出控制流程圖。
6 高級語言之間的轉換工具
將一種高級語言程序轉換成另一種高級語言程序
1.4 程序設計語言範型
一、強制式語言(過程式語言、命令式語言)
由一系列的語句組成,每個語句的執行引起若干存儲單元中值的改變。
如:C,Fortran,Pascal
二、函數式語言(應用式語言)
從前面已有的函數出發構造出更復雜的函數。
Function n(…Function 2(Function 1(data))…)
如:ML,LISP
三、基於規則的語言(基於邏輯的語言)
檢查一定的使能條件,當它滿足時,則執行適當的動作。
條件---->動作
如:PROLOG
四、面嚮對象語言
提供抽象數據類型,支持封裝性、繼承性和多態性。
如:Ada,C++,Java
練習
答案:ACAC
答案:BD
答案:BDAC
答案:
(1)詞法分析、語法分析、語義分析、中間代碼生成、代碼優化、目標代碼生成。
(2)表格管理
(3)出錯處理
答案:CB
答案:BCE
答案:(1)表格處理和出錯處理
(2)中間代碼生成(3) 代碼優化
(4)單詞 (5)語法錯誤
答案:ABD
答案:ABCF
因爲代碼優化是爲了提高目標程序的質量,不是必須的,沒有優化源程序一樣能夠轉化爲目標代碼。而中間代碼生成是爲代碼優化服務的,沒有代碼優化的編譯器可以直接生成目標代碼。
答案:BCD
答案:(1)B E (2) D (3) B
12、判斷:“含有代碼優化的編譯器的執行效率高”。
答案:錯。含有代碼優化的編譯器,其優化是指對生成的目標代碼進行了優化,而不是編譯器本身得到了優化,所以,它提高的是目標代碼的執行效率,而不是編譯器本身的執行效率。
13. 判斷:“解釋方式與編譯方式的區別在於解釋程序對源程序沒有真正進行翻譯”。
答案:錯。編譯方式和解釋方式實際上都進行的翻譯,只是編譯相當於筆譯,而解釋相當於口譯。 解釋方式下,不將於源程序徹底翻譯成目標代碼,而是每讀入一條語句,將其翻譯成中間代碼,解釋其含義並執行,然後再讀入下一條語句,再翻譯執行。 編譯方式和解釋方式的根本區別在於“是否生成了目標代碼”。