对于我的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/