decaf-doc
  • Introduction
  • pa1a
    • 实验内容
    • lalr1使用指导
      • 编写lexer
      • impl块的可选属性
      • 产生式和语法动作
      • 解决冲突
      • 一个完整的例子
    • 抽象语法树
    • 框架中部分实现的解释
    • 文件结构
  • pa1b
    • 实验内容
    • lalr1使用指导
    • 错误恢复
    • 文件结构
  • pa2
    • 实验内容
    • 语义分析
    • 符号表
    • 语句的返回类型
    • visitor模式
    • 框架中部分实现的解释
  • pa3
    • 实验内容
    • 中间代码
    • 中间代码中的类型信息
    • 运行时存储布局
    • 面向对象机制
    • tacvm介绍
  • pa4
    • 实验内容
    • 基本块
    • 数据流分析概述
    • 数据流优化概述
    • 公共表达式提取
    • 复写传播
    • 常量传播
    • 死代码消除
  • pa5
    • 实验内容
    • 图着色基本原理
    • 改进干涉图节点
    • 着色算法
    • 预着色节点
    • 干涉图节点合并
    • 调用约定
Powered by GitBook
On this page

Was this helpful?

  1. pa1b

错误恢复

Previouslalr1使用指导Next文件结构

Last updated 5 years ago

Was this helpful?

框架中的_parse函数已经实现了一部分,然而尚未实现错误恢复的功能,遇到错误时会直接unimplemented!(),这是大家需要完成的实验任务。

在lecture4中,我们介绍了应急恢复和短语层恢复的方法。这里,我们使用一种介于二者之间的错误恢复方法:与应急恢复的方法类似,当分析非终结符AAA时,若当前输入符号a∉Begin(A)a \notin Begin(A)a∈/Begin(A),则先报错,然后跳过输入符号串中的一些符号,直至遇到Begin(A)⋃End(A)Begin(A) \bigcup End(A)Begin(A)⋃End(A)中的符号:

  • 若遇到的是Begin(A)Begin(A)Begin(A)中的符号,可恢复分析A,即可以选择一个左端为AAA的产生式来分析它

  • 若遇到的是End(A)End(A)End(A)中的符号,则A分析失败,返回StackItem::_Fail,继续分析AAA后面的符号

这个处理方法与应急恢复方法的不同之处在于:

  • 我们用集合Begin(A)={s∣PS[A,s]非空}Begin(A) = \{s | PS[A, s]非空\}Begin(A)={s∣PS[A,s]非空}(其中,PSPSPS为预测分析表)来代替First(A)First(A)First(A)。由于First(A)∈Begin(A)First(A) \in Begin(A)First(A)∈Begin(A),我们能少跳过一些符号

  • 我们用集合End(A)=Follow(A)⋃FEnd(A) = Follow(A) \bigcup FEnd(A)=Follow(A)⋃F(其中,F为_parse函数传入的最后一个参数)来代替Follow(A)Follow(A)Follow(A)。由于FFF集合包含了AAA各父节点的FollowFollowFollow集合,我们能少跳过一些符号,同时由于结束符(_Eof)必然属于文法开始符号的FollowFollowFollow集合,本算法无需额外考虑因读到文件尾而陷入死循环的问题。

另外,当匹配终结符失败时,只报错,但不消耗此匹配失败的终结符,而是将它保留在剩余输入串中。这个逻辑已经在_parse函数中实现。