詞法分析
說明:以老師PPT為標准,借鑒部分教材內容,AlvinZH學習筆記。
語法分析基礎
1. 詞法分析程序的功能
- 詞法分析:根據詞法規則識別及組合單詞,進行詞法檢查;
- 對數字常數完成數字字符串到(二進制)數值的轉換;
- 刪去空格、換行、制表等字符和注釋。
2. 實現方案
- 詞法分析單獨做一遍。結構清晰,個遍功能單一,但是效率低。
- 詞法分析作為單獨的子程序,由語法分析程序調用。結構較復雜,效率高。
3. 單詞種類及輸出形式
單詞種類:保留字、標識符、常數、分界符等。
輸出形式:二元式,<單詞類別,單詞值>。按單詞種類分類,也可以將保留字和界符采用一符一類。
正則文法和狀態圖
狀態圖:用於識別(接受)一定的字符串。包含一個初始狀態(初態),至少一個終止狀態(終態)。畫法比較簡單:
注意:
- 利用狀態圖分析識別字符串——自底向上。
- 狀態圖只能用於左線性文法(形如A→Bb)。這是明顯和后面的DFA區別之處。
正則表達式
1.正則表達式運算符:|選擇、·連接、*重復、()括號。優先級:括號優先,先*后·最后|。
2.正則表達式與3型文法等價。相互轉換后續講解。
確定的有窮自動機(DFA)
1. DFA五元式定義:\(M = (S, ∑, δ, S0, Z)\)。其中 \(S\) 為有窮狀態集,\(∑\) 為輸入字母表,\(δ\) 為狀態轉換函數(S×∑ → S的映射),\(S_0\) 為初始狀態,\(Z\) 為終止狀態集。
2. 何為確定?表現在 \(δ\) 中的狀態轉換函數是單值函數。
3. DFA不可接受 \(ε\),DFA M所接受的語言為:\(L(M) = \{ α|δ(S0, α)= Sn, Sn∈Z \}\)。
非確定的有窮自動機(NFA)
1. 若 \(δ\) 是一個多值函數,且輸入允許為 \(ε\),則有窮自動機是不確定的。即對於某個輸入字符存在多個后繼狀態。
2. NFA五元式定義:\(M' = (S, Σ∪{ε}, δ, S0, Z)\)。\(δ\) 為狀態轉換函數(S×∑∪{ε} → 2^S的映射,2^S:S的冪集,即S的子集構成的集合)。
3. NFA M'所接受的語言為:\(L(M') = \{ α|δ( S0,α) = S’ S’∩Z≠Φ \}\)。
NFA的確定化——子集法
1. 已經證明:非確定的有窮自動機與確定的有窮自動機從功能上來說是等價的。這意味着,對於NFA M',可以構造出DFA M,使得L(M)=L(M')。
2. 集合 \(I\) 的 \(ε\) 閉包。\(I\) 是NFA狀態集S的一個子集,則ε-closure(I)為:
- 若s∈I,則s ∈ ε-closure(I);
- 若s∈I,則從 s 出發經過任意條ε弧能夠到達的任何狀態都屬於ε-closure(I)。
簡單理解,ε-closure(I)就是由I中所有狀態接收字符ε得到的狀態集。
3. 集合 \(I\) 對應 \(Ia\)。\(I\) 是NFA狀態集 \(S\) 的一個子集,a∈∑,則 \(I_a = ε-closure(J)\),其中 \(J = ∪ δ(S, a),S∈I\)。
簡單理解,分為兩步,第一步找到 \(I\) 中所有狀態接收字符 \(a\) 得到的狀態集 \(J\),再求 \(ε-closure(J)\)。
4. 確定化方法,過程如下。建議結合教材例子,實際求解過程畫表格更清晰。
①求初始狀態:S0 = ε-closure(S0');
②for 每個狀態
for 每個x∈∑
計算新狀態Ix;
注:過程②出現的新狀態也在循環中,直到不出現新狀態為止;
包含NFA M'原初態的狀態集為DFA M的初態;包含NFA M'原終態的狀態集為DFA M的終態。
5.簡單例子
DFA的最小化——分割法
1. 狀態s和狀態t等價條件:
- 一致性條件:狀態s和t必須同時為接受狀態或不接受狀態。
- 蔓延性條件:對於所有輸入符號,狀態s和t必須轉換到等價的狀態里。
2. 最小化方法:分割法。思路:把DFA所有狀態分割成不相關的子集,使得任意兩個子集狀態是可區分的,而同一子集中狀態是等價的。具體操作如下:
①區分終態和非終態,為區號1,2;(一致性條件)
②每個原狀態,對於每個輸入,對應后繼狀態的區號,全部相同的視為等價(暫時);(蔓延性條件)
③由於過程②划分出新的區間,對應的區號有所改變,重復過程②直至沒有新區間出現。
正則文法、正則表達式、NFA(DFA)相互轉換
1. 有窮自動機M => 正則文法G
①對轉換函數f(A, t) = B,可寫成一個產生式:A→tB,其中t∈Vt,A、B∈Vn
②對可接受狀態Z,增加一個產生式:Z→ε
③有窮自動機的初態對應於文法的開始符號,有窮自動機的字母表 ∑ 為文法的終結符號集Vt。
【例】
注意: 不知你注意到了沒有,有窮自動機M轉換出來的文法規則都是右線性的,這就體現了有窮自動機自頂向下的特點,在語法分析LR分析法中會用到這一特性。
2. 正則文法G=>有窮自動機M
【算法】
① M的字母表 ∑ 與G的終結符號 Vt 相同
②為G中的每個非終結符Vn生成M的一個新狀態,G的開始符號S作為M的開始狀態S
③增加一個新狀態Z,作為NFA的終態
④對G中產生式形如A→tB,其中t為終結符或ε,A和B為非終結符,構造M的一個轉換函數f(A, t) = B
⑤對G中的形如A→t的產生式,構造M的一個轉換函數f(A, t) = Z
【例】
3. 正則表達式 => 有窮自動機M
【算法】
【例】
4. 有窮自動機M => 正則表達式
【算法】
【例】
5. 正則文法轉正則表達式
【算法】
- 代入規則:對於A→xB,B→y,轉換為A→xy;
- 消除遞歸規則:對於A→xA|y,轉換為A→x*y;
- BNF規則:對於A→x,A→y,轉換為A→x|y。
6. 正則表達式轉正則文法
【算法】
- 對任何正則式r,選擇一個非終結符S作為識別符號,並產生產生式 S→r;
- 若x、y是正則式,對形為A→xy的產生式,重寫為A→xB和B→y,其中B為新的非終結符,B∈Vn。同樣,對於 A→x*y,重寫為A→xA,A→y;對於A→x|y,重寫為 A→x,A→y。
【例】將S = a ( a | d )* 轉換成相應的正則文法
解: 1) S→a(a|d)*
-
S→aA
A→(a|d)* -
S→aA
A→(a|d)A
A→ε -
S→aA
A→aA|dA
A→ε
LEX擴展知識點
1. 一個LEX源程序主要由三個部分組成:規則定義式、識別規則、用戶子程序。各部分之間用%%隔開。實質是是一個有窮自動機。
- 規則定義式:形如D1→R1,其中D1為正則表達式名字(簡名),R1為正則表達式。如digit →0|1|……|9。
- 識別規則:形如P1 {A1},其中P1為詞形,為在Σ∪{D1,D2,¨¨Dn}上的正則表達式;A1為語句序列,指出在識別出詞形為Pi的單詞以后,詞法分析器所應作的動作。其基本動作是返回單詞的類別編碼和單詞值。如digit(digit)* {RETURN(9,DTB }。
.2. 二義性處理原則:最長匹配原則;最優匹配原則。
引用說明
- 邵老師課堂PDF
- 《編譯原理級編譯程序構造》