匹配 Antlr 中不需要的标记以进行错误报告

matching an unwanted token in Antlr for error reporting

我有这样的规则(过于简单但仅供演示):

matches :
        MATCHES
    ;

但有时我在我的代码中错误地使用了 'matching' 而不是 'matches',我希望它能以一个很好的错误信息爆炸。我以前接触过这种类型的结构

matches :
        MATCHES
    |
        MATCHING
        {
            err("Wrong keyword, use MATCHES not MATCHING");
        }
    ;

但这需要进行 lex 符号匹配,这会干扰词法分析器。我想匹配 MATCHING 而根本不创建任何 lex 符号。

有什么想法吗?

很可能,由于没有 matching 的词法分析器规则,词法分析器会将其识别为类似 IDENTIFIER 的东西(假设您的语法有这样的规则)。

考虑到这一点,一种选择可能是让 Lexer 将“匹配”识别为 IDENTIFIER。然后你可以用 IDENTIFIER 和一个需要 IDENTIFIER == “匹配”的语义谓词来写这个替代。然后,在侦听器中,如果遇到传递语义 tic 谓词的上下文,您可以添加自己的自定义错误消息。

类似于:(未经测试的代码,因此可能会出现小错误)

matches :
        MATCHES
    |
        id=IDENTIFER { $id.text == "matching" }?
    ;

如果所有输入都没有被识别和标记化,您就不可能真正成功地进行解析。 (未能对其进行标记化,将导致错误消息。ANTLR 将通过插入或忽略允许其继续(并产生错误)的标记来尝试错误恢复。

另一种可能的方法来完成你想要的,带有特定的错误信息;您也许可以使用自定义 ErrorListener 并覆盖错误消息(但是,检测到错误时识别上下文可能很棘手。)