Tag: 错误恢复

如何阻止ANTLR抑制语法错误?

所以我用Java编写了一个使用ANTLR的编译器,我对它如何处理错误感到有些困惑。 默认行为似乎是打印错误消息,然后通过令牌插入等方式尝试从错误中恢复并继续解析。 我原则上喜欢这个; 这意味着(在最好的情况下)如果用户提交了多个语法错误,他们将在每个错误中获得一条消息,但它会提到所有错误,而不是强制它们重新编译以发现下一个错误。 默认错误消息可以用于我的目的。 当它读完所有令牌时就会出现问题。 当然,我使用ANTLR的树构造函数来构建抽象语法树。 虽然解析继续通过语法错误很好,所以用户可以看到所有错误,一旦完成解析我想得到一个exception或某种指示输入在语法上没有效果; 这样我就可以停止编译并告诉用户“抱歉,修复语法错误,然后重试”。 我不想要的是它根据它认为用户试图说的内容吐出一个不完整的AST,并继续编译的下一个阶段,没有任何迹象表明出现任何问题(除了错误信息之外)到控制台,我看不到)。 但默认情况下,确实如此。 最终的ANTLR参考提供了一种在检测到语法错误时立即停止解析的技术:覆盖mismatch和recoverFromMismatchedSet方法以抛出RecognitionException ,并添加@rulecatch操作来执行相同操作。 这似乎失去了从解析错误中恢复的好处,但更重要的是,它只能部分工作。 如果缺少必要的标记(例如,如果二元运算符只在其一侧有一个表达式),它会按预期抛出exception,但如果添加了一个无关的标记,ANTLR会插入它认为属于的标记并继续以其快乐的方式,生成一个AST,除了控制台消息外没有任何语法错误的迹象。 (更糟糕的是,它插入的令牌是EOF ,所以文件的其余部分甚至都没有被解析。) 我确定我可以解决这个问题,例如,向解析器添加类似isValid字段的内容并覆盖方法并添加操作,以便在解析结束时,如果出现任何错误,它会抛出exception。 但有更好的方法吗? 我无法想象我想要做的事情在ANTLR用户中是不寻常的。