本次笔记内容:
4-4 FIRST集和FOLLOW集
4-5 递归的预测分析法
4-6 非递归的预测分析法
4-7 预测分析法中的错误处理

本节课幻灯片,见于我的 GitHub 仓库:第5讲 语法分析_2.pdf

文章目录

  • FIRST集和FOLLOW集的计算
    • 计算文法符号X的FIRST(X)
      • 算法总结
      • 接着,计算串X1X2 …Xn的FIRST 集合
    • 计算非终结符A的FOLLOW(A)
      • 算法总结
      • 基于FIRST于FOLLOW计算SELECT集
    • 预测分析表
  • 递归的预测分析法
  • 非递归的预测分析法
    • 递归的预测分析法vs.非递归的预测分析法
    • 总结预测分析法实现步骤
  • 预测分析中的错误处理
    • 预测分析中的错误检测
    • 预测分析中的错误恢复

承接上一节课。上一节课提出了FIRST集FOLLOW集的概念,这节课先来讨论如何计算这两个集合。

FIRST集和FOLLOW集的计算

计算文法符号X的FIRST(X)

  • FIRST(X):可以从X推导出的所有串首终结符构成的集合;
  • 如果X⇒∗ϵX \Rightarrow * \epsilonX⇒∗ϵ,那么ε∈FIRST(X)。

取决于产生式的右部:

  • 比如2、4、5产生式,左部以终结符打头,这个终结符就是就是产生式可以推导出的终结符,于是加入到 FIRST 集合中
  • 对于非终结符,其依赖于自己的内容,比如F的FIRST为 {( id} ,则 T 的 FIRST 也为这个; E 依赖于 T ,则 E 的 FIRST 也是这个。
算法总结

不断应用下列规则,直到没有新的终结符或ε可以被加入到任何FIRST集合中为止。

  • 如果X是一个终结符,那么FIRST ( X ) = { X };
  • 如果X是一个非终结符,且X→Y1…Yk∈P(k≥1),那么如果对于某个i,a在FIRST (Yi ) 中且ε 在所有的FIRST(Y1) , … , FIRST(Yi-1)中(即Y1…Yi-1 ⇒\Rightarrow⇒* ε ),就把a加入到FIRST( X )中。如果对于所有的j = 1,2, . . . , k,ε在FIRST(Yj)中,那么将ε加入到FIRST( X );
  • 如果X→ε∈P,那么将ε加入到FIRST( X )中。
接着,计算串X1X2 …Xn的FIRST 集合
  • 向FIRST(X1X2X3X_1X_2X_3X1​X2​X3​)加入FIRST(X1X_1X1​)中所有的非ε符号;
  • 如果ε在FIRST(X1X_1X1​)中,再加入FIRST(X2X_2X2​)中的所有非ε符号;如果ε在FIRST(X1X_1X1​)和FIRST(X2X_2X2​)中,再加入FIRST(X3X_3X3​)中的所有非ε符号,以此类推;
  • 最后,如果对所有的i,ε都在FIRST(XiX_iXi​)中,那么将ε加入到FIRST(X1X2...XnX_1X_2...X_nX1​X2​...Xn​) 中。

计算非终结符A的FOLLOW(A)

  • FOLLOW(A):可能在某个句型中紧跟在A后边的终结符a的集合;
  • FOLLOW(A)={a∣S⇒∗αAaβ,a∈VT,α,β∈(VT∪VN)∗}F O L L O W(A)=\left\{\mathrm{a} \mid S \Rightarrow^{*} \alpha A a \beta, \mathrm{a} \in V_{T}, \quad \alpha, \beta \in\left(V_{T} \cup V_{N}\right)^{*}\right\}FOLLOW(A)={a∣S⇒∗αAaβ,a∈VT​,α,β∈(VT​∪VN​)∗}
  • 如果A是某个句型的的最右符号,则将结束符“$”添加到FOLLOW(A)中。

例子如上,基于 FIRST 计算:

  • 文法大E本身是一个句型,它也是这个句型的最右符号,因此将 $ 加入其 FOLLOW 集中;
  • 接下来逐个分析产生式。
  • 第一条产生式中,E’的FIRST集中的所有终结符可以跟在T的后面,所以将E’中的终结符,也就是 + 加入到T的 FOLLOW 集中;
  • 由于 E’ 可以推出空串,那么能跟在 E 后面的符号,就能跟在 T 后面,因此,将E的FOLLOW的$添加到T的FOLLOW中;
  • 对于E’,E’是产生式E→TE′E \rightarrow TE'E→TE′中最右边的符号,因此能跟在E后面的,自然就能跟在E’后面,因此将E中的元素添加到E’中。
  • 以此类推。
  • 最后,各个产生式都过完一遍了,再回到第一个产生式。注意到由于E’可以是空串,那么E’后面的东西,也能出现在T后面,因此将E’中有的而T中没有的反括号)加入到T中;补充添加以此类推。
