在this page上,作者解释了如何确定CFG的FOLLOW集。在标题语法分析目标:关注集下,他声明:
制作关注集的步骤
约定:a,b和c表示终端或非终端。一个* 表示零个或多个终端或非终端(可能两者)。 A + 表示一个或多个... D是非终端。
- 将输入结束标记($)放入起始规则的跟随集。
- 假设我们有一个规则R→a * Db。 First(b)中的所有内容(ε除外) 添加到Follow(D)。如果First(b)包含ε,那么一切都在 跟随(R)放入跟随(D)。
- 最后,如果我们有一个规则R→a * D, 然后Follow(R)中的所有内容都放在Follow(D)中。
- 关注集 终端是空集。
醇>
到目前为止一切顺利。但是在这个项目下面的框中,我们读到:
[...]规则1的第2步(N→V = E)表示第一个(=)在跟随(V)中。
现在这是我不理解的部分。当他说First(=)处于Follow(V)时,他显然将map = to b和V映射到D(b和D来自第一个框中的解释)。但(a*)(D)(b)
与()(V)(=)E
不匹配。
我读错了,或者作者是否写了a*Db
而不是a*Dba*
?
(特别是如果你在wikipedia上读到这个:“项目I的后跟(I)[A→α•Bβ,x]是在非终结符号B之后可以出现的终端集合,其中α, β是任意符号串,x是任意超前终端。“)
答案 0 :(得分:1)
是的,他的意思是:
R → a* D b*
并且因为b*
可以是零符号,即ε,所以不需要第二规则。请记住,FIRST
是在任意符号序列上定义的。
换句话说,对于:
A → α B β
FIRST(β)
中的每个终端都位于FOLLOW(B)
和β ⇒* ε
,FOLLOW(A)
中的所有内容都在FOLLOW(B)
。这是Aho,Sethi&乌尔曼在龙书中说:
正式地,我们说
LR(1)
项[A → α·β, a]
有效是否有可行的前缀γ,如果有派生的话S ⇒* δAw ⇒ δαβw
其中γ = δα
和a
是w
或w
的第一个符号是ε而a
是$
。
(上面的⇒
标记为rm
,意思是right-most derivation
;换句话说,在每个派生步骤中,最右边的非终端被其中一个取代因此,w
只包含终端。)
换句话说,LR(1)
项目有效(可以申请),如果我们已经达到了某个点,我们已经确定A
可能是下一次减少a
可能跟随A
;在解析的当前点,我们读了α。所以如果 a
跟随β,则可以减少。我们还不知道,除非β是空序列,但我们需要记住这个事实,以防β可以导出空序列。
我希望有所帮助。现在已经很晚了,我太累了,无法再次检查。也许明天......