編譯原理定義符號表
『壹』 什麼是*=>星推導(編譯原理) 星推導和加推導的區別
在編譯原理中,產生式的推導可以細分為 *=> "星推導"和 +=> "加推導",
那麼這兩個分別是什麼意思呢?
其實,'*' 和 '+' 這兩個符號是來自 正則表達式 的,正則表達式是什麼大家可以先不了解,弄懂這個問題暫時只需要知道 '*' 和 '+' 這兩個符號的意思就可以了。
符號 * :[1, n) 1到多
符號 + :[0, n) 0到多
則, *=> "星推導" 為對產生式進行1到多次推導; +=> "加推導" 為對產生式進行0到多次推導。
【舉例】
(1)v +=> w:意為產生式左端的 v 經過1到多次推導後能得到右端的 w
(2)v * => w: 意為產生式左端的 v 經過0到多次推導後能得到右端的w(其實,
就是比第(1)條多了一種情況,即 v= w,當 v= w 時,v不需要推導即可得到w,所以推導的次數為0)
『貳』 闄堢伀鏃 緙栬瘧鍘熺悊
絎涓絝狅細緙栬瘧鍘熺悊鍏ラ棬</
鍦ㄧ▼搴忕殑涓栫晫閲岋紝緲昏瘧紼嬪簭鏄璇璦闂寸殑妗ユ侊紝瀹冨皢婧愯璦浠g爜杞鍖栦負閫昏緫絳変環鐨勬墽琛屽艦寮忥紙婧愯璦紼嬪簭 → 閫昏緫絳変環鐩鏍囪璦紼嬪簭</錛夈傜紪璇戠▼搴忓垯鎵婕旂潃鍏抽敭瑙掕壊錛岄氳繃楂樼駭璇璦錛堝侾ython錛夎漿鍖栦負浣庣駭璇璦錛堝傛眹緙栨垨鏈哄櫒鐮侊級錛岀粡榪囩紪璇戝啀鎵ц岋紝鎻愬崌璁$畻鏁堢巼錛楂樼駭璇璦 → 浣庣駭璇璦 → 璁$畻鎵ц</錛夈傜浉姣斾箣涓嬶紝瑙i噴紼嬪簭鍒欏疄鏃惰В鏋愬苟鎵ц岋紝娌℃湁棰勫厛緙栬瘧鐨勮繃紼嬨
緙栬瘧榪囩▼閫氬父鍒嗕負浜斾釜闃舵碉細璇嶆硶鍒嗘瀽銆佽娉曞垎鏋愩佽涔夊垎鏋愩佷紭鍖栧拰鐩鏍囦唬鐮佺敓鎴愩傚叾涓錛岀﹀彿琛ㄦ槸紼嬪簭鐨勪腑鏋錛岃板綍婧愪唬鐮佺殑鍏抽敭淇℃伅錛屾秹鍙婂悇縐嶈〃鏍礆紙絎﹀彿琛錛氭簮紼嬪簭淇℃伅鐨勯泦鎴愪粨搴</錛夈傞亶鍘嗘簮鏂囦歡鏄紼嬪簭澶勭悊鐨勬牳蹇冪幆鑺傦紝緙栬瘧鍣ㄥ垎涓哄墠絝鍜屽悗絝錛屽墠絝鍏蟲敞婧愯璦鐗規э紝鍚庣鍒欓傚簲鐩鏍囨満鍣ㄦ灦鏋勶紙緙栬瘧鍓嶇錛氭簮璇璦鐗規х殑澶勭悊錛岀紪璇戝悗絝錛氱洰鏍囨満鍣ㄧ殑閫傞厤</錛夈
璇璦鐨勫畾涔夌敱璇娉曞拰璇涔変袱閮ㄥ垎鏋勬垚錛屽寘鎷鎶借薄鐨勯昏緫緇撴瀯鍜岃$畻鏈烘墽琛岀殑緇嗚妭銆傜▼搴忎腑鐨勮鍙ュ垎涓烘墽琛屾у拰璇存槑鎬э紝濡傝祴鍊箋佹帶鍒舵祦鍜岃緭鍏/杈撳嚭鎸囦護錛鎵ц屼笌璇存槑錛氳璦鐨勫熀鐭</錛夈備笂涓嬫枃鏃犲叧鏂囨硶鐢辯粓緇撶﹀彿銆侀潪緇堢粨絎︺佸紑濮嬬﹀彿鍜屼駭鐢熷紡瀹氫箟錛屾瀯鎴愮▼搴忕粨鏋勭殑鍩虹錛涓婁笅鏂囨棤鍏蟲枃娉曪細緙栫▼璇璦鐨勯ㄦ灦</錛夈
鎺ヤ笅鏉ョ殑絝犺妭娣卞叆鎺㈣ㄦ枃娉曠殑紜瀹氭у拰浜屼箟鎬э紝浠ュ強鏂囨硶鐨勭被鍨嬪垝鍒嗭紝濡傜煭璇鏂囨硶銆佷笂涓嬫枃鏈夊叧鏂囨硶絳夛紝榪欎簺閮芥槸璁捐″拰鐞嗚В緙栬瘧鍣ㄧ殑鍏抽敭姒傚康錛鏂囨硶綾誨瀷錛氫粠綆鍗曞埌澶嶆潅錛屽畾涔夎璦鐨勮竟鐣</錛夈
璇嶆硶鍒嗘瀽鍣ㄦ槸緙栬瘧嫻佺▼鐨勮搗鐐癸紝瀹冨皢婧愮▼搴忓垎瑙d負鍙璇嗗埆鐨勫崟鍏冿紙璇嶆硶鍒嗘瀽錛氱紪璇戝熀鐭</錛夛紝騫朵笖閫氬父杈撳嚭浜屽厓寮忋備粠NFA鍒癉FA鐨勮漿鎹錛岄氳繃瀛愰泦娉曟秷闄や笉紜瀹氭э紝浼樺寲鐘舵佽〃紺猴紙NFA鍒癉FA鐨勮漿鎹錛氱簿紜鐘舵佽〃紺虹殑杞鎹</錛夈
LR鍒嗘瀽鍣ㄦ槸寮哄ぇ鐨勫垎鏋愬伐鍏鳳紝瀹冨湪LL鏂囨硶鐨勬墿灞曚笂琛ㄧ幇鍑鴻壊錛屾棤鍥炴函鐨勭Щ榪-褰掔害鏈哄埗浣垮緱閿欒媯嫻嬫洿鍙婃椂錛屽垎鏋愯〃璁捐″嶆潅錛LR鍒嗘瀽錛氶珮鏁堝垎鏋愪笌閿欒媯嫻</錛夈侺R鍒嗘瀽鍣ㄧ敱鍔ㄤ綔琛ㄥ拰杞縐昏〃鏋勬垚錛屾敮鎸佸嶆潅榪愮畻絎﹀拰宸﹂掑綊銆
灞炴ф枃娉曚綔涓虹紪璇戝師鐞嗙殑閲嶈佸垎鏀錛岄氳繃涓烘枃娉曠﹀彿璧嬩簣灞炴э紝濡傜被鍨嬪拰鍊礆紝甯鍔╁勭悊璇涔変俊鎮銆傚畠浠鍦ㄧ紪璇戣繃紼嬩腑鍙戞尌鍏抽敭浣滅敤錛岀壒鍒鏄鍦ㄨ娉曞垎鏋愩佽涔夊勭悊鍜屼腑闂翠唬鐮佺敓鎴愪腑錛灞炴ф枃娉曪細緙栬瘧榪囩▼涓鐨勮涔夊姪鎵</錛夈
緙栬瘧浼樺寲涓昏侀泦涓鍦ㄨ娉曞垎鏋愪箣鍚庯紝鐩鏍囦唬鐮佺敓鎴愪箣鍓嶏紝榪芥眰鐨勬槸楂樻晥銆佺瓑浠蜂笖緇忔祹鐨勪唬鐮佺敓鎴愩傚悎鐞嗙殑絎﹀彿琛ㄧ$悊鍜屼紭鍖栫瓥鐣ュ圭紪璇戞晥鐜囪嚦鍏抽噸瑕侊紙浼樺寲絳栫暐錛氳拷奼傛晥鐜囦笌緇忔祹鎬х殑騫寵</錛夈
『叄』 關於編譯原理first follow 和select
首先要明白這三個集的作用和用途,知道了他們是用來做什麼的之後,理解起來就簡單一些
First(A)集的作用是標示在替換非終結符A的時候,替換後的文法的首字母集合,語法分析程序根據這個來判斷給定的語言是否是合法的,是符合規則的。
Follow(A)的作用是標示那些可以出現在A之後的字元,語法分析程序根據這個,在A可以被替換為e(空)的時候來進行判斷,看當前的文法是否是合法的。
這里簡單說明下,比如A->b,A->e(空) 當給定的語言是 bXXXXX的時候,根據第一句文法就可以判定句子合法,但是如果給的語言是cXXXXX的時候,因為A->可以替換為空,這時候就需要一句A的follow集來進行判斷,若A的follow集裡面含有c 則語言是合法的
Select集的作用是將first集和follow集進行合並,如果兩個文法的左端都是A,若他們的select集交集為空,表明他們是兩個無關的,不會產生不確定性的文法,反之,則表明文法不是LL(1)文法
計算的公式很繁雜,理解了意思之後,看就能看出來。。。。
『肆』 編譯原理四元式
四元式的一般形式為(op, arg1, arg2, result),其中:op為一個二元(也可以是零元或一元)運算符。arg1和arg2為兩個運算對象,可以是變數、常數或者系統定義的臨時變數名。result為運算結果。
第一步:T1=a*b,
第二步:T2=c*d,
第三步:T3=T2/e,
第四步:T4=T1-T3,
第五步:f=T4.
『伍』 什麼是文法(編譯原理)
【定義】
文法G定義為四元組(VN,VT,P,S)
其中 VN :非終結符號(即語法變數)集
VT : 終結符號集
VN∩VT =Φ,令V= VN∪VT,V稱為文法G的字母表或字匯表。
P :產生式(α→β)集
S :開始符號,且S∈VN ,S至少要在一條規則的左部出現。
【約定】
一般地,文法G的 四元組 不用全部給出 ,而只將產生式寫出。
約定:
(1)第一條產生式的左部是開始符號
(2)用尖括弧括起來的(或 大寫字母 )是非終結符號
(3)不用尖括弧括起來(或 小寫字母 )是終結符號
(4)還有一種習慣寫法,即 G[S] ,其中 S 是 開始符號 。
【舉例】
例: G=(VN,VT,P,S)
其中 VN={S},
VT ={0,1},
P={S→0S1,S→01}
S是開始符號
『陸』 編譯原理有有符號un-1.u=un嗎
編譯程序把源程序翻譯為目標程序。根據源程序的語言種類,翻譯程序可以分為匯編程序與編譯程序。與之相對,解釋程序是對源程序進行解釋執行的程序。相應的可以將高級語言分為
編譯型 C/C++, Swift, etc.
解釋型 Python, javascript, etc.
混合型 Java, etc.
本文重點放在編譯程序的設計上。典型的編譯程序具有 7 77 個邏輯部分
對源程序掃描一次被稱為一遍 (pass)。典型的一遍掃描編譯程序有如下形式
通常將中間代碼生成前的分析部分稱為編譯器的前端,其後的綜合部分則被稱為後端。這樣就把一個編譯程序分為了與源語言相關和與目標機有關的兩個獨立的部分,降低了程序的耦合。假設 llvm 編譯器 支持 M MM 種源語言到 N NN 種目標語言的編譯
傳統的編譯器如 gcc 可能需要開發 M × N M \times NM×N 個不同的子模塊。而 llvm 使用統一的中間語言 llvm Intermediate Representation 只需要 M MM 個前端與 N NN 個後端,大大降低了開發成本。
文法
設非空有窮集合 Σ \SigmaΣ 為一字母表,則其上的符號串為 ∀ s ∈ Σ ∗ \forall s \in \Sigma^*∀s∈Σ
∗
,其中 ∗ *∗ 表示集合的閉包。特別的記 Σ 0 = ε \Sigma^0 = {\varepsilon}Σ
0
=ε 為空串組成的集合。規則通常寫作
U : : = x or U → x , ∣ U ∣ = 1 , ∣ x ∣ ≥ 0 U ::= x\text{ or }U\rightarrow x,\quad |U| = 1, |x| \ge 0U::=x or U→x,∣U∣=1,∣x∣≥0
其中左部 U UU 是符號,右部 x xx 是有窮符號串。規則的集合 P PP 即可確定一個文法 G GG
<程序> ::= <常量說明><變數說明><函數說明>
<常量說明> ::= {const<常量定義>;}
<常量定義> ::= int<標識符>=<整數>{,<標識符>=<整數>}|char<標識符>=<字元>{,<標識符>=<字元>}
<變數說明> ::= {<類型標識符><變數定義>;}
<變數定義> ::= <標識符>[<下標>]{,<標識符>[<下標>]}
<下標> ::= '['<無符號整數>']' // <無符號整數>表示數組元素的個數,其值需大於0
<函數說明> ::= {(<類型標識符>|void)<函數定義>}void<主函數>
<函數定義> ::= <標識符>'('<參數表>')'<復合語句>
<參數表> ::= [<類型標識符><標識符>{,<類型標識符><標識符>}]
<主函數> ::= main'('')'<復合語句>
<復合語句> ::= '{'<常量說明><變數說明>{<語句>}'}'
<語句> ::= <條件語句>|'{'{<語句>}'}'|<函數調用語句>;|<賦值語句>;|<讀語句>;|<寫語句>;|<返回語句>;|;
<條件語句> ::= <if語句>|<while語句>|<do語句>|<for語句>
<if語句> ::= if'('<條件>')'<語句>[else<語句>]
<while語句> ::= while'('<條件>')'<語句>
<do語句> ::= do<語句>while'('<條件>')'
<for語句> ::= for'('<標識符>=<表達式>;<條件>;<標識符>=<標識符><加法運算符><無符號整數>')'<語句>
<條件> ::= <表達式>[<關系運算符><表達式>] // 表達式為0條件為假,否則為真
<函數調用語句> ::= <標識符>'('[<表達式>{,<表達式>}]')'
<賦值語句> ::= <標識符>['['<表達式>']']=<表達式>
<讀語句> ::= scanf'('<標識符>{,<標識符>}')'
<寫語句> ::= printf'('<字元串>[,<表達式>]')'|printf'('<表達式>')'
<返回語句> ::= return['('<表達式>')']
<表達式> ::= [<加法運算符>]<項>{<加法運算符><項>} // [+|-]只作用於第一個<項>
<項> ::= <因子>{<乘法運算符><因子>}
<因子> ::= <標識符>['['<表達式>']']|'('<表達式>')'|<整數>|<字元>|<函數調用語句>
<整數> ::= [<加法運算符>]<無符號整數>
<標識符> ::= <字母>{<字母>|<數字>}
<無符號整數> ::= <非零數字>{<數字>}|0
<數字> ::= 0|<非零數字>
<非零數字> ::= 1|...|9
<字元> ::= '<加法運算符>'|'<乘法運算符>'|'<字母>'|'<數字>'
<字元串> ::= "{十進制編碼為32,33,35-126的ASCII字元}"
<類型標識符> ::= int|char
<加法運算符> ::= +|-
<乘法運算符> ::= *|/
<關系運算符> ::= <|<=|>|>=|!=|==
<字母> ::= _|a|...|z|A|...|Z
復制
上述文法使用擴充的 BNF 表示法進行描述
符號 定義 說明
∣ \vert∣ 或 作用域由括弧限定
{ t } n m \{t\}^m_n{t}
n
m
將 t tt 重復連接 n ∼ m n \sim mn∼m 次 預設時 m = ∞ , n = 0 m = \infin,\ n = 0m=∞, n=0
[ t ] [t][t] 符號串 t tt 可有可無 等價於 { t } 1 \{t\}^1{t}
1
( t ) (t)(t) 局部作用域 主要用於限定 ∣ \vert∣ 范圍
相關概念有
概念 符號 定義 示例
識別符號 Z ZZ 文法中第一條規則的左部符號 <程序>
字匯表 V VV 文法中出現的全部符號 { <程序>, <常量說明>, …, 0, 1, … }
非終結符號集 V n V_nV
n
全部規則的左部組成的集合 { <程序>, <常量說明>, <變數說明>, … }
終結符號集 V t V_tV
t
V − V n V - V_nV−V
n
{ 0, 1, …, _, a, b, … }
設 U : : = u ∈ P U ::= u \in PU::=u∈P 則對於 ∀ x , y ∈ V ∗ \forall x, y \in V^*∀x,y∈V
∗
有直接推導 x U y ⇒ x u y xUy \Rightarrow xuyxUy⇒xuy 。如果 y ∈ V t ∗ y \in V_t^*y∈V
t
∗
則 x U y ⤃ x u y xUy\ ⤃\ xuyxUy ⤃ xuy 稱為規范推導。直接推導序列 u 0 ⇒ u 1 ⇒ ⋯ ⇒ u n u_0 \Rightarrow u_1 \Rightarrow \cdots \Rightarrow u_nu
0
⇒u
1
⇒⋯⇒u
n
可簡記為
{ u 0 ⇒ + u n n > 0 u 0 ⇒ ∗ u n n ≥ 0 \begin{cases} u_0 \mathop\Rightarrow\limits^+ u_n & n > 0\\ u_0 \mathop\Rightarrow\limits^* u_n & n \ge 0\\ \end{cases}{
u
0
⇒
+
u
n
u
0
⇒
∗
u
n
n
>
0
n
≥
0
進一步定義
句型 V ∗ ∋ x ⇐ ∗ Z V^* \ni x \mathop\Leftarrow\limits^* ZV
∗
∋x
⇐
∗
Z
句子 V t ∗ ∋ x ⇐ + Z V_t^* \ni x \mathop\Leftarrow\limits^+ ZV
t
∗
∋x
⇐
+
Z
語言 L ( G ) = { x ∣ x is sentence } L(G) = \{ x| x\text{ is sentence} \}L(G)={x∣x is sentence}
如果文法 G GG 和 G ′ G'G
′
有 L ( G ) = L ( G ′ ) L(G) = L(G')L(G)=L(G
′
) ,則稱這兩個文法等價。設 w = x u y w=xuyw=xuy 為一句型,稱 u uu 為一個相對於 U ∈ V n U \in V_nU∈V
n
的
w ww 的短語 如果 Z ⇒ ∗ x U y ∧ U ⇒ + u Z \mathop\Rightarrow\limits^* xUy \land U \mathop\Rightarrow\limits^+ uZ
⇒
∗
xUy∧U
⇒
+
u
w ww 的簡單短語 如果 u uu 是短語且 U ⇒ u U \mathop\Rightarrow\limits uU⇒u
句型的最左簡單短語稱為句柄。
二義性
文法 G GG 是二義性的,如果 ∃ x ∈ L ( G ) \exist x \in L(G)∃x∈L(G) 使下列條件之一成立
x xx 可以對應兩顆不同的語法樹
x xx 有兩個不同的規范推導