【编译原理】大白话讲解 First 集和 Follow 集的构造算法

First集构造流程


 

  对于 X -> ... 这条产生式而言,

    【1】若右边第一个符号是终结符或 ε  ,则直接将其加入 First(X)

    【2】若右边第一个符号是非终结符,则将其 First 集的的非 ε  元素加入 First(X)

    【3】若右边第一个符号是非终结符而且紧随其后的是很多个非终结符,这个时候就要注意是否有 ε 

      【3.1】若第 i 个非终结符的 First 集有 ε  ,则可将第 i+1 个非终结符去除 ε  的 First 集加入 First(X)。

      【3.2】若所有的非终结符都能够推导出 ε ,则将  ε  也加入到 First(X)

 

    E.G. G[S]:

      S -> ABCD

      A -> a |  ε  

      B -> b |  ε  

      C -> c

      D -> d

      解:

        First(S) = {a, b, c},其中 c 是由上面所说的第二、三条规则所推得出来的,因为此时 A 和 B 都可以等于空串( ε  ),所以非终结符 C 的 first 集合就被加入 G[S] 了。

        如果这里 C,D 也能够产生 ε  的话,根据第三条规则中的第二小点,此时 First(S) = {a, b, c, d,  ε}

 

 

Follow集构造流程


 

  【1】将所有产生式的候选式(即产生式右部)的非终结符都找到,定位到你想要求解 Follow 集的非终结符的位置,从当前位置往后挨个检查。设 A -> aBC 是一个产生式,在这个产生式中, B 和 C 是非终结符,a 是终结符

  【2】先检验这个非终结符的右边还有没有别的符号(终结符或非终结符都可以),在例子中 B 是需要检查的第一个非终结符,它的右边是有非终结符 C 的。

    【2.1】若右边有符号 -> 将 First(右侧第一个符号)的非 ε 集合加入到 Follow(当前符号)中,如果 First(右侧第一个符号)含有 ε  ,即有 ... -> ε ,则将 Follow(产生式左部符号)加入 Follow(当前符号)中。

     E.G.  用 A -> aBC 来说就是,当前扫描到 B 了,而 B 的右侧有非终结符 C,则将去掉 ε  的 First(C)加入 Follow(B)中。若存在 C -> ε  ,则将 Follow(A)也加入 Follow(B)中。

    【2.2】若右边没有符号了,例如这里的 C,那么可以将 Follow(A)中的元素全部加入到 Follow(C)中。

  【3】判断当前符号是不是文法的开始符号,比如 G[A] 中的非终结符 A 就是 G[A] 文法的开始符号,如果是的话就将“#”也加入到 Follow(当前符号)中去。

 

 

预测表的构造


 

  首先构造出预测分析表的第一行与第一列,第一行为文法出现的所有终结符以及‘#’(注意:没有 ε ,因为 Follow 集不含 ε),第一列为文法出现的所有终结符。

  然后对文法 G 的每个产生式 A -> ab 都执行如下操作:

    【1】对于每个属于 First(ab) 的终结符 m ,都把 A -> ab 添加到预测表中的 [A, m] 中去

    【2】如果 ε 也属于 First(ab),那么对于任何属于 Follow(A) 的字符 x,都把 A ->  ε  加入到 [A, x] 中去

 

转载于:https://www.cnblogs.com/Bw98blogs/p/10028271.html

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目:FirstFollow生成算法模拟 【问题描述】 设计一个由正规文法生成FirstFollow并进行简化的算法动态模拟。(算法参见教材) 【基本要求】 动态模拟算法的基本功能是: (1) 输入一个文法G; (2) 输出由文法G构造FIRST算法; (3) 输出First; (4) 输出由文法G构造FOLLOW算法; (5) 输出FOLLOW。 【测试数据】 输入文法: E->TE’ E’->+TE’|ε T->FT’ T’->*FT’|εF->(E)|i 【实现提示】 用数据库存储多行文法,用LIST控件显示算法,用GRID类依据算法进行作图。并实现算法与生成过程的关联。 三、设计思路 该分析器主要包括三大部分:求FIRST,求FOLLOW,求SELECT。下面主要介绍计算FIRSTFOLLOW算法思想。 求FIRST算法思想:主要有三个函数 First(), First_getvn(), First_getvt。函数 First()调用First_getvn(),First_getvn()调用First_getvt 这里主要把产生式分成的两种: 一:产生式只能推出空,形如:S->$;此时S的FIRST为{$} 二:产生式右部包含非终结符和终结符,形如:S->aA, S->AB. 这里定义了两个比较重要字符串,分别是first 即FIRST;另一个是first_vn,把它定义非终结符的FIRST。当产生式右边的第一个字符为非终结符时,把该VN加入 srt first_vn中,后再调用函数first_getvt求出FIRST。若产生式右边的第一个字符为终结符时,则直接把该VT加入str first,得到FISRT。 流程图: 略

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值