第一步:寫出規范推導(最右)序列
規范推導就是最右推導。我們的目標是從起始符號 E
出發,通過每步替換最右邊的非終結符,最終得到句型 R(P+i)
。
文法 G[E]:
E ::= RP | P
P ::= (E) | i
R ::= RP+ | RP* | P+ | P*
推導過程:
-
E => RP
- 我們選擇
E → RP
開始,因為目標句型以R
開頭。現在句型是RP
,最右非終結符是P
。
- 我們選擇
-
=> R(E)
- 目標句型
R(P+i)
包含括號()
。唯一能產生括號的規則是P → (E)
。我們用它替換最右的P
。現在句型是R(E)
,最右(也是唯一)的非終結符是E
。
- 目標句型
-
=> R(RP)
- 現在需要推導括號里的內容
P+i
。它由兩部分組成。我們先用E → RP
展開。現在句型是R(RP)
,最右非終結符是P
。
- 現在需要推導括號里的內容
-
=> R(Ri)
- 為了得到
P+i
的i
部分,我們用規則P → i
替換最右的P
。現在句型是R(Ri)
,最右非終-結符是R
。
- 為了得到
-
=> R(P+i)
- 最后,為了得到
P+
部分,我們用規則R → P+
替換最右的R
。推導完成。
- 最后,為了得到
規范推導序列為:
E => RP => R(E) => R(RP) => R(Ri) => R(P+i)
第二步:快速查找短語、簡單短語和句柄 (核心技巧)
方法:利用語法樹結構。
根據上面的推導過程,我們可以畫出這個句型對應的語法樹:
E/ \R P/|\( E )/ \R P/ \ |P + i
現在,我們可以用這棵樹來快速找出所有答案:
1. 找出所有短語
規則:語法樹中,任何一個以非終結符為根的子樹,其所有葉子節點從左到右組成的字符串,都是一個短語。
我們從下往上、從小到大找所有子樹:
- 以最下面的
P
為根的子樹,葉子是i
。 短語是i
。 - 以
R
為根的子樹,葉子是P
和+
。 短語是P+
。 - 以括號內的
E
為根的子樹,葉子是P
,+
,i
。 短語是P+i
。 - 以最右邊的
P
為根的子樹,葉子是(
,P
,+
,i
,)
。 短語是(P+i)
。 - 以最頂層的
E
為根的子樹(整棵樹),葉子是R
,(
,P
,+
,i
,)
。 短語是R(P+i)
。
所有短語列表: i
, P+
, P+i
, (P+i)
, R(P+i)
2. 找出所有簡單短語
規則:簡單短語是一個直接由某條產生式一步推導而來的短語。在語法樹上,任何一個以非終結符為根的子樹,并且葉子節點和當前非終結符為父子關系(一步得來的),其所有葉子節點從左到右組成的字符串,都是一個短語。
我們檢查剛才找出的短語:
i
: 是由P → i
一步得來的嗎?是的。所以i
是簡單短語。P+
: 是由R → P+
一步得來的嗎?是的。所以P+
是簡單短語。P+i
: 是由E → P+i
一步得來的嗎?不是,E
先變成RP
,經過多步才得到。所以它不是簡單短語。(P+i)
: 是由P → (P+i)
一步得來的嗎?不是,P
是先變成(E)
。所以它不是簡單短-語。R(P+i)
: 不是一步得來的。
所有簡單短語列表: i
, P+
3. 找出句柄
規則:句柄是該句型的最左邊的簡單短語。
- 看我們的句型
R(P+i)
。 - 看我們的簡單短語列表
i
,P+
。 - 從左到右掃描句型
R(P+i)
,看哪個簡單短語先出現。 - 我們先遇到的是
P+
。
句柄是: P+
最終答案總結
- 規范推導序列:
E => RP => R(E) => R(RP) => R(Ri) => R(P+i)
- 所有短語:
i
,P+
,P+i
,(P+i)
,R(P+i)
- 所有簡單短語:
i
,P+
- 句柄:
P+