如何求First集与Follow集(超详细)

如何求First集与Follow集

已知文法如下,求First集与Follow集
G [ E ] : E → T E ′ E ′ → + T E ′ ∣ ε T → F T ′ T ′ → ∗ F T ′ ∣ ε F → ( E ) ∣ i G[E]: E{\rightarrow} TE' \\ {\quad\quad\quad\quad\quad}E'{\rightarrow}+TE'|\varepsilon \\ {\quad\quad\quad}T{\rightarrow}FT'\\ {\quad\quad\quad\quad\quad}T'{\rightarrow}*FT'|\varepsilon\\ {\quad\quad\quad}F{\rightarrow}(E)|i\\ G[E]:ETEE+TEεTFTTFTεF(E)i

First集:

  1. 第一次查看所有式子

  2. 首先看第一个式子: E → T E ′ E{\rightarrow} TE' ETE,候选式中未包含终结符,暂时无法得出结果

    当前First集:

    First(E) = { }
    First(E ′ ' ) = { }
    First(T) = { }
    First(T ′ ' ) = { }
    First(F) = { }

  3. 第二个式子: E ′ → + T E ′ ∣ ε E'{\rightarrow}+TE'|\varepsilon E+TEε,可以得到其所有候选式的串首终结符: +、 ε {\varepsilon} ε,将其加入到First(E ′ ' )中

    当前First集:

    First(E) = { }
    First(E ′ ' ) = {+, ε {\varepsilon} ε}
    First(T) = { }
    First(T ′ ' ) = { }
    First(F) = { }

  4. 第三个式子同 1,First集无变化

  5. 第四个式子同 2,将 *、 ε {\varepsilon} ε加入到First(T ′ ' )中

    当前First集:

    First(E) = { }
    First(E ′ ' ) = {+, ε {\varepsilon} ε}
    First(T) = { }
    First(T ′ ' ) = { *, ε {\varepsilon} ε}
    First(F) = { }

  6. 第五个式子: F → ( E ) ∣ i F{\rightarrow}(E)|i F(E)i,将 (、i 加入到First(F)中

    当前First集:

    First(E) = { }
    First(E ′ ' ) = {+, ε {\varepsilon} ε}
    First(T) = { }
    First(T ′ ' ) = { *, ε {\varepsilon} ε}
    First(F) = { (,i}

  7. 第二次查看所有式子

  8. 第一个式子可得,First(T) 是First(E) ,但First(T)是空的,故无变化

    [注:参照书本58页第三行②,若有 X → Y X{\rightarrow}Y XY, Y Y Y是非终结符,就把First(Y)中非 ε {\varepsilon} ε元素加入到First(X)中]

  9. 第二个式子不能得到新的结果,下一步

  10. 第三个式子可得,First(F)是First(T),故将 ( ,i 加入到First(T)
    当前First集:

    First(E) = { }
    First(E ′ ' ) = {+, ε {\varepsilon} ε}
    First(T) = { (,i }
    First(T ′ ' ) = { *, ε {\varepsilon} ε}
    First(F) = { (,i }

  11. 后续式子均不能得到新的结果,下一步

  12. 第三次查看所有式子

  13. 第一个式子得,First(T) 是First(E),故First集产生变化

    当前First集:

    First(E) = {(,i }
    First(E ′ ' ) = {+, ε {\varepsilon} ε}
    First(T) = { (,i }
    First(T ′ ' ) = { *, ε {\varepsilon} ε}
    First(F) = { (,i }

  14. 后续式子均无法得到新的结果,求First集完毕

  15. 注:理论上每次First集产生变化就要重新查看一遍所有式子,这里为了方便进行了简写,实际做题时可以按照变化一次重新求一次

Follow集:

求Follow集是在已经求出First集的基础上进行

  1. 将#置入Follow(文法开始符号),即Follow(E)

    当前Follow集:

    Follow(E) = { # }
    Follow(E ′ ' ) = { }
    Follow(T) = { }
    Follow(T ′ ' ) = { }
    Follow(F) = { }

  2. 第一次查看所有式子

  3. E → T E ′ E{\rightarrow} TE' ETE可得

    • Follow(E)可以加入到Follow(E ′ ' ),将 # 置入Follow(E ′ ' )

    • Follow(E)可以加入到Follow(T),将 # 置入Follow(T)

      [注:因为E ′ ' 可能为 ε {\varepsilon} ε],

    • First(E ′ ' )中非 ε {\varepsilon} ε元素可以加入到Follow(T)中,将 + 置入Follow(T)

      当前Follow集:

      Follow(E) = { # }
      Follow(E ′ ' ) = { # }
      Follow(T) = { #,+ }
      Follow(T ′ ' ) = { }
      Follow(F) = { }

  4. E ′ → + T E ′ ∣ ε E'{\rightarrow}+TE'|\varepsilon E+TEε 可得

    • Follow(E ′ ' )可以加入到Follow(T),无变化
  5. T → F T ′ T{\rightarrow}FT' TFT可得

    • Follow(T)可以加入到Follow(T ′ ' ),将 #、+ 置入Follow(T ′ ' )

    • Follow(T)可以加入到Follow(F),将 #、+ 置入Follow(F)

    • First(T ′ ' )中非 ε {\varepsilon} ε元素可以加入到Follow(F)中,将 * 置入Follow(F)

      当前Follow集:

      Follow(E) = { # }
      Follow(E ′ ' ) = { # }
      Follow(T) = { #,+ }
      Follow(T ′ ' ) = { #,+ }
      Follow(F) = {#,+ ,* }

  6. T ′ → ∗ F T ′ ∣ ε T'{\rightarrow}*FT'|\varepsilon TFTε 可得

  • Follow(T ′ ' )可以加入到Follow(F),无变化
  1. F → ( E ) ∣ i F{\rightarrow}(E)|i F(E)i 可得

    • 非终结符E后有一个终结符 ),故将 ) 置入Follow(E)

      当前Follow集:

      Follow(E) = { #,) }
      Follow(E ′ ' ) = { # }
      Follow(T) = { #,+ }
      Follow(T ′ ' ) = { #,+ }
      Follow(F) = {#,+ ,* }

  2. 第二次查看所有式子

  3. E → T E ′ E{\rightarrow} TE' ETE可得

    • Follow(E)可以加入到Follow(E ′ ' ),将 ) 置入Follow(E ′ ' )

    • Follow(E)可以加入到Follow(T),将 ) 置入Follow(T)

    • First(E ′ ' )中非 ε {\varepsilon} ε元素可以加入到Follow(T)中,已有+,Follow(T)无变化

      当前Follow集:

      Follow(E) = { #,) }
      Follow(E ′ ' ) = { # ,) }
      Follow(T) = { #,+ ,) }
      Follow(T ′ ' ) = { #,+ }
      Follow(F) = {#,+ ,* }

  4. E ′ → + T E ′ ∣ ε E'{\rightarrow}+TE'|\varepsilon E+TEε 可得

  • Follow(E ′ ' )可以加入到Follow(T),无变化
  1. T → F T ′ T{\rightarrow}FT' TFT可以得到
  • Follow(T)可以加入到Follow(T ′ ' ),将 ) 置入Follow(T ′ ' )

  • Follow(T)可以加入到Follow(F),将 )置入Follow(F)

  • First(T ′ ' )中非 ε {\varepsilon} ε元素可以加入到Follow(F)中,已有*,Follow(F)无变化

    当前Follow集:

    Follow(E) = { #,) }
    Follow(E ′ ' ) = { # ,) }
    Follow(T) = { #,+ ,) }
    Follow(T ′ ' ) = { #,+,) }
    Follow(F) = {#,+ ,*,) }

  1. T ′ → ∗ F T ′ ∣ ε T'{\rightarrow}*FT'|\varepsilon TFTε 可得
  • Follow(T ′ ' )可以加入到Follow(F),无变化
  1. F → ( E ) ∣ i F{\rightarrow}(E)|i F(E)i 并不能得到新的结果
  2. 再次查看所有式子,均不能产生新的变化,求Follow集完毕
  3. 注:理论上每次Follow集产生变化就要重新查看一遍所有式子,这里为了方便进行了简写,实际做题时可以按照变化一次重新求一次

那么在已知First集和Follow集的情况下如何构造LL1分析表呢

First集与Follow集:

First(E) = {(,i }
First(E ′ ' ) = {+, ε {\varepsilon} ε}
First(T) = { (,i }
First(T ′ ' ) = { *, ε {\varepsilon} ε}
First(F) = { (,i }

Follow(E) = { #,) }
Follow(E ′ ' ) = { # ,) }
Follow(T) = { #,+ ,) }
Follow(T ′ ' ) = { #,+,) }
Follow(F) = {#,+ ,*,) }

LL1分析表:

第一列为非终结符,第一行为终结符

i+*(#
EE遇到 i,i ϵ { \epsilon} ϵ First(E),且E只有一个候选式,填入 E → T E ′ E{\rightarrow} TE' ETEE遇到(,( ϵ { \epsilon} ϵ First(E),且E只有一个候选式,填入 E → T E ′ E{\rightarrow} TE' ETE
E’+ ϵ { \epsilon} ϵ First(E ′ ' ),在E’的候选式中选择+开头的, 填入 E ′ → + T E ′ E'{\rightarrow}+TE' E+TEFirst(E ′ ' )中含有 ε {\varepsilon} ε,故E’遇到Follow(E ′ ' )中的终结符时均填入 E ′ → ε E'{\rightarrow} {\varepsilon} Eε E ′ → ε E'{\rightarrow} {\varepsilon} Eε
T T → F T ′ T{\rightarrow}FT' TFT T → F T ′ T{\rightarrow}FT' TFT
T’ T ′ → ε T'{\rightarrow} {\varepsilon} Tε T ′ → ∗ F T ′ T'{\rightarrow}*FT' TFT T ′ → ε T'{\rightarrow} {\varepsilon} Tε T ′ → ε T'{\rightarrow} {\varepsilon} Tε
F F → i F{\rightarrow}i Fi F → ( E ) F{\rightarrow}(E) F(E)

注:大写字母表示非终结符,小写字母与符号表示终结符

总结:

  1. 当非终结符遇到其First集中的终结符时填入相应候选式
  2. 当非终结符的First集中含有 ε {\varepsilon} ε 元素时,遇到其Follow集中的终结符时填入 非终结符 → ε {\rightarrow} {\varepsilon} ε

如有错误欢迎指正

  • 334
    点赞
  • 1333
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论
### 回答1: FirstFollow是语法分析中的概念,是用于判断一个文法是否为LL(1)文法的重要工具。 First是指一个非终结符号能推导出的所有符号的首字母集合Follow是指在文法中,在一个非终结符号之后的符号集合。 对于C语言来说,要计算FirstFollow,需要对C语言的语法进行分析,计算每一个非终结符号的FirstFollow。 ### 回答2: First是指一个文法中每个非终结符对应的产生式右侧的第一个符号的集合。在C语言中,可以通过以下步骤出每个非终结符的First集合: 1. 如果一个非终结符的产生式右侧第一个符号是终结符,则该终结符就是该非终结符的First集合中的元素。 2. 如果一个非终结符的产生式右侧第一个符号是另一个非终结符,则将该非终结符的First集合中的元素添加到当前非终结符的First集合中。 3. 如果一个非终结符的产生式右侧第一个符号可以推导出空串,则需要考虑后面的符号。如果后面的符号是终结符,则将该终结符加入该非终结符的First集合中;如果后面的符号是非终结符,则将该非终结符的First集合中去掉空串的元素添加到当前非终结符的First集合中。 Follow是指文法中每个非终结符在任意一个派生式中“后面”可能出现的终结符的集合。在C语言中,可以通过以下步骤出每个非终结符的Follow集合: 1. 对于文法起始符号S,将“$”加入S的Follow中。 2. 对于每一个非终结符A,遍历文法中每个产生式,将“后面”可能出现在A之后的符号(包括终结符和非终结符)的First集合中除去空串的元素加入A的Follow中。 3. 如果一个非终结符B可以推导出空串,即存在一个产生式右侧只包含空串的产生式,那么将B的Follow加入至B所在产生式左侧非终结符的Follow中。 通过解First和Follow集合,可以完成C语言语法分析的相关操作。 ### 回答3: 首先,需要先了解什么是firstfollow。 first:给定一个文法的某个非终结符,它所有能够推导出来的字符串中的第一个终结符集合,即每个产生式右边的终结符或空串的集合follow:给定一个文法的某个非终结符,所有可能出现在它后面的终结符集合,即考虑这个非终结符在右侧是否还有其他非终结符或者是这个非终结符后面是否还能够推导出来空串。 接下来,我们以以下的C语言的产生式为例,来看如何解firstfollow。 S → F; S → if(E)S; S → if(E)S else S; F → id=E; F → ε; E → EEQ E → int E → id 首先,我们来解S的first: - S → F;,F是一个非终结符,在F的first中,包含了终结符id和空串ε,然后将继续对;进行计算。 - S → if(E)S;,if是终结符,而E的first中包含int和id,所以if的first中也包含int和id。然后继续对(E)S进行计算,(和E相同,仅包含int和id,)的first包含int和id,S的first是它的first和else的first之和,由于S可以推导出空串,所以在这里也会包含空串ε。 - S → if(E)S else S;,if的first中包含int和id,E计算出来也是int和id,)\E的first是int和id,S的first是它的第一个产生式的F的first和else的first之和。 - F → id=E;,id的first是它本身,而E的first中包含int和id,=的first是它本身,F的first为id。 - F → ε,F的first是空集合。 然后,我们来解S的follow: - S → F;,S的follow包含文法中结束符$。 - S → if(E)S,假设A是它的follow,则E的follow是A,S的follow是它后面的一个终结符else的first和A的并。由于S可以推导出空串,所以还需要加上它的前面的非终结符的follow,即F的follow。所以这里S的follow即为else和$。 - S → if(E)S else S,同上,A是它的follow,则E的follow为else和A的并,第一个S的follow即为A,第二个S的follow则是它后面的终结符$。 - F → id=E;,同上,E的follow即为;的first,F的follow即为S的follow。 - F → ε,F的follow即为S的follow。 接下来,我们来解E的firstfollow: - E → EEQ,E的first为int和id。 - E → int,E的first为int。 - E → id,E的first为id。 - E的follow即为它后面的终结符}和else的first。由于E在这个文法中出现的时候都是在if语句中,所以也需要加上if的follow,即else和$。 最后,我们来解if的firstfollow: - if的first为if。 - if的follow为else和$。 综上所述,我们可以通过算法,计算出文法中每个非终结符的firstfollow,这可以被用于语法分析、错误检查、文法的优化等方面。
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RENSRM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值