编译器设计 - 错误恢复
解析器应该能够检测并报告程序中的任何错误。当遇到错误时,解析器应该能够处理它并继续解析其余的输入。解析器主要检查错误,但在编译过程的各个阶段都可能遇到错误。程序可能在各个阶段出现以下类型的错误:
词汇:某些标识符的名称输入错误
语法:缺少分号或括号不匹配
语义:值分配不兼容
逻辑:代码无法访问,无限循环
解析器中可以实现四种常见的错误恢复策略来处理代码中的错误。
紧急模式
当解析器在语句中的任何位置遇到错误时,它会忽略语句的其余部分,不处理从错误输入到分隔符(例如分号)的输入。这是最简单的错误恢复方法,同时还可以防止解析器陷入无限循环。
语句模式
当解析器遇到错误时,它会尝试采取纠正措施,以便语句的其余输入允许解析器继续解析。例如,插入缺失的分号、用分号替换逗号等。解析器设计者必须小心谨慎,因为一次错误的更正可能会导致无限循环。
错误产生
编译器设计者知道代码中可能出现的一些常见错误。此外,设计者可以创建增强语法,作为在遇到这些错误时生成错误构造的产生式。
全局更正
解析器将手头的程序视为一个整体,并尝试找出程序的预期用途,并尝试找出最接近的匹配,即无错误匹配。当输入错误输入(语句)X 时,它会为某个最接近的无错误语句 Y 创建一棵解析树。这可能允许解析器在源代码中进行最小程度的更改,但由于此策略的复杂性(时间和空间),它尚未在实践中实现。
抽象语法树
解析树表示不易被编译器解析,因为它们包含比实际需要更多的细节。以以下解析树为例:

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

抽象树可以表示为:

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