算法总结

不断应用下列规则,直到没有新的终结符可以被加入到任何FOLLOW集合中为止:

  • 将$放入FOLLOW(S)中,其中S是开始符号,$是输入右端的结束标记
  • 如果存在一个产生式A→αBβ,那么FIRST(β)中除ε之外的所有符号都在FOLLOW(B)中;
  • 如果存在一个产生式A→αB,或存在产生式A→αBβ且FIRST(β) 包含ε,那么FOLLOW(A)中的所有符号都在FOLLOW(B)中。
基于FIRST于FOLLOW计算SELECT集

  • 第一个产生式,左部是T(非终结符),因此是T的FIRST集中的终结符
  • 第二个产生式,左部是终结符,因此就是终结符
  • 第三个产生式,左部是空串,因此就是其FOLLOW集

可以看出:

  • 第1个和第2个产生式,具有相同的左部,其SELECT集互不相交
  • 第4,5同理;
  • 因此,这个算数表达式文法是LL(1)文法
  • 因此可以写预测分析表

预测分析表

由上,我们得出了这个可以帮助我们大大提升效率,不需要再编译中回溯的预测分析表

LL(1)文法的分析方法分为,将在后面介绍:

  • 递归的预测分析法
  • 非递归的预测分析法

递归的预测分析法

递归的预测分析法是指:在递归下降分析中,根据预测分析表进行产生式的选择。

根据每个非终结符的产生式和LL(1)文法的预测分析表,为每个非终结符编写对应的过程。

一个例子:

右边为递归下降分析的主程序。

其递归过程如下。






非终结符有自己对应的程序。

非递归的预测分析法

非递归的预测分析不需要为每个非终结符编写递归下降过程,而是根据预测分析表构造一个自动机,也叫表驱动的预测分析

如图,为有穷自动机增加一个栈,用于增加记忆功能。比如对于上图中例子,输入a,压栈,输入b,b进栈,a出栈,最终可以判断a与b的数量是否一致。

如图,通过入栈出栈的形式,实现了预测分析

表驱动的预测分析法总结:

递归的预测分析法vs.非递归的预测分析法

递归的预测分析法 非递归的预测分析法
程序规模 程序规模较大,不需载入分析表 主控程序规模较小,需载入分析表(表较小)
直观性 较好 较差
效率 较低 分析时间大约正比于待分析程序的长度
自动生成 较难 较易

总结预测分析法实现步骤

  1. 构造文法;
  2. 改造文法:消除二义性、消除左递归、消除回溯;
  3. 求每个变量的FIRST集和FOLLOW集,从而求得每个候选式的SELECT集
  4. 检查是不是LL(1)文法。若是,构造预测分析表
  5. 对于递归的预测分析,根据预测分析表为每一个非终结符编写一个过程;对于非递归的预测分析,实现表驱动的预测分析算法;

预测分析中的错误处理

预测分析中的错误检测

两种情况下可以检测到错误:

  • 栈顶的终结符和当前输入符号不匹配;
  • 栈顶非终结符与当前输入符号在预测分析表对应项中的信息为空。

预测分析中的错误恢复

可以使用恐慌模式:

  • 忽略输入中的一些符号,直到输入中出现由设计者选定的同步词法单元(synchronizing token)集合中的某个词法单元:
    • 其效果依赖于同步集合的选取。集合的选取应该使得语法分析器能从实际遇到的错误中快速恢复
    • 例如可以把FOLLOW(A)中的所有终结符放入非终结符A的同步记号集合;
  • 如果终结符在栈顶而不能匹配,一个简单的办法就是弹出此终结符。

一个例子:

先由FOLLOW(X)得到SYNCH在哪里。

