编译原理中 Error Recovery 怎么实现错误恢复?

文章导读
Previous Quiz Next 解析器应该能够检测并报告程序中的任何错误。预期的是,当遇到错误时,解析器能够处理它并继续解析其余输入。大多数情况下,解析器需要检查错误,但错误可能在编译过程的各个阶段被遇到。程序在各个阶段可能存在以下几种错误:
📋 目录
  1. Panic mode
  2. Statement mode
  3. Error productions
  4. Global correction
  5. Abstract Syntax Trees
A A

编译器设计 - 错误恢复



Previous
Quiz
Next

解析器应该能够检测并报告程序中的任何错误。预期的是,当遇到错误时,解析器能够处理它并继续解析其余输入。大多数情况下,解析器需要检查错误,但错误可能在编译过程的各个阶段被遇到。程序在各个阶段可能存在以下几种错误:

  • 词法:某些标识符名称输入错误

  • 语法:缺少分号或括号不匹配

  • 语义:不兼容的值赋值

  • 逻辑:代码不可达、无限循环

解析器中可以实现四种常见的错误恢复策略来处理代码中的错误。

Panic mode

当解析器在语句的任何位置遇到错误时,它会忽略语句的其余部分,不处理从错误输入到分隔符(如分号)的输入。这是错误恢复的最简单方法,而且它能防止解析器陷入无限循环。

Statement mode

当解析器遇到错误时,它会尝试采取纠正措施,以便语句的其余输入允许解析器继续解析。例如,插入缺少的分号、将逗号替换为分号等。解析器设计者在这里需要小心,因为一个错误的纠正可能会导致无限循环。

Error productions

编译器设计者已知一些常见的代码错误。此外,设计者可以创建扩充文法,用于生成错误构造的产生式,当遇到这些错误时使用。

Global correction

解析器将手头的程序视为一个整体,试图弄清楚程序的预期功能,并寻找最接近的无错匹配。当输入错误语句 X 时,它会为某个最接近的无错语句 Y 创建解析树。这可能允许解析器对源代码进行最小更改,但由于该策略的复杂性(时间和空间),尚未在实践中实现。

Abstract Syntax Trees

解析树表示对编译器来说不易解析,因为它们包含了比实际需要更多的细节。以以下解析树为例:

Parse Tree

仔细观察,我们会发现大多数叶节点都是其父节点的单一子节点。在此之前,可以消除这些信息,然后将其输入到下一阶段。通过隐藏多余信息,我们可以得到如下所示的树:

Abstract Syntax Tree

抽象语法树可以表示为:

Abstract Syntax Tree Representation

AST 是编译器中重要的数据结构,包含最少的不必要信息。AST 比解析树更紧凑,便于编译器使用。