FIRST集合

定义

可从α推导得到的串的首符号的集合,其中α是任意的文法符号串。

规则

计算文法符号 X 的 FIRST(X),不断运用以下规则直到没有新终结符号或 ε可以被加入为止 :

(1)如果 X 是一个终结符号,那么 FIRST(X) = X。

(2)如果 X 是一个非终结符号,且 X ->Y1 Y2 … Yk是一个产生式,其中 k≥1,那么如果对于某个i,a在 FIRST(Y1)、FIRST(Y2)… FIRST(Yi-1)中,就把a加入到 FIRST(X) 中。

(3)如果 X ->ε是一个产生式,那么将ε加入到 FIRST(X)中。


以上是书上的官方规则,不仅读起来很拗口,理解也很累。

下面看一下精简版的规则(从别人 @樱草书 那里看来的,感觉很棒,这里引用一下):

(1)如果X是终结符,则FIRST(X) = { X } 。

(2)如果X是非终结符,且有产生式形如X → a…,则FIRST( X ) = { a }。

(3) 如果X是非终结符,且有产生式形如X → ABCdEF…(A、B、C均属于非终结符且包含 ε,d为终结符),需要把FIRST( A )、FIRST( B )、FIRST( C )、FIRST( d )加入到 FIRST( X ) 中。

(4)如果X经过一步或多步推导出空字符ε,将ε加入FIRST( X )。

实践

记得,曾经有人说过:

只读,就会白给

下面以这个文法为例讲解一波,会用精简版规则,更容易理解一些:

E -> T E'
E' -> + T E' | ε
T -> F T'
T' -> * F T' | ε
F -> ( E ) | id
  • 1
  • 2
  • 3
  • 4
  • 5
  1. FIRST(E) = FIRST(T) 根据规则3,很容易理解,这里要注意的由于T不含ε,所以遍历到T就停止了,E’不会加入进来
  2. FIRST(E’) = FIRST(+) ∪ FIRST(ε)= { +, ε } 根据规则2和4,,很好理解
  3. FIRST(T) = FIRST(F) 根据规则3,和第一条推导过程一样
  4. FIRST(T’) = FIRST() ∪ FIRST(ε)= { , ε } 根据规则2和4,和第二条推导一样
  5. FIRST(F) = FIRST( ( ) ∪ FIRST(id)= { ( , id } 根据规则2

结果:

FIRST(E) = FIRST(T) = FIRST(F) = { ( , id }
FIRST(E') = FIRST(+) ∪ FIRST(ε)= { + , ε }
FIRST(E') = FIRST(*) ∪ FIRST(ε)= { * , ε }
  • 1
  • 2
  • 3

FOLLOW集合

定义

对于非终结符号A,FOLLOW(A) 被定义为可能在某些句型中紧跟在A右边的终结符号集合。

规则

计算文法符号 X 的 FOLLOW(X) ,不断运用以下规则直到没有新终结符号可以被加入任意FOLLOW集合为止 :

(1)将$加入到FOLLOW(X)中,其中S是开始符号,而$是输出右端的结束标记。

(2)如果存在一个产生式S->αXβ,那么将集合FIRST(β)中除ε外的所有元素加入到FOLLOW(X)当中。

(3)如果存在一个产生式 S->αX , 或者S->αXβ且FIRST(β)中包含ε , 那么将集合FOLLOW(S)中的所有元素加入到集合FOLLOW(X)中。

实践

还是用之前的例子来做

E -> T E'
E' -> + T E' | ε
T -> F T'
T' -> * F T' | ε
F -> ( E ) | id
  • 1
  • 2
  • 3
  • 4
  • 5
  1. FOLLOW(E) ,根据规则1,首先把$加入进来,根据规则2,可以得出 FOLLOW(E) = { ) , $ }
  2. FOLLOW(E’) = FOLLOW(E) = { ) , $ } 根据规则3
  3. FOLLOW(T) = FIRST(E’) ∪ FOLLOW(E) = { + , ) , $ } 根据规则2
  4. FOLLOW(T’) = FOLLOW(T) = { + , ) , $ } 根据规则3
  5. FOLLOW(F) = FOLLOW(T) ∪ FIRST(T’) = { * , + , ) , $ } 根据规则2和3

