[英]ANTLR turns useful error messages into "no viable alternative" when I try to add custom error messages
我正在为一种深奥的编程语言编写 ANTLR 语法。 我正在尝试添加在编写某些 forms 语法时将输出的自定义错误消息。
这是一个MCVE :
grammar Foo;
OPEN_BRACE: '{';
CLOSE_BRACE: '}';
SEMI_COLON: ';';
PERIOD: '.';
WS: ' ' -> skip;
NOOP: 'noop';
statements
: NOOP
| NOOP SEMI_COLON statements
// other kind of statements
;
program
: OPEN_BRACE
statements
CLOSE_BRACE
EOF
假设我想SEMICOLON
如果program
以分号结尾或大括号中没有statements
时自定义错误消息。 在这个答案之后,我添加了一些错误替代方案:
program
: OPEN_BRACE
statements
CLOSE_BRACE
EOF
| invalidPrograms
;
invalidPrograms
: OPEN_BRACE
statements
CLOSE_BRACE
SEMI_COLON
EOF { notifyErrorListeners($SEMI_COLON, "program must not end with semicolon!", null); }
| OPEN_BRACE
CLOSE_BRACE
EOF { notifyErrorListeners($OPEN_BRACE, "program must have at least one statement!", null); }
;
然后我使用ErrorListener
来收集解析器和词法分析器生成的所有错误。
这是可行的,但它也会使 ANTLR 生成的其他默认错误消息全部变成单个“没有可行的替代方案”消息。 例如,如果我尝试解析语法无效:
{noop
在我添加错误选项之前,它会产生一个非常有用的错误消息:
line 1:5 missing '}' at '<EOF>'
或者如果我写
{noop.}
错误消息说:
line 1:5 extraneous input '.' expecting '}'
这是相当描述性的。 但是,如果我添加错误替代项,错误消息将变为:
line 1:5 no viable alternative at input...
这是不可取的。 我怎样才能保留好的错误消息,同时仍然使用错误替代方案?
通过添加这些规则,您无意中破坏了 ANTLR 错误报告和错误恢复的某些功能(通过向解析器添加“有效”规则,特别是通过使<EOF>
有效)。
通常,您尝试添加的两个示例通常都被视为语义错误。 最好通过使用侦听器或访问者评估解析器树来在您自己的代码中处理这些问题。
引入规则以匹配特定的错误语法以促进生成更用户友好的错误消息可能是有效的用途,但您必须小心避免像这样破坏解析器错误恢复。
通常,您需要一个相对“接受”但在正确解释您的输入时明确的解析器。 然后,您可以从该解析树中查找已识别的语义错误。 (将“尽可能多地”放入语法中是一种常见的诱惑,但这可能会适得其反(如您所见))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.