编译器笔记11-语法分析-递归与非递归的预测分析

递归的预测分析法

递归的预测分析法是指:在递归下降分析中,根据预测分析表进行产生式的选择。根据每个非终结符的产生式和LL(1)文法的预测分析表,为每个非终结符编写对应的过程:

过程.png
主过程.png

PROGRAM表示为程序,其中program与end为关键字。DELIST表示标识符的序列。STLIST表示语句的序列,s表示语句。

PROGRAM的过程.png
DECLIST的过程.png
DECLISTN的过程.png
STLIST的过程.png
STLISTN的过程.png
TYPE的过程.png

若过程中不发生错误则说明输入是符号文法的。

非递归的预测分析法

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

自动机.png

下推自动机比有穷自动机识别能力更强,有穷自动机的识别能力不强是因为其识别能力不强。如若想识别上图例子中语言的句子,就需要读入a的个数。但有穷自动机不具备专门的存储器因此它利用不同的状态记录a的个数n。但n是趋于无穷而有穷自动机的状态数是有穷的,这就导致有穷自动机无法识别这样的语言。

非递归的预测分析法.png

上图输出的产生式序列就相当于一个最左推导

表驱动的预测分析法

输入:一个串w和文法G的分析表M
输出:如果w 在L(G) 中,输出w的最左推导;否则给出错误提示
方法:最初,语法分析器的格局如下:输入缓冲区中是w$ ,G的开始符号位于栈顶,其下面是$。下面的程序使用预测分析表M生成了处理这个输入的预测分析过程

预测分析过程.png

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

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

递归预测分析法是根据产生式的右部来编写程序,因此直观性比较好。

预测分析法实现步骤:

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

预测分析中的错误处理

预测分析中的错误检测

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

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

恐慌模式:

  1. 忽略输入中的一些符号,直到输入中出现由设计者选定的同步词法单元 (synchronizing token) 集合中的某个词法单元。其效果依赖于同步集合的选取。集合的选取应该使得语法分析器能从实际遇到的错误中快速恢复。

例如可以把FOLLOW(A)中的所有终结符放入非终结符A的同步记号集合。这么做的原因是当栈顶为非终结符A的时候检测到错误,说明A在识别过程中遇到了问题,此时就会放弃对A这个成分进行识别而从它后面的成分继续分析,因此当FALLOW(A)符号出现的时候就可以立即进行同步。此时将A出栈,从它后面的成分继续进行分析。

  1. 如果终结符在栈顶而不能匹配,一个简单的办法就是弹出此终结符。
同步词法单元.png

由于E'与T'有空产生式,它们的FOLLOW集中对应的符号,对应对空产生式的应用,因此它们不作为同步词法单元。

分析表的使用方法:

  • 如果M[A,a ]是空,表示检测到错误,根据恐慌模式忽略输入符号a。
  • 如果M[A,a ]是synch,则弹出栈顶的非终结符A,试图继续分析后面的语法成分。
  • 如果栈顶的终结符和输入符号不匹配,则弹出栈顶的终结符。
恐慌模式处理错误.png

你可能感兴趣的:(编译器笔记11-语法分析-递归与非递归的预测分析)