《編譯原理》復習
README
- 來源網絡&書本&PPT整理
- 截取了老師課上講解or布置的題目
- 一些題目懶得貼答案了,寫了些注意事項
第1 章引論
- 運行編譯程序的計算機:宿主機
- 運行編譯程序所產生的目標代碼的計算機:目標機
第1 題解釋下列術語:
(1)編譯程序:如果源語言為高級語言,目標語言為某台計算機上的匯編語言或機器語言,則此翻譯程序稱為編譯程序。
(2)源程序:源語言編寫的程序稱為源程序。
(3)目標程序:目標語言書寫的程序稱為目標程序。
(4)編譯程序的前端:它由這樣一些階段組成:這些階段的工作主要依賴於源語言而與目標機無關。通常前端包括詞法分析、語法分析、語義分析和中間代碼生成這些階段,某些優化工作也可在前端做,也包括與前端每個階段相關的出錯處理工作和符號表管理等工作。
(5)后端:指那些依賴於目標機而一般不依賴源語言,只與中間代碼有關的那些階段,即目標代碼生成,以及相關出錯處理和符號表操作。
(6)遍:是對源程序或其等價的中間語言程序從頭到尾掃視並完成規定任務的過程。
第2 題
一個典型的編譯程序通常由哪些部分組成?各部分的主要功能是什么?並畫出編譯程序的總體結構圖。(區別編譯程序的六個階段)
答案:一個典型的編譯程序通常包含8 個組成部分,它們是詞法分析程序、語法分析程序、語義分析程序、中間代碼生成程序、中間代碼優化程序、目標代碼生成程序、表格管理程序和錯誤處理程序。其各部分的主要功能簡述如下。
詞法分析程序:輸人源程序,拼單詞、檢查單詞和分析單詞,輸出單詞的機內表達形式。語法分析程序:檢查源程序中存在的形式語法錯誤,輸出錯誤處理信息。
語義分析程序:進行語義檢查和分析語義信息,並把分析的結果保存到各類語義信息表中。
中間代碼生成程序:按照語義規則,將語法分析程序分析出的語法單位轉換成一定形式的中間語言代碼,如三元式或四元式。
中間代碼優化程序:為了產生高質量的目標代碼,對中間代碼進行等價變換處理。
目標代碼生成程序:將優化后的中間代碼程序轉換成目標代碼程序。
表格管理程序:負責建立、填寫和查找等一系列表格工作。表格的作用是記錄源程序的各類信息和編譯各階段的進展情況,編譯的每個階段所需信息多數都從表格中讀取,產生的中間結果都記錄在相應的表格中。可以說整個編譯過程就是造表、查表的工作過程。需要指出的是,這里的“表格管理程序”並不意味着它就是一個獨立的表格管理模塊,而是指編譯程序具有的表格管理功能。
錯誤處理程序:處理和校正源程序中存在的詞法、語法和語義錯誤。當編譯程序發現源程序中的錯誤時,錯誤處理程序負責報告出錯的位置和錯誤性質等信息,同時對發現的錯誤進行適當的校正(修復),目的是使編譯程序能夠繼續向下進行分析和處理。
第3 題 何謂翻譯程序、編譯程序和解釋程序?它們三者之間有何種關系?
答案:翻譯程序是指將用某種語言編寫的程序轉換成另一種語言形式的程序的程序,如編譯程序和匯編程序等。
編譯程序是把用高級語言編寫的源程序轉換(加工)成與之等價的另一種用低級語言編寫的目標程序的翻譯程序。
解釋程序是解釋、執行高級語言源程序的程序。解釋方式一般分為兩種:一種方式是,源程序功能的實現完全由解釋程序承擔和完成,即每讀出源程序的一條語句的第一個單詞,則依據這個單詞把控制轉移到實現這條語句功能的程序部分,該部分負責完成這條語句的功能的實現,完成后返回到解釋程序的總控部分再讀人下一條語句繼續進行解釋、執行,如此反復;另一種方式是,一邊翻譯一邊執行,即每讀出源程序的一條語句,解釋程序就將其翻譯成一段機器指令並執行之,然后再讀人下一條語句繼續進行解釋、執行,如此反復。無論是哪種方式,其加工結果都是源程序的執行結果。目前很多解釋程序采取上述兩種方式的綜合實現方案,即先把源程序翻譯成較容易解釋執行的某種中間代碼程序,然后集中解釋執行中間代碼程序,最后得到運行結果。
廣義上講,編譯程序和解釋程序都屬於翻譯程序,但它們的翻譯方式不同,解釋程序是邊翻譯(解釋)邊執行,不產生目標代碼,輸出源程序的運行結果。而編譯程序只負責把源程序翻譯成目標程序,輸出與源程序等價的目標程序,而目標程序的執行任務由操作系統來完成,即只翻譯不執行。
第4 題 對下列錯誤信息,請指出可能是編譯的哪個階段(詞法分析、語法分析、語義分析、代碼生成)報告的。
(1)else 沒有匹配的if
(2)數組下標越界
(3)使用的函數沒有定義
(4)在數中出現非數字字符
答案:(1)語法分析
(2)語義分析
(3)(課上說是語義分析)
(4)詞法分析
第2 章文法和語言
第1 題文法G=({A,B,S},{a,b,c},P,S)其中P 為:
S→Ac|aB
A→ab
B→bc
寫出L(G[S])的全部元素。
答案:L(G[S])={abc}
第2 題文法G[N]為:
N→D|ND
D→0|1|2|3|4|5|6|7|8|9
G[N]的語言是什么?
答案:G[N]的語言是V+。V={0,1,2,3,4,5,6,7,8,9}
N=>ND=>NDD.... =>NDDDD...D=>D......D
第5題 已知文法G[Z]:Z→aZb|ab 寫出L(G[Z])的全部元素。
答案:Z=>aZb=>aaZbb=>aaa..Z...bbb=> aaa..ab...bbb
L(G[Z])={anbn|n>=1}
第8題 考慮下面上下文無關文法
S—>SS*|SS+|a
(1)表明通過此文發如何生成串aa+a*, 並為該串構造推導樹。
(2)該文法生成的語言是什么?
(2)??? 由a, +, * 組成的逆波蘭表達式
第9題 文法
\(S->S(S)S|\varepsilon\)
(1)生成的語言是什么?
(2)該文發是二義的嗎?說明理由。
第10題
令文法G[E]為:
E->T|E+T|E-T
T->F|T*F|T/F
F->(E)|i
證明E+T*F是它的一個句型,指出這個句型的所有短語,直接短語和句柄。
答:因為E=>E+T=>E+T*F,所以E+T*F是它的一個句型。
因為E=>E+T=>E+T*F,所以該句型相對於E的短語有:E+T*F
因為T-> T*F,所以該句型相對於T的短語有:T*F
直接短語為:T*F
句柄為:T*F
第11題
一個上下文無關文法生成句子abbaa的推導樹如下
(1)
最右推導:
S=>ABS=>ABAa=>ABaa=>ASBBaa=>ASBbaa=> ASbbaa=>Abbaa=>Abbaa=>abbaa
最左推導:
S=>ABS=>aBS=>aSBBS=>aBBS=>aBBS=>abBS=> abbS=>abbAa=>abbaa
(2)
(3)
第3章 詞法分析
第1題
1.構造下列正規式相應的DFA.
(1)1(0|1)*101
第3題
將3.16中的NFA確定化
答:

