为什么使用 ANTLR4 创建正确的错误消息如此复杂?

Why is it so complicated to create proper error messages with ANTLR4?

我正在尝试在 Java 中编写命题逻辑程序 来确定公式是否合式。显然,ANTLR 是一个不错的选择,因为我可以在一个 CFG 中编写所有规则。所有这一切都很好,而且我的语法工作得很好(它检测公式何时格式正确或格式不正确)。但是,这个程序是针对该主题的初学者的,我希望能够告诉他们输入公式时哪里出错了。

如果我输入公式 (A -> B,解析器会识别出它的格式不正确,因为它缺少右括号。但是,它生成的错误至少可以说是乏善可陈:line 1:5 no viable alternative at input '(A -> B'(这是从 vanilla ANTLR 稍作修改以包括行号 iirc)。我见过人们使用 notifyErrorListener(...) 在语法 中嵌入规则,但这意味着我的所有规则都必须是非左递归的。例如,我有规则

propImpRule: OPEN_PAREN propWff IMPLIES propWff CLOSE_PAREN;
propImpRule: OPEN_PAREN propWff IMPLIES propWff {notifyErrorListener("Missing ')'");};

如果我想对左括号做同样的事情(或两者都做),我不能,因为 ANTLR 的解析器是如何工作的(我真的不想经历这样的麻烦将每个规则都转换为非左递归。另外,将规则嵌入语法中似乎很麻烦,但也是解决实际问题的一种方法。

我试图遵循过去 Whosebug answers 中的示例并阅读 ANTLR manual/documentation,但没有任何东西真正提供我想要或需要的东西(或足够的文档来做到这一点)。谁能指出我正确的方向?谢谢!

标准的“没有可行的选择”消息还将列出预期的字符。该信息也可用于生成您自己的消息。

话虽这么说,我怀疑仍然不能满足您的需求。

通用工具很难为初学者生成有用的信息。

一个可能有帮助的建议:

继续编写与您可能预期的错误匹配的解析器规则。这有点违反直觉,因为大多数人都希望语法只识别有效的结构。但是,这并不是真正的“规则”。您还可以识别无效的构造,然后,当它们出现在您的解析树中时,您可以添加语义处理以提供您愿意制作的“漂亮”和信息丰富的错误消息。