❶ 【編譯原理】第二章:語言和文法
上述文法 表示,該文法由終結符集合 ,非終結符集合 ,產生式集合 ,以及開始符號 構成。
而產生式 表示,一個表達式(Expression) ,可以由一個標識符(Identifier) 、或者兩個表達式由加號 或乘號 連接、或者另一個表達式用括弧包裹( )構成。
約定 :在不引起歧義的情況下,可以只寫產生式。如以上文法可以簡寫為:
產生式
可以簡寫為:
如上例中,
可以簡寫為:
給定文法 ,如果有 ,那麼可以將符號串 重寫 為 ,記作 ,這個過程稱為 推導 。
如上例中, 可以推導出 或 或 等等。
如果 ,
可以記作 ,則稱為 經過n步推導出 ,記作 。
推導的反過程稱為 歸約 。
如果 ,則稱 是 的一個 句型(sentential form )。
由文法 的開始符號 推導出的所有句子構成的集合稱為 文法G生成的語言 ,記作 。
即:
例
文法
表示什麼呢?
代表小寫字母;
代表數字;
表示若干個字母和數字構成的字元串;
說明 是一個字母、或者是字母開頭的字元串。
那麼這個文法表示的即是,以字母開頭的、非空的字元串,即標識符的構成方式。
並、連接、冪、克林閉包、正閉包。
如上例表示為:
中必須包含一個 非終結符 。
產生式一般形式:
即上式中只有當上下文滿足 與 時,才能進行從 到 的推導。
上下文有關文法不包含空產生式( )。
產生式的一般形式:
即產生式左邊都是非終結符。
右線性文法 :
左線性文法 :
以上都成為正則文法。
即產生式的右側只能有一個終結符,且所有終結符只能在同一側。
例:(右線性文法)
以上文法滿足右線性文法。
以上文法生成一個以字母開頭的字母數字串(標識符)。
以上文法等價於 上下文無關文法 :
正則文法能描述程序設計語言中的多數單詞。
正則文法能描述程序設計語言中的多數單詞,但不能表示句子構造,所以用到最多的是CFG。
根節點 表示文法開始符號S;
內部節點 表示對產生式 的應用;該節點的標號是產生式左部,子節點從左到右表示了產生式的右部;
葉節點 (又稱邊緣)既可以是非終結符也可以是終結符。
給定一個句型,其分析樹的每一棵子樹的邊緣稱為該句型的一個 短語 。
如果子樹高度為2,那麼這棵子樹的邊緣稱為該句型的一個 直接短語 。
直接短語一定是某產生式的右部,但反之不一定。
如果一個文法可以為某個句子生成 多棵分析樹 ,則稱這個文法是 二義性的 。
二義性原因:多個if只有一個else;
消岐規則:每個else只與最近的if匹配。
❷ 編譯原理
編譯原理):利用編譯程序從源語言編寫的源程序產生目標程序的過程; 用編譯程序產生目標程序的動作。 編譯就是把高級語言變成計算機可以識別的2進制語言,計算機只認識1和0,編譯程序把人們熟悉的語言換成2進制的。
編譯程序把一個源程序翻譯成目標程序的工作過程分為五個階段:詞法分析;語法分析;語義檢查和中間代碼生成
(2)編譯原理推導是什麼意思擴展閱讀:
編譯程序的語法分析器以單詞符號作為輸入,分析單詞符號串是否形成符合語法規則的語法單位,如表達式、賦值、循環等,最後看是否構成一個符合要求的程序,按該語言使用的語法規則分析檢查每條語句是否有正確的邏輯結構,程序是最終的一個語法單位。
編譯程序的語法規則可用上下文無關文法來刻畫。語法分析的方法分為兩種:自上而下分析法和自下而上分析法。自上而下就是從文法的開始符號出發,向下推導,推出句子。
而自下而上分析法採用的是移進歸約法,基本思想是:用一個寄存符號的先進後出棧,把輸入符號一個一個地移進棧里,當棧頂形成某個產生式的一個候選式時,即把棧頂的這一部分歸約成該產生式的左鄰符號。
❸ (編譯原理) 求下述文法對應正規式: S->0A|1B A->1S|1 B->0S|0
一、簡單的推導思路
1、該文法的對應正規式為:[01|10]+
2、推導:
(1)首先,展開產生式S,可知S要麼以0開頭,要麼以1開頭;
(2)如果S按產生式S->0A展開,則S必以01開頭,因為通過產生式A->1S|1可知,A必定是以1開頭的;
(3)如果S按產生式S->1B展開,則S必以10開頭,因為產生式B必定以0開頭;
(4)綜上,可知,S是以01或10開頭的非終結符號;
(5)當A以產生式A->1展開或 B以B->0展開時,S將推導結束;
(6)當A以產生式A->1S展開或 B以B->0S展開時,產生式中的非終結符號S將重復(1)-(3)的推導步驟;
(7)綜上所述,該文法的對應正規式為:[01|10]+。
二、聯立方程組求解
假設非終結符號S、A、B都分別代表一個正規式,則正規文法的產生式集合所代表的就是關於正規式S、A、B的一個方程組。
我們將文法「|」符號替換為正規式「+」符號,可得,
S=0A+1B=0(1S+1)+1(0S+0)=01(S+ε)+10(S+ε)=(01+10)(S+ε)=(01+10)S+(01+10)。
根據方程X=rX+t有形如X=r*t的解論斷,可得,
S=(01+10)*(01+10)=[01|10]+。
❹ 編譯原理的最左推導和最右推導問題
最左推導:
S=> (L) =>(L,S)=>(S,S)=>(a,S)=>(a,(L))=>(a,(L,S))=>(a,(S,S))=>(a,((L),S))=>(a,((L,S),S))
=>(a,((S,S),S))=>(a,((a,S),S))=>(a,((a,a),S))=>(a,((a,a),(L)))=>(a,((a,a),(L,S)))
=>(a,((a,a),(S,S)))=>(a,((a,a),(a,S)))=>(a,((a,a),(a,a))) 共17步
最右推導
S=> (L) =>(L,S)=>(L,(L))=>(L,(L,S))=>(L,(L,(L)))=>(L,(L,(L,S)))=>(L,(L,(L,a)))=>(L,(L,(S,a)))
=>(L,(L,(a,a)))=>(L,(S,(a,a)))=>(L,((L),(a,a)))=>(L,((L,S),(a,a)))=>(L,((L,a),(a,a)))
=>(L,((S,a),(a,a)))=>(L,((a,a),(a,a)))=>(S,((a,a),(a,a)))=>(a,((a,a),(a,a)))
❺ 編譯原理問題:求解
E是文法開頭。ε代表終結符號(推理中代表終點或結果,程序語言中代表常量等)。E T 這些大寫字母一般代表非終結符號(這些代表中間過程,非結果。程序中代表函數等等)。開始是E。因為有個G(E)。E就是文法開始符號。推導就有E開始,它也是一個非終結符(代表函數、或者一個推導過程,類似於程序中的main(c++)、winmain(vc++)、dllmain(dll)等主函數)。
1算術表達式文法:這個文法是一個遞歸文法。計算機進行邏輯推導時會走很多彎路(類似於遍歷一顆樹的過程)。為了不讓計算機走彎路(提高效率的目的),可以變換為第二種文法。這種文法消除了遞歸(消除了歧義,類似於後綴表達式),使計算機可以一條直線走到底兒推導出結果。
我也很久沒看編譯原理了。 呵呵
❻ 編譯原理全部的名詞解釋
書上有別那麼懶!。。。。
編譯過程的六個階段:詞法分析,語法分析,語義分析,中間代碼生成,代碼優化,目標代碼生成
解釋程序:把某種語言的源程序轉換成等價的另一種語言程序——目標語言程序,然後再執行目標程序。解釋方式是接受某高級語言的一個語句輸入,進行解釋並控制計算機執行,馬上得到這句的執行結果,然後再接受下一句。
編譯程序:就是指這樣一種程序,通過它能夠將用高級語言編寫的源程序轉換成與之在邏輯上等價的低級語言形式的目標程序(機器語言程序或匯編語言程序)。
解釋程序和編譯程序的根本區別:是否生成目標代碼
句子的二義性(這里的二義性是指語法結構上的。):文法G[S]的一個句子如果能找到兩種不同的最左推導(或最右推導),或者存在兩棵不同的語法樹,則稱這個句子是二義性的。
文法的二義性:一個文法如果包含二義性的句子,則這個文法是二義文法,否則是無二義文法。
LL(1)的含義:(LL(1)文法是無二義的; LL(1)文法不含左遞歸)
第1個L:從左到右掃描輸入串 第2個L:生成的是最左推導
1 :向右看1個輸入符號便可決定選擇哪個產生式
某些非LL(1)文法到LL(1)文法的等價變換: 1. 提取公因子 2. 消除左遞歸
文法符號的屬性:單詞的含義,即與文法符號相關的一些信息。如,類型、值、存儲地址等。
一個屬性文法(attribute grammar)是一個三元組A=(G, V, F)
G:上下文無關文法。
V:屬性的有窮集。每個屬性與文法的一個終結符或非終結符相連。屬性與變數一樣,可以進行計算和傳遞。
F:關於屬性的斷言或謂詞(一組屬性的計算規則)的有窮集。斷言或語義規則與一個產生式相聯,只引用該產生式左端或右端的終結符或非終結符相聯的屬性。
綜合屬性:若產生式左部的單非終結符A的屬性值由右部各非終結符的屬性值決定,則A的屬性稱為綜合屬
繼承屬性:若產生式右部符號B的屬性值是根據左部非終結符的屬性值或者右部其它符號的屬性值決定的,則B的屬性為繼承屬性。
(1)非終結符既可有綜合屬性也可有繼承屬性,但文法開始符號沒有繼承屬性。
(2) 終結符只有綜合屬性,沒有繼承屬性,它們由詞法程序提供。
在計算時: 綜合屬性沿屬性語法樹向上傳遞;繼承屬性沿屬性語法樹向下傳遞。
語法制導翻譯:是指在語法分析過程中,完成附加在所使用的產生式上的語義規則描述的動作。
語法制導翻譯實現:對單詞符號串進行語法分析,構造語法分析樹,然後根據需要構造屬性依賴圖,遍歷語法樹並在語法樹的各結點處按語義規則進行計算。
中間代碼(中間語言)
1、是復雜性介於源程序語言和機器語言的一種表示形式。
2、一般,快速編譯程序直接生成目標代碼。
3、為了使編譯程序結構在邏輯上更為簡單明確,常採用中間代碼,這樣可以將與機器相關的某些實現細節置於代碼生成階段仔細處理,並且可以在中間代碼一級進行優化工作,使得代碼優化比較容易實現。
何謂中間代碼:源程序的一種內部表示,不依賴目標機的結構,易於代碼的機械生成。
為何要轉換成中間代碼:(1)邏輯結構清楚;利於不同目標機上實現同一種語言。
(2)便於移植,便於修改,便於進行與機器無關的優化。
中間代碼的幾種形式:逆波蘭記號 ,三元式和樹形表示 ,四元式
符號表的一般形式:一張符號表的的組成包括兩項,即名字欄和信息欄。
信息欄包含許多子欄和標志位,用來記錄相應名字和種種不同屬性,名字欄也稱主欄。主欄的內容稱為關鍵字(key word)。
符號表的功能:(1)收集符號屬性 (2) 上下文語義的合法性檢查的依據: 檢查標識符屬性在上下文中的一致性和合法性。(3)作為目標代碼生成階段地址分配的依據
符號的主要屬性及作用:
1. 符號名 2. 符號的類型 (整型、實型、字元串型等))3. 符號的存儲類別(公共、私有)
4. 符號的作用域及可視性 (全局、局部) 5. 符號變數的存儲分配信息 (靜態存儲區、動態存儲區)
存儲分配方案策略:靜態存儲分配;動態存儲分配:棧式、 堆式。
靜態存儲分配
1、基本策略
在編譯時就安排好目標程序運行時的全部數據空間,並能確定每個數據項的單元地址。
2、適用的分配對象:子程序的目標代碼段;全局數據目標(全局變數)
3、靜態存儲分配的要求:不允許遞歸調用,不含有可變數組。
FORTRAN程序是段結構,不允許遞歸,數據名大小、性質固定。 是典型的靜態分配
動態存儲分配
1、如果一個程序設計語言允許遞歸過程、可變數組或允許用戶自由申請和釋放空間,那麼,就需要採用動態存儲管理技術。
2、兩種動態存儲分配方式:棧式,堆式
棧式動態存儲分配
分配策略:將整個程序的數據空間設計為一個棧。
【例】在具有遞歸結構的語言程序中,每當調用一個過程時,它所需的數據空間就分配在棧頂,每當過程工作結束時就釋放這部分空間。
過程所需的數據空間包括兩部分
一部分是生存期在本過程這次活動中的數據對象。如局部變數、參數單元、臨時變數等;
另一部分則是用以管理過程活動的記錄信息(連接數據)。
活動記錄(AR)
一個過程的一次執行所需要的信息使用一個連續的存儲區來管理,這個區 (塊)叫做一個活動記錄。
構成
1、臨時工作單元;2、局部變數;3、機器狀態信息;4、存取鏈;
5、控制鏈;6、實參;7、返回地址
什麼是代碼優化
所謂優化,就是對代碼進行等價變換,使得變換後的代碼運行結果與變換前代碼運行結果相同,而運行速度加快或佔用存儲空間減少。
優化原則:等價原則:經過優化後不應改變程序運行的結果。
有效原則:使優化後所產生的目標代碼運行時間較短,佔用的存儲空間較小。
合算原則:以盡可能低的代價取得較好的優化效果。
常見的優化技術
(1) 刪除多餘運算(刪除公共子表達式) (2) 代碼外提 +刪除歸納變數+ (3)強度削弱; (4)變換循環控制條件 (5)合並已知量與復寫傳播 (6)刪除無用賦值
基本塊定義
程序中只有一個入口和一個出口的一段順序執行的語句序列,稱為程序的一個基本塊。
給我分數啊。。。
❼ 編譯原理-句型、句子、短語、直接短語、句柄、素短語、最左素短語
在進行語法分析的時候,有時候會對這些詞語的概念不清晰,這里我們就詳細歸納總結一下。
可以看出這個裡面,最需要理解的概念就是短語,其他大部分概念都是在短語基礎上延伸的,從概念上可以看出:
假設有一個文法
針對文法的一個特定句型 (Sd(T)db) , 其推導過程如下:
這個句型 (Sd(T)db) 對應的 CFG 分析樹如下:
那個這個句型 (Sd(T)db) 有多少個短語呢?
還記得短語的定義么, S ⇒* αβδ , αβδ 代表句型就是這里的 (Sd(T)db) 。
因此這個句型 (Sd(T)db) :
演算法非常簡單,就是通過分析樹的後序遍歷,先將子樹的葉節點從左到右排合並成字元串(即一個短語),然後用它代表子樹的根節點的值,再和與子樹根節點同一層節點值合並,得到新的短語。就這樣從分析樹的最底層,一路合並到分析樹的根節點,就能得到所有的短語了。
通過遞歸的方法,獲取短語列表 phraseList , 直接短語列表 directPhraseList 和 素短語列表 plainPhraseList 。
運行結果:
❽ 編譯原理的LL(1)文法是什麼意思
LL(1)的含義:第1個L表明自頂向下分析是從左向右掃描輸入串,第2個L表明分析過程中將用最左到推倒,1表明只需向右看一個符號便可決定如何推倒即選擇哪個產生式(規則)進行推導,類似也可以有LL(k)文法,也就是需要向前查看k個符號才能確定選用哪個產生式。
這是從我們編譯原理課本上抄來的,希望對你有幫助