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 报告错误,我认为它应该能够通过回溯解决输入的主要内容,如果未能解决你的问题,请参考以下文章