
第一步:写出规范推导(最右)序列
规范推导就是最右推导。我们的目标是从起始符号 E 出发,通过每步替换最右边的非终结符,最终得到句型 R(P+i)。
文法 G[E]:
E ::= RP | PP ::= (E) | iR ::= 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+