错误恢复

在课程讲义 Lecture04 中,我们介绍了应急恢复和短语层恢复的方法。这里,我们提出一种介于二者之间的错误恢复方法:

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

  • 另外,当匹配终结符失败时,只报错,但不消耗此匹配失败的终结符,而是将它保留在剩余输入串中。这部分的处理已经在 matchToken 函数中实现了。

一般来说,错误恢复是一个非常难的问题。上述方法显然也会有在一些 Decaf 程序上产生误报。

避免重复报错

由于实现的原因,本框架的 parseSymbol 函数有可能会多次连续调用 issue 方法报告同样的语法错误 (DecafError)。 为了避免输出重复的错误信息,在 LLParser 类中,我们重载了 issue 方法,在添加错误之前先检查它是不是刚添加过了:

@Override
public void issue(DecafError error) {
    if (!errors.isEmpty()) {
        var last = errors.get(errors.size() - 1);
        if (error.toString().equals(last.toString())) { // ignore
            return;
        }
    }

    super.issue(error);
}

Last updated