我有一个 ANTLR 语法,格式如下:
A - B: more,things
但是有时,A 或 B 可能会丢失,例如:
- B: more, things //Skip
A - : some, other, things //Skip
C - D: yet, more, things //Read this one and following
E - F: things
我希望 ANTLR 跳过这些行(缺少 - 的任一侧)并继续处理其余部分。
基本上,类似的东西
- B: more, things {if (!hasBothParts()) { continueAtNextLine();} };
从书中,我在适当的 Parser 块之后提供了一个@rulecatch 和这个捕获:
catch[RecognitionException re]{
reportError(re);
consumeUntil(input, NEWLINE);
input.consume();
}
编辑 2 - 我尝试这样做:
while (input.LA(1) != 6){
input.consume();
}
这按预期工作。6 对我来说是“NEWLINE”的令牌标识符。我不知道如何进行像 input.LA(1) != "\n" 或类似的比较。我知道这样做是不正确的,我只是在尝试。如果你知道正确的方法,请告诉我!:)
但这有效,与第一个循环不同。我怀疑consumeUntil 可能看不到隐藏频道上的NEWLINE。
NullPointer 似乎是由输入快进到 EOF 引起的,因此,树语法在执行 input.LT(1) 时遇到了 Null。
但是,这样做时,我的树语法中会出现 NullPointerException:
Exception in thread "main" java.lang.NullPointerException
at org.antlr.runtime.tree.BaseTreeAdaptor.isNil(BaseTreeAdaptor.java:70)
at org.antlr.runtime.tree.CommonTreeNodeStream.nextElement(CommonTreeNodeStream.java:93)
at org.antlr.runtime.misc.LookaheadStream.fill(LookaheadStream.java:94)
at org.antlr.runtime.misc.LookaheadStream.sync(LookaheadStream.java:88)
at org.antlr.runtime.misc.LookaheadStream.LT(LookaheadStream.java:119)
....
我想要的行为是让解析器跳过缺少组件的行并继续处理剩余的行。我认为树解析器应该不是问题?
ANTLR 书没有提到任何关于这个问题的内容。
另外,我认为ANTLR 错误恢复提到了这些方面的内容,但提供的解决方案相当复杂/丑陋,可以追溯到 2004 年。那么,有没有更好的方法在 ANTLR 中做这个相对简单的事情?
谢谢你。
编辑如果这有帮助,则错误是由生成的树语法中的这一行引起的:
retval.start = input.LT(1);
我认为,这是一无所有地被调用的。即 LT(1) 返回 Null,因为它跳过了。