【编译原理】FIRST集合和FOLLOW集合

2023-11-01

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)中。

上述为官方给出的计算FIRST集合的规则,不太好理解,接下来我将综合其他笔者总结的规则给出我理解的FIRST集合的规则。

(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

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(T') = FIRST(*) ∪ FIRST(ε)= { * , ε }

FOLLOW集合

定义:对于非终结符号X,FOLLOW(X) 被定义为可能在某些句型中紧跟在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)中。

理解:FOLLOW集合对于非终结符而言,是非终结符的全部后跟符号的集合,

如果后跟终结符则加入,

如果后跟非终结符,则加入该非终结符的不含空符号串的FIRST集,

特别地,文法的识别符的FOLLOW集需要额外的加入‘#’。

下面给出简化后的规则:

首先:如果要找L的Follow,要从式子的右边找到L,然后来找L的Follow。

其次:将‘#’加入到 开始符 的 Follow中  ①

接着:如果L的右边是终结符,那么这个终结符加入L的Follow  ②

如果L的右边是非终结符, 那么把这个非终结符的First集合除去 ε后剩下的元素加到L的Follow中,同时将 '->' 符号左边的Follow加入L的Follow  ③

特别的,如果L处在末尾,那么,将 '->' 符号左边的Follow加入L的Follow  ④

练习:还是用之前的例子来做

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

FOLLOW(E) ,运用 ① ,E是开始符,所以首先将 # 加入到 FOLLOW(E)中 ;接下来在上述文法的右边找到  E ,发现E在第5行文法的右边,E 后面是终结符 ) ,所以将 )加入到 FOLLOW(E)中 ;此处运用的是规则②,综上即 FOLLOW(E) = { ) , # }


FOLLOW(E’) ,先在上述文法的右边找到  E' ,发现E' 分别在第1行(在自己行不算),此时可以运用规则④,即将FOLLOW(E) 加入到FOLLOW(E')中,综上即 FOLLOW(E')= FOLLOW(E) = { ) , # } 


FOLLOW(T),先在上述文法的右边找到 T ,发现T在第一行,此时运用规则 ③,将E'的FIRST集合中除  ε外其他元素加入到FOLLOW(T)中,同时将FOLLOW(E) 加入到FOLLOW(T)中,综上即FOLLOW(T)= { + , ) , # } 


FOLLOW(T’) ,先在上述文法的右边找到 T ' ,发现T'在第三行,此时可以运用规则④,即将FOLLOW(T) 加入到FOLLOW(T')中,综上即 FOLLOW(T')= FOLLOW(T) = { + , ) , # } 


FOLLOW(F),先在上述文法的右边找到 ,发现F在第三行和第四行,此时运用规则 ③,对于第3行,将T'的FIRST集合中除  ε外其他元素加入到FOLLOW(F)中,同时将FOLLOW(T) 加入到FOLLOW(F)中,此时FOLLOW(F)= { * , + , ) , # } ;对于第4行,将将T'的FIRST集合中除  ε外其他元素加入到FOLLOW(F)中,同时将FOLLOW(T') 加入到FOLLOW(F)中,而 FOLLOW(T')= FOLLOW(T),所以FOLLOW(F)依旧= { * , + , ) , # } ,综上所述,FOLLOW(F)= { * , + , ) , # } 。

结果:

FOLLOW(E) = FOLLOW(E') = { ) , # }

FOLLOW(T) = FOLLOW(T') = { + , ) , # }

FOLLOW(F) = { * , + , ) ,# }

FIRST集合和FOLLOW集合在编译原理语法分析中是我觉得比较难理解的,以上是我看过很多csdn上面其他文章再加上我的理解总结出来的,尤其是FOLLOW集合,是我看了另一篇写的好的文章加上我的理解总结出来的,希望对你们有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【编译原理】FIRST集合和FOLLOW集合 的相关文章

  • LLVM Language Reference Manual

    摘要 该文档是LLVM汇编语言的参考指南 LLVM是基于表示的静态单赋值 SSA 该表示提供类型安全 低层级操作 灵活性 及简洁表示所有高层级语言的能力 这是贯穿各方面LLVM编译策略的通用代码表示 简介 LLVM代码表示用于三个不同形式
  • 【编译原理与技术】递归下降语法分析器(C++实现)

    目录 内容 示例 具体实现 C 代码 运行结果 内容 实现以下语法的递归下降分析 示例 对于以下代码给出其递归下降语法分析过程 i 2 while i lt 100 sum sum i i i 2 具体实现 首先对上下文无关文法进行检查 消
  • 编译原理 课程设计 LR(1)分析法

    作业目的 构造LR 1 分析程序 利用它进行语法分析 判断给出的符号串是否为该文法识别的句子 了解LR K 分析方法是严格的从左向右扫描 和自底向上的语法分析方法 作业题目 1 对下列文法 用LR 1 分析法对任意输入的符号串进行分析 0
  • 【编译原理】FIRST集合和FOLLOW集合

    FIRST集合 定义 可从 推导得到的串的首符号的集合 其中 是任意的文法符号串 规则 计算文法符号 X 的 FIRST X 不断运用以下规则直到没有新终结符号或 可以被加入为止 1 如果 X 是一个终结符号 那么 FIRST X X 2
  • 编译原理笔记

    目录 序章 编译原理 编译器 程序设计语言 第一章 概述 机器语言 第一代语言 特点 汇编语言 高级程序设计语言 鼻祖 时期 特点 翻译程序 汇编语言 解释语言 编译程序 编译过程 词法分析 语法分析 语义分析 中间代码生成 之前三步都是编
  • 深入浅出编译原理-5-一个简单语法分析器的C语言实现

    引言 前面已经介绍了编译器的预处理 词法分析 词法分析器的实现 也在其中说到了语法分析的任务和过程 语法分析的输入是词法单元序列 然后根据语言的文法表示 展开式 利用有限状态机理论 生成抽象语法树 然后遍历得到中间代码 即 三地址码 本节就
  • 将NFA变成最小化DFA的方法

    学习的时候总感觉这个遇到新的题目不会做 这里总结一下 整个流程是这样的 我们直接来看一个例子 使用上面的算法来实现我们最后的目标 a b ba ab 我们先来画NFA 明确 开始状态和接受状态 终结状态要画两个圈 值得注意的是 由于 也可以
  • 电子科技大学编译原理复习笔记(四):程序语言的设计

    目录 前言 重点一览 语言的定义 比较 生成观点与识别观点 语义又该怎么描述 符号串 符号串集合 文法 超重点 定义 组成 表示 分类 重点 文法产生的语言 短语 直接短语和句柄 求它们目的是语法分析 语法树 推导树 语言的设计 本章习题
  • 吉首大学_编译原理实验题_基于预测方法的语法分析程序的设计【通过代码】

    一 实验要求 实验二 基于预测方法的语法分析程序的设计 一 实验目的 了解预测分析器的基本构成及用自顶向下的预测法对表达式进行语法分析的方法 掌握预测语法分析程序的手工构造方法 二 实验内容 1 了解编译程序的基于预测方法的语法分析过程 2
  • LLVM里的寄存器分配 - 准备工作(一)

    1 背景介绍 本文档是基于 LLVM 的寄存器分配系列科研笔记第一篇 以一个 C 语言程序为主干介绍 LLVM 在寄存器分配前做的一些主要工作 分析在寄存器分配前期可能的写操作来源 并记录了我在研究 LLVM 后端中 SSA 形式的中间表示
  • 简单的递归下降语法分析程序

    简单递归分析程序 其代码如下 include
  • 编译原理实验二:Bison

    编译原理实验二 Bison 实验要求 1 了解Bision基础知识 如何将文法产生式转换为Bison语句 2 阅读 src common SyntaxTree c 对应头文件 include SyntaxTree h 理解分析树生成的过程
  • 编译原理绪论

    1 美图 5 编译过程一语法分析 任务 在词法分析的基础上 根据语言的语法规则把单词符号串分解成各类语法单位 语法范畴 依循的原则 语法规则 描述工具 上下文无关文法 6 编译过程一中间代码产生 任务 对各类不同语法范畴按语言的语义进行初步
  • 正规表达式与有限自动机

    1 美图 2 概念 3 正规式和正规集 正规集可以用正规表达式 简称正规式 表示 正规表达式是表示正规集一种方法 一个字集合是正规集当且仅当它能用正规式表示 3 1 正规式和正规集的递归定义 4 确定有限自动机 DFA
  • 递归下降算法语法分析c语言

    递归下降算法 自上而下文法的递归下降的预测分析 从根节点出发逐步构造分析树 所以被称作自上而下文法 在文法中有递归的函数 例如 E gt TE 所以叫做递归下降算法 使用的文法如下 E gt TE E gt TE e T gt FT T g
  • 编译原理实验:使用C/C++语言编写C-语言的词法分析器

    文章目录 实验目的 实验任务 实验内容 实验步骤 分析c 的词法规则 算法基本思想 Step1 find token Step2 DFA状态图构建 Step3 使用while switch双循环将DFA代码化 主程序流程 各程序模块之间层次
  • 编译原理LL(1)文法之提取左公因子,消除左递归

    在判断LL 1 文法是否符合的时候 需要判断LL 1 文法是否存在左公因子 和左递归的情况 以下给出相应的判断方法以及通过提取左公因子和消除左递归使非LL 1 文法转换为LL 1 法的方法 第一种情况 存在左公因子 解决方法 提取左公因子
  • 编译原理_计算器_flex、bison实现(详细辅助理解)

    编译原理 计算器 flex bison实现 详细辅助理解 个人博客 https www yuque com ngp blog tuanh6 https www yuque com ngp blog tuanh6 P S 这篇文章只能助你理解
  • 【编译原理】 CS143 斯坦福大学公开课 第一周:简介

    youtube 1 1 Introduction to Compilers and interpreters 1 1 Introduction to Compilers and interpreters 编译器解释器介绍 两种主要的实现编程
  • Go 程序编译过程(基于 Go1.21)

    版本说明 Go 1 21 官方文档 Go 语言官方文档详细阐述了 Go 语言编译器的具体执行过程 Go1 21 版本可以看这个 https github com golang go tree release branch go1 21 sr

随机推荐

  • [转载]Stanford华人教授李飞飞写给她学生的一封信,如何做好研究以及写好PA

    De mystifying Good Research and Good Papers By Fei Fei Li 2009 03 01 Please remember this 1000 computer vision papers ge
  • 算法——动态规划算法

    动态规划的核心思路 动态规划的解题核心主要分为两步 第一步 定义问题 有的问题过于抽象 或者过于啰嗦干扰我们解题的思路 我们要做的就是将题干中的问题转化成一系列同类问题的某个解的情况 比如说 题目 求一个数列中最大连续子序列的和 我们要将这
  • tomcat部署项目

    今天总算是把部署tomcat部署项目的几种方式实验了一下 一 1 下载 Tomcat 服务器 官网下载地址 http tomcat apache org 2 启动并部署 Tomcat 服务器 解压 tomcat 安装包到一个非中文目录下 配
  • 微服务架构详解

    一 微服务架构的由来 在微服务架构出现之前 最常用的架构就是单体架构 俗称 一个jar war 包打天下 在一个jar包工程中 采用MVC架构 分为表现层 业务层 数据访问层 所有的业务模块 都放在这个工程中集成 如下图所示 随着软件行业规
  • DS18B20温度传感器

    1 DS18B20 单线数字温度传感器 即 一线器件 其具有独特的优点 采用单总线的接口方式 与微处理器连接时仅需要一条口线即可实现微处理器与 DS18B20 的双向通讯 单总线具有经济性好 抗干扰能力强 适合于恶劣环境的现场温度测量 测量
  • 【前端】ant design中树形控件的父子节点受控实现

    前言 1 ant design的树形控件里面先设置好checkStrictly属性 即checkable 状态下节点选择完全受控 父子节点选中状态不再关联 这样的话 onCheck函数中的checkedKeys参数打印出来它是一个有chek
  • conda添加清华镜像源

    Anaconda 是一个用于科学计算的 Python 发行版 支持 Linux Mac Windows 包含了众多流行的科学计算 数据分析的 Python 包 Anaconda 安装包可以到 清华镜像源下载anaconda 下载 TUNA
  • 异步赠书:10月Python畅销书升级

    2018年最新活动 免费赠书 1 关注微信号 异步图书 2 邀请10位好友关注10天后 填写下方表单登记信息 即可免费获得异步图书一本 异步社区选书网址 www epubit com 点击登记免费图书邮寄信息 活动已结束 最新活动地址 ht
  • LeetCode 1689. 十-二进制数的最少数目

    如果一个十进制数字不含任何前导零 且每一位上的数字不是 0 就是 1 那么该数字就是一个 十 二进制数 例如 101 和 1100 都是 十 二进制数 而 112 和 3001 不是 给你一个表示十进制整数的字符串 n 返回和为 n 的 十
  • idea 通过访问路径快速定位到Controller方法

    目录 问题原因 解决方案 RestfulToolkit插件 使用方式 windows MAC 扩展 效果展示 问题原因 我们在调试 或者某个接口出现bug首先知道和拿到的一般是接口路径 系统运行久了 模块会很多 接口也会很多 找起来很麻烦
  • Strus2+Spring整合笔记

    1 拷贝Struts2 jar包和Spring jar包到 WEB INF lib目录下 2 配置Strust2核心控制器 配置文件 3 为第三步的Spring提供配置文件 4 添加Struts2 Spring整合的插件包 5 在appCt
  • 虚拟IP是什么?

    要是单讲解虚拟 IP 理解起来很困难 所以干脆把 动态 IP 固定 IP 实体 IP 与虚拟 IP都讲解一下 加深理解和知识扩展 实体 IP 在网络的世界里 为了要辨识每一部计算机的位置 因此有了计算机 IP 位址的定义 一个 IP 就好似
  • 2023-5-16第十六天

    permanent永久的 temporary instruction教授 传授 impart教授 initiate教授 接纳 reside居住于 resident居民 recover恢复 找回 laternate交替的 轮流的 interp
  • 小米官网项目制作——javascript知识分享上

    目录 前言 一 整体架构 二 弹出的盒子 1 定位盒子 2 弹出效果 3 其他细节 三 下拉 展开的切换菜单 1 放置盒子 2 切换盒子 3 添加索引 4 侧边展开的盒子 四 轮播图 1 本体的部件 2 轮播图 3 节流阀 4 其他的细节
  • Docker搭建Seata环境

    Docker搭建Seata环境 添加seata需要的数据库表 直接点击 mysql数据库 oracle数据库 postgresql数据库 为业务数据库也添加一个undo log表 Seata的AT模式下之所以在第一阶段直接提交事务 依赖的是
  • scikit keras_使用Scikit-Learn,Scikit-Opt和Keras进行超参数优化

    scikit keras Hyperparameter optimization is often one of the final steps in a data science project Once you have a short
  • Redis第十四讲 Redis是单线程还是多线程以及Redis保持高性能的原因

    Redis是单线程还是多线程 redis 4 0 之前 redis 是完全单线程的 redis 4 0 时 redis 引入了多线程 但是额外的线程只是用于后台处理 例如 删除对象 核心流程还是完全单线程的 这也是为什么有些人说 4 0 是
  • 【CTF知识库】常见安全设备默认口令清单

    设备 默认账号 默认密码 地址 深信服产品 sangfor sangfor sangfor 2018 sangfor 2019 无 深信服科技 AD dlanrecover https wenku baidu com view d49d55
  • UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x82 in position 193: illegal multibyte sequence

    终端命令行运行python出错 UnicodeDecodeError gbk codec can t decode byte 0x82 in position 193 illegal multibyte sequence 解决方法 参考博客
  • 【编译原理】FIRST集合和FOLLOW集合

    FIRST集合 定义 可从 推导得到的串的首符号的集合 其中 是任意的文法符号串 规则 计算文法符号 X 的 FIRST X 不断运用以下规则直到没有新终结符号或 可以被加入为止 1 如果 X 是一个终结符号 那么 FIRST X X 2