Parsing 如何推导语法生成中非终结符的跟随者?

Parsing 如何推导语法生成中非终结符的跟随者?,parsing,syntax,compiler-construction,grammar,production,Parsing,Syntax,Compiler Construction,Grammar,Production,以下是一组语法产品: 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

以下是一组语法产品:

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]
但我不知道怎么才能得到。那么,有人能具体说明如何做到这一点吗

要计算FOLLOW(非终端),请应用以下规则,直到FOLLOW集合中无法添加任何内容:-//取自《龙书》

  • 在FOLLOW(开始符号)中放置$,其中$是输入右结束标记
  • 如果有一个产品
    a->XBY
    ,那么第一个(Y)中除了ε之外的所有东西都在后面(B)
  • 如果有一个生产
    a->XB
    ,或一个生产
    a->XBY
    ,其中第一个(Y)包含ε,那么后面(a)中的所有内容都在后面(B)中
  • 现在按照规则,我们推导出所有非终端的FOLLOW()

    FOLLOW(S)={),$}
    因为S是开始符号,FOLLOW(S)必须包含$。生产编号第四个正文解释了为什么FOLLOW(S)中包含右括号

    遵循(B)={,$}
    ,因为B只出现在S-productions主体的末尾(而不是A-productions,后面将在讨论部分讨论)

    FOLLOW(A)={+,*,(,A,),$}
    因为A出现在body中,后面紧跟着B,因此,除了ε之外,位于第一个(B)中的所有东西都必须位于FOLLOW(A)中。然而,由于第一个(B)包含ε,并且B在初始生产中从S派生,因此,后面(S)中的所有内容也必须在后面(A)中。这解释了符号$and)

    FOLLOW(T)={+,*,(,a,),$}
    因为T出现在主体中,后面紧跟着B,因此,除ε之外的所有元素都必须在FOLLOW(T)中。然而,由于第一个(B)包含ε,并且B是S产生式主体中T之后的整个字符串,因此FOLLOW(S)中的所有内容也必须在FOLLOW(T)中。这解释了符号$and)

    讨论:-

    现在,谈到第三代产品引起的某种冲突,
    A->+S | TB |*
    ,您可能很容易用S代替TB,因为您可能会感到困惑

    根据我的说法,您应该将产品保留为:-

    S -> TB
    B -> AB | ε
    A -> +S | S | *  //substitute S for understanding FOLLOW(B) without any confusion
    T -> (S) | a
    

    这个问题是龙书的练习4.4.1 d)。但实际上我还没有得到这本书的正式答案。我能找到的唯一答案就是这里。这个答案很奇怪。“你能解释一下吗?”埃里克黄-我也认为这个答案本身就很混乱。不能肯定,但是,似乎有些错误。如果你能向你的教授核实一下,我将非常感谢你。