【编译原理笔记05】语法分析:FIRST集和FOLLOW集的计算,[非]递归的预测分析法,预测分析中的错误处理相关推荐

  1. FIRST集和FOLLOW集的计算

    文章目录 `FIRST`集的计算 计算`FIRST(x)` 具体算法 计算`$X_21,X_2,X_3,...,X_n$`的`FIRST`集 FOLLOW集的计算 算法 FIRST集的计算 计算FIR ...

  2. 【编译原理】FIRST集和FOLLOW集构造法速学

    编译原理速成大法 FIRST集和FOLLOW集构造法速成 FIRST FOLLOW FIRST集和FOLLOW集构造法速成 例:对于文法G(E) 首先像E,T,E',F这样的就是非终结符 +,*, ε ...

  3. 【编译原理笔记07】语法分析:SLR、LR(1)、LALR、二义性分析与错误处理

    本次笔记内容: 4-12 SLR 4-13 LR1分析 4-14 LALR分析法 4-15 二义性文法的LR分析 4-16 LR分析中的错误处理 本节课幻灯片,见于我的 GitHub 仓库:第7讲 语 ...

  4. 编译原理-First集和Follow集

    刚学first集和follow集的时候,如果上课老师没有讲明白或者自己没听明白,自己看的时候还真是有点难理解,不过结合着具体的题目可以理解的更快. 先看一下两种集合的求法: First集合的求法:   ...

  5. 【编译原理笔记06】语法分析,移入-归约分析:自底向上的分析,LR(0)分析法,LR(0)分析表的构建(基于自动机)

    本次笔记内容: 4-8 自底向上的分析概述 4-9 LR分析法概述 4-10 LR0分析 4-11 LR0分析表构造 本节课幻灯片,见于我的 GitHub 仓库:第6讲 语法分析_3.pdf 本节课介 ...

  6. 【编译原理】First集和Follow集简易解释(偏人话)

    \ε:非ε元素 First集和Follow集是集合 First集规则(相应字母在->左边,查找->右边第一个东西) ①A->aB,a加进First(A): (->右边第一个是终 ...

  7. 编译原理--实验2 语法分析

    文章目录 前言 1.1实验目的 1.2 实验任务 1.3 实验内容 1.3.1 实验要求 1.3.2 输入格式 1.3.3 输出格式 1.3.4 样例 1.4 程序 1.4.1 程序流程图 1.4.2 ...

  8. 编译原理笔记(二)之词法分析

    编译原理笔记(二)之词法分析 1. 词法分析中的若干问题 1.1 基本概念 1.2 记号的属性 1.3 词法分析器的作用与工作方式 1.4 输入缓冲区 2. 模式的形式化描述 2.1 字符串与语言 2 ...

  9. zucc 编译原理 笔记

    zucc 编译原理 笔记 lec02 lec03 lec04

最新文章

  1. 没想到图像直方图有这么多应用场景
  2. gradle加载spring包
  3. 【项目管理】ITTO-风险管理
  4. php图片上传方案,php图片上传
  5. HoloLens开发手记 - Unity development overview 使用Unity开发概述
  6. 把室友的STM32换成了GD32,会被打吗?
  7. mysql+误操作怎么恢复_Mysql误操作恢复流程
  8. js室内地图开发_GIS开发_OpenLayers
  9. linux用shell写正则表达式,Linux命令行与Shell脚本编程大全-shell正则表达式
  10. oracle11g手工监听配置,手工在同一主机创建主备库oracle11g active dataguard
  11. 9.数据结构 --- 查找
  12. 第2章-系统控制原理 -> 李雅普诺夫稳定性分析
  13. 井口综合安检-解决方案
  14. word无法自动修复计算机怎么办,电脑Word问题解决办法
  15. 家里装电线时,为啥说“走顶”比“走地”好
  16. 微信公众号网页授权--前端获取code及用户信息(vue)
  17. 进程与程序的区别与联系
  18. 企业微信客户端通过jsapi调起微信扫码提示40093:jsapi签名错误
  19. 软件工程毕业设计课题(73)微信小程序毕业设计PHP菜谱美食小程序系统设计与实现
  20. 导入自己模块包导入报错:ModuleNotFoundError: No module named ‘xxx‘解决方法 晓物智联

热门文章

  1. php 变量传给另外一个函数,将在一个函数中创建的PHP变量传递给另一个
  2. 【Linux】Ubuntu输入法不能开机自启的解决方法
  3. 解决Android Studio卡在Gradle:Resolve dependecies ‘app:_debugCompile‘问题
  4. 跨站点脚本编制-XSS 描述及解决方法
  5. 我的世界java版联机不稳定_我的世界:你一定不会相信,时隔2年,网易这次真的“更新”了...
  6. car-like robot运动模型及应用分析(图片版)
  7. python有关迭代器和生成器的面试题_python面试题之生成器迭代器
  8. 手机按三角返回页面上一页_小猿圈微信小程序跳转页面都有哪些?
  9. 最长公共子串(10分)
  10. 找出数组的最大公约数