第4題
- 注意即使初態又是終態的情況
- 畫圖時要記得表上終態和初態
- 確定化的時候要看看是不是已經是確定的了,看兩個方面
- 初態多個:不確定
- 有空轉移:不確定(初態又是終態也是有空轉移的一種情況)
- 同個輸入會轉到很多個狀態:不確定
第7題
- 這類題,容易看漏轉向,建議直接看正規文法。
- 或者做完對着正規文法檢查一遍。
- 做確定化和最小化的題,都要有條理,一個個分析,每個狀態對每個輸入的情況進行分析,否則容易漏掉。
- 看看是否有多余的狀態,(or 多余的產生式:通過S,輸入任何輸入串,都無法到達),多余的刪除。
第9題
- 注意:最小化時,去向為{}和去向非{}是不一樣的,要繼續分割!
第4章 自頂向下語法分析
第1題
-
題目: // TODO:
-
(1) 注意分層
-
(2)
- 改寫:非LL(1)轉換為LL(1)文法。這個知識點主要是提左公因子和消除左遞歸。
- 這道題 \(T \to T,S|S\)
- 遞歸下降子程序:注意要看Select(...),特別是推出\(\varepsilon\)的情況。
- 改寫:非LL(1)轉換為LL(1)文法。這個知識點主要是提左公因子和消除左遞歸。
-
(3)
- 判斷是否為LL(1)文法:看產生式左部相同的SELECT集之間是否有交集,有則不是,否則是。
- 預測分析表:注意看整個預測分析表的結構
-
(4)
- 分析過程:使用預測分析表,預測分析表有四個部分
- 步驟
- 分析棧:右邊是棧頂,初始時棧內為”#S“
- 剩余輸入串:這個不是棧,就是要求的輸入串,從左到右掃描
- 所用產生式或匹配:使用產生式,先在分析棧中把原來的左部彈出,再逆序將右部壓入棧。
- 當最終分析棧和剩余輸入串都是#時,匹配部分寫:接受
- 分析過程:使用預測分析表,預測分析表有四個部分
第2題
- (1) 求FIRST, FOLLOW, SELECT太容易連環錯啦!!!
- 求FIRST時,建議拿個鉛筆對着產生式,求一個刪一個,別看錯了!!!!啊啊啊!!
- 求FOLLOW的時候用哪個產生式,拿手或者對那個產生式做個標記,別看歪了。大😭
- 而且求這個FOLLOW集的時候,可能要用到別的FOLLOW集,別看錯把FIRST集填進去了,最好寫個F幾,到時求出來了就回填。
- (4)遞歸下降分析有緣再貼上來,太多了哈哈🐷
第3題
-
求FIRST的時候建議把\(\varepsilon\)放集合的末尾,以免我又分析完為空的情況就以為自己做完了😐
-
第6章 LR分析
考綱
老師的簡單總結
- 編譯過程的各個階段
- 文法和語言的關系,給定一個文法,生成語言的句子;給定句子,設計相應的文法;文法的分類;句型、句子、最左推導,最右推導,規范推導、短語,直接短語,句柄;
- 單詞的描述工具:正規文法和正規式,有窮自動機,三者之間的轉換關系,有窮自動機的確定化和最小化;
- 自頂向下的語法分析:LL(1)文法,非LL(1)文法消除左遞歸,提取左公因子;預測分析法,遞歸子程序法,如何利用預測分析表進行某個句型或句子的語法分析判斷;
- LR分析:LR(0)\SLR(1),如何構造識別活前綴和可歸前綴的有窮自動機,項目是什么,項目集規范族來構造DFA,得到LR分析表,如何進行語法分析。
- 注意:構造識別一個文法活前綴的有窮自動機是DFA
- 項目:在文法G中每個產生式的右部適當位置添加一個圓點構成項目
- 注意:\(A\rightarrow \varepsilon\)只有一個項目\(A\rightarrow \cdot\)
- 中間代碼的形式,基本語言成分的中間代碼的生成;
- 逆波蘭表達式
- 三元式
- 四元式
- 樹形表示
- 中間代碼優化,分為局部優化,循環優化和全局優化,基本塊,如何利用DAG進行優化;
- 存儲分配:靜態和動態(棧式和堆式);
- 靜態:指在編譯時對數據對象分配固定的存儲位置,運行時始終不變。即一旦存儲空間的某個位置分配給了某個數據名,則在目標程序的整個運行過程中,此位置(地址)就屬於該數據名。
- 特點:簡單,易於實現
- 動態棧式存儲分配:在數據空間中開辟一個棧區,每當調用一個過程時,他所需要的數據空間就分配在棧頂,每當過程工作結束時就釋放這部分空間。空間使用符合先借后還得原則。
- 特點;先借后還,管理簡單,空間使用效率高
- 動態堆式存儲分配:在數據空間中開辟一片連續的存儲區(堆),每當需要時就從這片空間借用一塊,不用時再環。借用和歸還未必服從“先借后還”原則。
- 特點:適用范圍廣,容易出現碎片。
- 靜態:指在編譯時對數據對象分配固定的存儲位置,運行時始終不變。即一旦存儲空間的某個位置分配給了某個數據名,則在目標程序的整個運行過程中,此位置(地址)就屬於該數據名。
- 存儲分配:參數傳遞形式;
- 傳值(值調用)
- 傳地址(引用調用)
- 傳名(換名)
- 目標代碼生成的基本知識。
簡答題復習
文法
- 文法定義 G=(VN, VT, P, S)
- VN:一組非終結符號
- VT:一組終結符號
- P: 一組產生式
- S: 一個開始符號
- 文法分類 按對產生式施加不同的限制把文法分成四種類型:
- 0型:短語文法
- 1型:上下文有關文法
- 2型:上下文無關文法
- 3型:正規文法(正則文法、線性文法)
- 涉及的上下文無關文法:LL(1)文法、LR文法
- 文法的二義性
- 對於一個文法G而言,如果L(G)中存在某個句子對應兩顆不同的語法樹,那么該文法就稱為二義的。
- 文法的實用限制
基本概念(按概念的關聯性分組記憶)
-
直接推出、推導、句型、句子、語言、最左推導、最右推導(規范推導)、規范句型
- 直接推出:
- 推導:
- 句型: 如果符號串x是從識別符號推導出來的,即\(S\Rightarrow ^* x\)那么稱x是G[S]的句型
- 句子:若x僅由終結符號組成,即\(S\Rightarrow ^* x, x\in V_T^*\)
- 語言:文法描述的語言是該文法一切句子的集合。
- 最左推導:
- 最右推導(規范推導):
- 規范句型(右句型):由規范推導所得到的句型
-
-
直接歸約、歸約、句柄、規范歸約(最左歸約)
-
可歸前綴、LR(0)項目集規范族
- 活前綴:形成可歸前綴之前包括可歸前綴的所有前綴
其他
-
什么叫翻譯程序?什么叫匯編程序?什么叫編譯程序
- 編譯程序:將用高級語言書寫的程序翻譯成等價的低級語言程序
- 匯編程序:將用高級語言書寫的程序翻譯成等價的匯編語言程序
- 翻譯程序:將用某種語言編寫的程序轉換成另一種語言形式的程序的程序,如編譯程序和匯編程序等。
-
編譯過程分哪幾個主要階段?每個階段的主要任務是什么?
- 詞法分析:對構成源程序的字符流進行掃描和分解,從而識別出一個個單詞。
- 語法分析:在詞法分析的基礎上,將單詞序列分解成各類語法短語,確定整個輸入串是否構成語法上的正確程序。
- 語義分析:審查源程序是否有語義錯誤,為代碼生成階段收集類型信息。
- 中間代碼生成:將源程序生成一種內部表示形式,這種內部表示形式叫中間代碼。
- 代碼優化:對中間代碼進行等價變換,以便生成更高效的目標代碼。
- 目標代碼生成:把中間代碼變換成特定機器上的絕對指令代碼或可重定位的指令代碼或匯編指令代碼,它的工作與硬件系統和指令含義有關。
-
單詞符號分哪幾類?各舉出例子。
- 標識符
- 基本字(關鍵字)
- 運算符
- 界符
- 常數
-
正則表達式到DFA的轉換(子集法和分割法)
-
什么叫靜態存儲分配?
- 指在編譯時對數據對象分配固定的存儲位置,運行時始終不變。即一旦存儲空間的某個位置分配給了某個數據名,則在目標程序的整個運行過程中,此位置(地址)就屬於該數據名。
- 特點:簡單,易於實現
-
通常參數傳遞有哪些主要方式?每種方式是如何實現的?
- 傳值
- 傳地址
- 傳名
-
中間代碼通常有哪些類型?各有什么特點?
- 逆波蘭記號:運算對象寫在前面,運算符寫在后面,易於計算機處理。
- 三元式
- 四元式:普遍
- 比三元式更便於優化
- 四元式對生成目標代碼有利
- 樹形表示:二目運算對應二叉子樹,朵目運算對應多叉子樹。
-
什么叫語法制導翻譯法?
- 在語法分析過程中,隨着分析的步步進展,每當使用一條產生式進行推導(對於自上而下分析)或歸約(對於自下而上分析),就執行該產生式所對應的語義動作,完成相應的翻譯工作。
-
試述賦值語句、布爾表達式、IF語句、WHILE語句、REPEAT語句的文法、語義、翻譯目標?
-
中間代碼優化分哪幾類?每一類有哪些主要優化技術?
- 局部優化:在只有一個入口、一個出口的基本塊上進行優化。(用DAG)
- 刪除多余運算(刪除公共子表達式)
- 合並已知量與復寫傳播
- 刪除無用賦值
- 循環優化:對循環中的代碼進行優化(用流圖)
- 代碼外提
- 強度削弱
- 變換循環控制條件(刪除歸納變量)
- 全局優化:在整個程序范圍內進行的優化
- 局部優化:在只有一個入口、一個出口的基本塊上進行優化。(用DAG)
-
什么叫基本塊?如何把中間代碼程序划分成基本塊?
- 基本塊是指程序中一順序執行的語句序列,其中只有一個入口語句和一個出口語句。執行試時,只能從入口語句進入,從其出口語句退出。
- 入口語句:
- 程序的第一個語句
- 條件轉移或者無條件轉移語句的轉移目標語句
- 緊跟在條件轉移語句后面的語句
-
基本塊優化的算法
- 借助DAG進行基本塊的優化