Antlr解析器运行异常



对于我的anltr配置,解析器有这种奇怪的行为。到目前为止,这是预期的工作,但现在我们发现了一些额外的情况,当鹿角压碎。

这是词法分析器

lexer grammar RuleLexer;

WORD: (DIGIT | LOWERCASE | UPPERCASE)+;
ANY_SPACE: (SINGLE_SPACE | NEW_LINE)+;
WS: [rt]+ -> skip;
CONDITION_OPEN: '<';
CONDITION_CLOSE: '>';
AND: '&';
OR: '/';
fragment LOWERCASE: [a-z];
fragment UPPERCASE: [A-Z];
fragment DIGIT: [0-9];
fragment SINGLE_SPACE: ' ';
fragment NEW_LINE: [n];

解析器:

parser grammar RuleParser;
options {
tokenVocab = RuleLexer;
language = Java;
}
rules: term+ EOF;
term:
constraint EOF                                                      # statement
| fi = constraint CONDITION_OPEN then = constraint CONDITION_CLOSE  # conditional;
constraint:
ANY_SPACE? (element) ANY_SPACE? (
operation constraint
)?;
operation: AND | OR;
element: WORD;

下面是一些输入和结果的图片:001/002/003→工作正常:001/002/003

但现在奇怪的部分出现了。如果我添加另一个运算符/或&在输入的末尾001/002/003/→是行不通的。001/002/003/

如果我有一个条件作为输入,解析器按预期工作。它验证输入并识别额外的操作:001 & lt; 002/003>/→工作001 & lt; 002/003>/我希望第二个输入像第三个一样被解释。

我发现的最后一个问题是当我缺少约束之间的操作时。001/002 003/004001/002 003/004

我想知道为什么在不工作的情况下,我有EOF和null的结果。我希望图片的分辨率足够好。

使用constraint EOF # statement替代方案,您只匹配约束如果它是整个输入流中唯一的东西。

你等同地对待空格和换行,所以,你打算在输入流中允许多个约束条件吗?如果是这样,您需要删除该规则备选项上的EOF

由于您已将/定义为仅在后跟另一个约束时可用的OR操作符,因此在输入结束时无效。因此,您得到no viable alternative错误消息。看来你会更喜欢得到extraneous input '/' expecting ...错误。

您可以在statement备选项上获得EOF消息(对于一些输入),因为ANTLR能够使用它的一些错误恢复策略。extraneous input错误是ANTLR试图做的更优雅的错误恢复(有点像"嗯……我可以理解,如果我忽略这个标记)。然而,ANTLR并不总是能够尝试这些错误恢复。(我认为我知道他们什么时候会开火,什么时候不会,但是不能修改这个语法来利用我认为的的工作方式。我敢肯定,某些错误恢复策略是否适用,涉及到相当复杂的内部问题。

对术语规则进行如下修改:

term:
fi = constraint (
CONDITION_OPEN then = constraint CONDITION_CLOSE
)?; 

我得到line 1:12 mismatched input '<EOF>' expecting {WORD, ANY_SPACE}而不是no viable alternative错误信息。这似乎是一个更具体的错误信息。

也就是说,这似乎是一个相当精简的语法,这种避免替代的更改在更大的范围内可能不实用。

最后,很可能出现no viable alternative错误消息。

您也可以考虑实现自己的错误恢复策略,但这通常用于跳过某些策略以避免开销。添加更多的逻辑可能是一个"专家"。水平努力。

注意:我刚刚在ANTLR书中注意到的一个相当聪明的选择是,如果你有某些常见错误(比如,说后面的'/'),你可以添加一个规则来专门检测错误。

constraint:
ANY_SPACE? (element) ANY_SPACE? (operation constraint)?
| ANY_SPACE? (element) ANY_SPACE? operation {notifyErrorListeners("operation without following constraint");
};

给出:line 1:12 operation without following constraint用于输入001/002/003/

相关内容

  • 没有找到相关文章

最新更新