以下是一组语法制作:
S -> SA | T
A -> +S | S | *
T -> (S) | a
当消除左递归时,我得到了这些:
S -> TB
B -> AB | ε
A -> +S | TB | *
T -> (S) | a
然后我尝试按照龙书所描述的步骤获取其中非终端的第一和第二。我已经正确地获得了第一次:
first(T) = [(, a]
first(A) = [+, *, (, a]
first(B) = [ε, +, *, (, a]
first(S) = [(, a]
但是我无法弄清楚如何得到Follows。那么任何一个人都能说明具体如何做到这一点吗?
答案 0 :(得分:1)
要计算 FOLLOW(Non-Terminal)
,请应用以下规则,直到无法将任何内容添加到FOLLOW集: - //取自Dragon Book
A->XBY
,那么FIRST(Y)中除ε以外的所有内容都在FOLLOW(B)中。A->XB
或生产A->XBY
,其中FIRST(Y)包含ε,那么FOLLOW(A)中的所有内容都在FOLLOW(B)中。所以,现在按照规则,我们在这里推导出所有非终端的FOLLOW()。
FOLLOW(S) = {),$}
由于S是起始符号,因此FOLLOW(S)必须包含$。生产编号第4个正文(S)解释为什么右括号在FOLLOW(S)。
FOLLOW(B) = {),$}
由于B只出现在S-productions主体的末端(而不是A-productions,后面将在讨论部分讨论)。< / p>
FOLLOW(A) = {+,*,(,a,),$}
由于A出现在主体后面只有B,因此除FIRST(B)中的ε之外的所有内容都必须在FOLLOW中(A )。但是,由于FIRST(B)包含ε,而B在初始生产中来自S,因此,FOLLOW(S)中的所有内容也必须在FOLLOW(A)中。这解释了符号$和。
FOLLOW(T) = {+,*,(,a,),$}
由于T出现在主体后面只有B,因此除FIRST(B)中的ε之外的所有内容都必须在FOLLOW中(T )。但是,由于FIRST(B)包含ε,而B是S产生体中T之后的整个字符串,因此FOLLOW(S)中的所有内容也必须在FOLLOW(T)中。这解释了符号$和)。
讨论: -
现在,谈论由于第3次制作引起的某种冲突, A -> +S | TB | *
,你可以很容易地用S代替TB,因为你可能会感到困惑。
按照我的说法,你应该将作品保留为: -
S -> TB
B -> AB | ε
A -> +S | S | * //substitute S for understanding FOLLOW(B) without any confusion
T -> (S) | a