自底向上分析之算符優先分析法
說明:以老師PPT為標准,借鑒部分教材內容,AlvinZH學習筆記。
基本過程
1. 一般方法:采用自左向右地掃描和分析輸入串,從輸入符號串開始,通過反復查找當前句型的句柄(最左簡單短語),並利用有關規則進行規約。
分析過程如下,關鍵步驟是第一點!
- 找出當前句型的句柄 x (或句柄的變形);
- 找出以 x 為右部的規則 X::= x ;
- 把 x 規約為X,產生語法樹的一枝。
2. 自底向上分析也叫作移進-規約分析,簡單的例子中,識別句柄的過程,主要看棧頂符號串是否形成規則的右部。這種做法形式上正確,但實際上不一定正確。原因:不能認為對於句型xuy,若有U::=u,就斷定u是簡單短語或者u是句柄,也就是說這是一個必要不充分條件。
算符優先分析(OPP)
1. OPP:簡單直觀,廣為使用的自底向上分析方法,易手工實現。可用於一大類上下文無關文法。
分析器的結構:符號棧、優先關系矩陣、分析程序。
2. 特點:預先規定相鄰終結符之間的優先關系,利用優先關系確定句型的“句柄”並進行規約。
注意:
- 這里的“句柄”有可能不是真正的句柄,這種規約也未必是嚴格的最左規約。(后續解釋)
- 對於二義性文法,如 \(E ::= E+E | E-E | E*E | E/E | (E) | i\),可以通過定義優先關系和左結合原則,OPP可分析之。
3. 終結符之間優先關系定義
- a = b:a的優先級等於b
- a < b:a的優先級小於b
- a > b:a的優先級大於b
注意: 這個關系是單方面的,也就是說這里的 “a<b” 並不意味着 “b>a”,同樣的,“a=b” 也不意味着 “b=a”。
4. 優先關系舉矩陣:左終結符(棧內)、右終結符(棧外),值為優先關系,空表示兩個終結符不能相鄰。
使用方法:當棧頂項(或次棧頂項) 終結符的優先級大於棧外的終結符的優先級則進行規約,否則移進。
出錯情況:
- 相鄰終結符之間無優先關系。
- 對雙目運算符進行規約時,符號棧中無足夠項。
- 非正常結束狀態。
5. 優先函數:文法終結符之間的優先關系可以不用矩陣表示,而是采用兩個郵箱函數來表示:f(x)表示棧內優先函數,g(x)表示棧外優先函數。把優先關系的比較轉換成數值的比較。
特點:優先函數值不唯一,只要相互之間數值大小表示優先關系就行。
優點:節省內存空間,易於比較(數值比較)
缺點:可能掩蓋錯誤,由於優先關系變為數值,原先可能不存在的優先關系現在也可比較了。可以通過特判避免這個問題。
OG與OPG定義
1. 算符文法(OG):若文法G中沒有形如 \(U ::= ···VW···\) 的規則(V,W∈Vn),則稱G為算符文法。
直觀理解:算符文法不允許兩個非終結符相鄰!
2. 優先關系定義:設嗡文法G是一個OG文法,a,b∈Vt,U,V,W∈Vn。
-
a = b: iff 文法中有形如 \(U∷=…ab…\) 或 \(U∷=…aVb…\) 的規則。
-
a < b: iff 文法中有形如 \(U∷=…aW…\) 的規則,其中 \(W =+> b…\) 或 \(W =+> Vb…\)。
-
a > b: iff 文法中有形如 \(U∷=…Wb…\) 的規則,其中 \(W =+> …a\) 或 \(W =+>…aV\)。
TIP:只是定義,第二第三條實際用起來真的難用,還是繼續看下去,用FIRSTVT和LASTVT高級操作吧!
3. 算符優先文法(OPG):設有一OG文法,如果在任意兩個終結符之間,至多只有上述關系中的一種,則稱該文法為算符優先文法(OPG)。
構造優先關系矩陣
1. 通過檢查每一條規則,'=' 優先關系很容易求得,但是 '>' 和 '<' 就復雜了,需要引入兩個集合輔助:FIRSTVT、LASTVT。
FIRSTVT( U ) = { b | U =+> b…或U =+> Vb…, b∈Vt , V∈Vn}
LASTVT( U ) = { a | U =+> …a 或U =+> …aV, a∈Vt , V∈Vn}
若文法有規則形如 \(W∷= ...a U...\),對任何 b∈FIRSTVT( U ),則有: a < b。
若文法有規則形如 \(W∷= ...U b...\),對任何 a∈LASTVT( U ),則有: a > b。
2.構造FIRSTVT集合
- 若有規則 U∷= b… 或 U∷= V b…,則 b∈FIRSTVT(U);
- 若有規則 U∷= V… 且 b∈FIRSTVT(V), 則 b∈FIRSTVT(U)。
3.構造LASTVT集合
- 若有規則 U::=…a 或 U::=…aV,則 a∈LASTVT(U);
- 若有規則 U::=…V,且 a∈LASTVT(V) ,則 a∈LASTVT(U)。
4.構造算符優先矩陣
FOR 每條規則U::= x1 x2…xn DO
FOR i:=1 TO n-1 DO
BEGIN
IF xi和xi+1均為終結符, THEN 置 xi=xi+1
IF i≤n-2,且xi和xi+2都為終結符號但xi+1為非終結符號 THEN 置 xi=xi+2
IF xi為終結符號xi+1為非終結符號 THEN
FOR FIRSTVT(xi+1)中的每個b DO 置xi<b
IF xi為非終結符號xi+1為終結符號 THEN
FOR LASTVT(xi)中的每個a DO 置a>xi+1
END
5. 舉個例子
分析句子 \(i*(i+i)\)。
分析算符優先分析法
1. 提出問題:這種分析算法並不是嚴格的最左規約,也就是說,每次規約的未必是當前句型的句柄。那它規約的是什么?
答案:最左素短語。
先給出分析過程的特點(不予證明):
- 每次規約的最左子串,確實是當前句型的最左素短語;
- 規約的不都是真正的句柄(有時候是只是偶然);
- 沒有完全按規則進行規約,因為素短語不一定是簡單短語(有時候是只是偶然)
2. 素短語:句型的素短語是一個短語,它至少包含有一個終結符號,並且除它自身以外不再包含其它素短語。
例如:對於句型T+TF+i,通過語法樹可以輕易找到所有短語:① T + T * F + i;② T + T * F;③ T;④ T * F;⑤ i。①包含其它短語②包含其它短語③不包含終結符④是素短語⑤是素短語。最后最左素短語就是④TF。然而該句型的句柄確實③T。
3. 形式化尋找最左素短語:設有OPG文法句型:#N1 a1 N2 a2…Nn an Nn+1 #,其中Ni為非終結符(可以為空),ai為終結符。
定理:一個OPG句型的最左素短語是滿足下列條件的最左子串:Nj aj … Ni ai Ni+1,其中aj-1 < aj ,aj = a . . . . j+1 , aj+1 = aj+2 , … , ai-2 = ai-1 , ai-1 = ai, ai.> ai+1。
4. 實現算符優先分析法:找句型的最左子串(最左素短語)並進行規約。
具體實現:當棧內終結符的優先級<或=棧外終結符的優先級時,移進;當棧內終結符的優先級>棧外終結符的優先級時,表明找到了素短語的尾,再往前找其頭,並進行規約。
引用說明
- 邵老師課堂PDF
- 《編譯原理級編譯程序構造》