结果:

FOLLOW(E) = FOLLOW(E') = { ) , $ }
FOLLOW(T) = FOLLOW(T') = { + , ) , $ }
FOLLOW(F) = { * , + , ) , $ }
  • 1
  • 2
  • 3

LL(1)文法

解释

LL(1) 中第一个“L”表示从左向右扫描输入,第二个“L”表示产生最左推导,而“1”表示在每一步中只需要向前看一个输入符号来决定语法分析动作。

定义

对于文法LL(1)文法G,当且仅当G的任意两个不同产生式 A -> α | β

(1)不存在终结符号a使得α和β都能推导出以a开头的串。

(2)α和β中最多只有一个可以推导出空串。

(3)如果 β=》ε ,那么α不能推导出任何以FOLLOW(A)中某个终结符号开头的串。

可能很多人看的云里雾里,解释一下:

(1)和(2)意思是α和β的FIRST集合相交。(3)是指如果FIRST(α)中有 ε,那么FIRST(β)和FOLLOW(A)是不相交的集合,反之一样。

预测分析表的构建

方法:

对于文法G的每个产生式 A->α ,进行如下处理

(1)对于FIRST(α)中每个终结符号a,将 A->α 加入到 M[A,a] 中。

(2)如果 ε在FIRST(α)中,那么对于FOLLOW(A)中每个终结符号b,将 A->α 加入到 M[A,b] 中。如果 ε在FIRST(α),且$在FOLLOW(A)中,也将 A->α 加入到 M[A,$] 中。

还是以之前的例子示例

E -> T E'
E' -> + T E' | ε
T -> F T'
T' -> * F T' | ε
F -> ( E ) | id
  • 1
  • 2
  • 3
  • 4
  • 5

1.先求FIRST和FOLLOW集合:

FIRST(E) = FIRST(T) = FIRST(F) = { ( , id }
FIRST(E') = FIRST(+) ∪ FIRST(ε)= { + , ε }
FIRST(T') = FIRST(*) ∪ FIRST(ε)= { * , ε }
FOLLOW(E) = FOLLOW(E') = { ) , $ }
FOLLOW(T) = FOLLOW(T') = { + , ) , $ }
FOLLOW(F) = { * , + , ) , $ }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.然后构建一个这样的表



3.然后依次填入非终结符号



4.按照规则1填写其余内容



5.按照规则2填写内容



至此整个构建全部完成

                                </div>

FIRST集合、FOLLOW集合及LL(1)文法求法的更多相关文章

  1. FIRST集合、FOLLOW集合、SELECT集合以及预测分析表地构造

    FIRST集合.FOLLOW集合.SELECT集合以及预测分析表地构造 FIRST集合的简单理解就是推导出的字符串的开头终结符的集合. FOLLOW集合简单的理解就对于非终结符后面接的第一个终结符. ...

  2. first集合follow集的求法

    FIRST集的定义 : 设G=(VT,VN,P,S)是上下文无关文法 FIRST(a)={a|a=>*ab,a∈VT, a,b∈V*} 若a=>*ε则规定ε∈FIRST (a) FIRST ...

  3. 【BZOJ-4199】品酒大会 后缀数组 + 并查集合并集合

    4199: [Noi2015]品酒大会 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 436  Solved: 243[Submit][Status] ...

  4. Linq to 泛型集合查询集合包括大写M和年龄小于等于18

    #region Linq to 泛型集合查询集合包括大写M和年龄小于等于18            //List<Student> list = new List<Student&g ...

  5. IT第二十一天 - Collections、ArrayList集合、LinkedList集合、Set集合、HashMap集合、集合的操作注意【修20130828】

    NIIT第二十一天 上午 集合 1. 集合Collection存储数据的形式是单个存储的,而Map存储是按照键值对来存储的,键值对:即键+值同时存储的,类似align="center&quo ...

  6. 数组转集合、集合转数组、字符串数组与int型、long型数组等的转换

    在项目中经常会遇到数组转集合.集合转数组.数组之间类型转换等操作 1.数组转集合 为了实现把一个数组转换成一个ArrayList,很多Java程序员会使用如下的代码: String str[] = { ...

  7. 廖雪峰Java5集合-1Java集合简介-1Java结合简介

    1.集合 定义:集合就是一堆东西.集合里的东西,称为元素Element 数学中的集合: 有限集合: * 一个班所有的学生组成的集合 * 一个网站所有的商品组成的集合 无限集合: * 全体自然数集合 * ...

  8. Java集合 -- ArrayList集合及应用

    JAVA集合 对象数组 集合类之ArrayList 学生管理系统 斗地主案例 NO.one 对象数组 1.1 对象数组描述 A:基本类型的数组:存储的元素为基本类型 int[] arr={1,2,3, ...

  9. Java集合----Set集合

    Set集合 Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败. Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法 Ha ...

随机推荐

  1. C++11 STL Regex正则表达式与字符串字段解析

    简单的日期正则表达式 一个简单的日期解析程序,从yyyy-mm-dd格式的日期字符串中,分别获取年月日. 先设置一个简单的正则表达式,4位数字的"年",1-2位数字的"月 ...

  2. spring学习(七)spring整合JDBC

    Spring中封装了一个可操作数据库的对象,该对象封装了JDBC技术 使用数据库 一.导包(IDEA的maven工程,在pom.xml文件中导入依赖,必须注意依赖,不然会报各种异常) <?xml ...

  3. 面试题三十:包含min函数的栈

    定义一个栈的数据结构,请实现一个每次都能找到栈中的最小元素,要求时间复杂度O(1).意思就是说每次进栈出栈后,min函数总能在时间1的前提下找到.方法一:由于每次循序遍历栈的话时间复杂度为n,所以要想 ...

  4. 第33课 C++中的字符串

    1. 历史遗留问题及解决方案 (1)历史遗留问题 ①C语言不支持真正意义上的字符串------c语言是用字符数组实现字符串 ②C语言用字符数组和一组函数模拟字符串操作 ③C语言不支持自定义类型,因此无 ...

  5. 关于RecyclerView(一)基本使用

    前言 最近在项目中用到了ListView,不知道为什么总是出现数据错乱的情况,另外RecyclerView包含很多Item动画,所以改成了RecyclerView. 简单使用 RecyclerView ...

  6. 02 . Beego框架结构组织,路由及项目初始化

    Beego项目组织结构 conf conf:项目配置文件所在的目录,项目中有一些全局的配置都可以放在此目录下.默认的app.conf文件中默认指定了三个配置: // 1)appname = Beego ...

  7. Django开发之Ajax 返回内容报错

    预期效果 Django通过Ajax POST提交数据,前台弹窗处理结果 粗略代码 # views.py 代码 ...省略... msg = { 'code': 200, 'message': 'Hel ...

  8. PHP is_link() 函数

    定义和用法 The is_link() 函数检查指定的文件是否是一个连接. 如果文件是一个连接,该函数返回 TRUE. 语法 is_link(file) 参数 描述 file 必需.规定要检查的文件. ...

  9. MyBatis辟邪剑谱

    一 MyBatis简介 MyBatis是一个优秀的持久层框架 它对JDBC操作数据库的过程进行封装 开发者只需要关注SQL本身 而不需要花费精力去处理JDBC繁杂的过程代码 MyBatis将要执行的各 ...

  10. java开发-flyway

    数据库版本管理工具 什么是数据库版本管理? 做过开发的小伙伴们都知道,实现一个需求时,一般情况下都需要设计到数据库表结构的修改.那么我们怎么能保证项目多人开发时,多个数据库环境(测试,生产环境)能够保 ...