ANTLR 报告错误,我认为它应该能够通过回溯解决输入

Posted

技术标签:

【中文标题】ANTLR 报告错误,我认为它应该能够通过回溯解决输入【英文标题】:ANTLR reports error and I think it should be able to resolve input with backtracking 【发布时间】:2012-04-07 15:47:39 【问题描述】:

我有一个简单的语法,大部分情况下都有效,但在某个地方它会报告错误,我认为它不应该,因为它可以使用回溯来解决。

这是有问题的部分。

command: object message_chain;
object: ID;
message_chain: unary_message_chain keyword_message?
             | binary_message_chain keyword_message?
             | keyword_message;
unary_message_chain: unary_message+;
binary_message_chain: binary_message+;
unary_message: ID;
binary_message: BINARY_OPERATOR object;
keyword_message: (ID ':' object)+;

这是简化版本,对象更复杂(它可以是其他命令的结果,原始值等,但那部分工作正常)。问题出在message_chain,在第一个替代方案中。对于像obj unary1 unary2 这样的输入,它可以正常工作,但是对于像obj unary1 unary2 keyword1:obj2 这样的输入,它会尝试将keyword1 匹配为一元消息,并在到达: 时失败。我认为这种情况解析器会回溯并认为存在: 并识别出这是关键字消息。

如果我将关键字消息设为非可选,它可以正常工作,但我需要关键字消息是可选的。

如果关键字消息在第二个备选(binary_message)和第三个备选(只是keyword_message)中,解析器会找到它。所以这样的事情会产生很好的效果:1 + 2 + 3 Keyword1:Value

我错过了什么?回溯在选项中设置为 true,并且在相同语法的其他情况下可以正常工作。

谢谢。

【问题讨论】:

【参考方案1】:

这并不是 PEG 式回溯的真正案例,因为一旦失败,它只会在未完成的推导中返回到决策点。对于输入obj unary1 unary2 keyword1:obj2,具有单个标记前瞻,keyword1 可以被unary_message_chain 使用。失败可能不会发生在keyword_message 之前,接下来要尝试的是message_chain 的第二种选择,即binary_message_chain,因此会丢失正确的解析。

但是,由于该语法是 LL(2),因此应该可以扩展前瞻以避免在 unary_message_chain 中使用 keyword1。您是否尝试过明确设置k=2,而不回溯?

【讨论】:

感谢您的回复。我的其余语法需要回溯,所以我无法将其关闭(antlr 不会编译语法),但您的回答启发了我重做语法,我做到了。现在它不需要回溯,问题的问题就消失了(我没有在代码中的任何地方明确设置k)。所以,这个答案确实解决了我的问题。谢谢:)

以上是关于ANTLR 报告错误,我认为它应该能够通过回溯解决输入的主要内容,如果未能解决你的问题,请参考以下文章

解析 Java 源代码

如何使用回溯算法获得所有可能的解决方案?

回溯算法卡住了

Chrome 似乎报告了错误的错误行

具有回溯的数独求解器不能总是检测到多个解决方案

如何最好地实现简单的崩溃/错误报告?