FIRST集合、FOLLOW集合及LL(1)文法求法
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
- FIRST(E) = FIRST(T) 根据规则3,很容易理解,这里要注意的由于T不含ε,所以遍历到T就停止了,E’不会加入进来
- FIRST(E’) = FIRST(+) ∪ FIRST(ε)= { +, ε } 根据规则2和4,,很好理解
- FIRST(T) = FIRST(F) 根据规则3,和第一条推导过程一样
- FIRST(T’) = FIRST() ∪ FIRST(ε)= { , ε } 根据规则2和4,和第二条推导一样
- 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
- FOLLOW(E) ,根据规则1,首先把$加入进来,根据规则2,可以得出 FOLLOW(E) = { ) , $ }
- FOLLOW(E’) = FOLLOW(E) = { ) , $ } 根据规则3
- FOLLOW(T) = FIRST(E’) ∪ FOLLOW(E) = { + , ) , $ } 根据规则2
- FOLLOW(T’) = FOLLOW(T) = { + , ) , $ } 根据规则3
- 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)文法求法的更多相关文章
- FIRST集合、FOLLOW集合、SELECT集合以及预测分析表地构造
FIRST集合.FOLLOW集合.SELECT集合以及预测分析表地构造 FIRST集合的简单理解就是推导出的字符串的开头终结符的集合. FOLLOW集合简单的理解就对于非终结符后面接的第一个终结符. ...
- first集合follow集的求法
FIRST集的定义 : 设G=(VT,VN,P,S)是上下文无关文法 FIRST(a)={a|a=>*ab,a∈VT, a,b∈V*} 若a=>*ε则规定ε∈FIRST (a) FIRST ...
- 【BZOJ-4199】品酒大会 后缀数组 + 并查集合并集合
4199: [Noi2015]品酒大会 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 436 Solved: 243[Submit][Status] ...
- Linq to 泛型集合查询集合包括大写M和年龄小于等于18
#region Linq to 泛型集合查询集合包括大写M和年龄小于等于18 //List<Student> list = new List<Student&g ...
- IT第二十一天 - Collections、ArrayList集合、LinkedList集合、Set集合、HashMap集合、集合的操作注意【修20130828】
NIIT第二十一天 上午 集合 1. 集合Collection存储数据的形式是单个存储的,而Map存储是按照键值对来存储的,键值对:即键+值同时存储的,类似align="center&quo ...
- 数组转集合、集合转数组、字符串数组与int型、long型数组等的转换
在项目中经常会遇到数组转集合.集合转数组.数组之间类型转换等操作 1.数组转集合 为了实现把一个数组转换成一个ArrayList,很多Java程序员会使用如下的代码: String str[] = { ...
- 廖雪峰Java5集合-1Java集合简介-1Java结合简介
1.集合 定义:集合就是一堆东西.集合里的东西,称为元素Element 数学中的集合: 有限集合: * 一个班所有的学生组成的集合 * 一个网站所有的商品组成的集合 无限集合: * 全体自然数集合 * ...
- Java集合 -- ArrayList集合及应用
JAVA集合 对象数组 集合类之ArrayList 学生管理系统 斗地主案例 NO.one 对象数组 1.1 对象数组描述 A:基本类型的数组:存储的元素为基本类型 int[] arr={1,2,3, ...
- Java集合----Set集合
Set集合 Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败. Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法 Ha ...
随机推荐
- iOS打包测试ipa
1. 连接iphone真机 2.选中真机, archive
- Spring Security 实战干货:理解AuthenticationManager
1. 前言 我们上一篇介绍了UsernamePasswordAuthenticationFilter的工作流程,留下了一个小小的伏笔,作为一个Servlet Filter应该存在一个doFilter实 ...
- HTML5其他标签应用
HTML5 是下一代 HTML 标准. HTML5 多媒体 音频标签 <audio src=" "></audio> 视频标签 <video src= ...
- 线程_进程间通信Queue合集
# Queue的工作原理 from multiprocessing import Queue q = Queue(3)#初始化一个Queue对象,最多可接收3条put消息 q.put("In ...
- abs,all,any函数的使用
''' abs函数:如果参数为实数,则返回绝对值 如果参数为复数,则返回复数的模 ''' a = 6 b = -6 c = 0 # print("a = {0} , b = {1} , c ...
- luogu P3920 [WC2014]紫荆花之恋
LINK:紫荆花之恋 每次动态加入一个节点 统计 有多少个节点和当前节点的距离小于他们的权值和. 显然我们不能n^2暴力. 考虑一个简化版的问题 树已经给出 每次求某个节点和其他节点的贡献. 不难想到 ...
- Vue笔记(有点乱)
Vue学习笔记(2019.7.31) 目录 Vue学习笔记(2019.7.31) vue 基本指令用法 v-cloak v-text v-html v-bind v-on 跑马灯 v-on v-mod ...
- ABAP 动态备份自建表数据到新表(自建表有数据的情况下要改字段长度或者其他)
当abaper开发好一个程序给用户使用一段时间后,发现某个字段的长度需要修改,但数据库表中已经存在很多数据,冒然直接改表字段可能会导致数据丢失,这种问题的后果可能非常严重. 所以我想到先复制出一个新表 ...
- RabbitMQ学习总结(1)-基础概念
1. 概念 1.1 AMQP协议 AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消 ...
- Springboot+Mybatis+Clickhouse+jsp 搭建单体应用项目(三)(添加增删改查)
一.添加增加接口 @ApiResponses(value = { @ApiResponse(code = 200, message = "接口返回成功状态"), @ApiRespo ...