我正在使用列表标签来收集令牌和语义谓词,以验证我的解析器语法中的序列。 E.g。
line
:
(text+=WORD | text+=NUMBER)+ ((BLANK | SKIP)+ (text+=WORD | text+=NUMBER)+)+
{Parser.validateContext(_localctx)}?
(BLANK | SKIP)*
;
,其中
WORD: [\u0021-\u002F\u003A-\u007E]+; // printable ASCII characters (excluding SP and numbers)
NUMBER: [\u0030-\u0039]+; // printable ASCII number characters
BLANK: '\u0020';
SKIP: '\u0020\u0020' | '\t'; // two SPs or a HT symbol
用于验证Parser.validateContext
规则的line
部分将按此实现
private static final boolean validateContext(ParserRuleContext context) {
//.. other contexts
if(context instanceof LineContext)
return "<reference-sequence>".equals(Parser.joinTokens(((LineContext) context).text, " "));
return false;}
其中Parser.joinTokens
定义为
private static String joinTokens(java.util.List<org.antlr.v4.runtime.Token> tokens, String delimiter) {
StringBuilder builder = new StringBuilder();
int i = 0, n;
if((n = tokens.size()) == 0) return "";
builder.append(tokens.get(0).getText());
while(++i < n) builder.append(delimiter + tokens.get(i).getText());
return builder.toString();}
两者都放在语法文件开头的@parser::members
子句中。
我的问题是这样的:有时_localctx
引用是null
,我收到“没有可行的替代”错误。这些可能是因为失败的谓词保护相应的规则而没有给出替代方案。
有没有理由 - 我可能会出错 - 为什么_localctx
会null
?
更新: this question的答案似乎表明在预测期间也会调用语义谓词。也许在预测期间,不会创建任何上下文,并且_localctx
设置为null
。
答案 0 :(得分:1)
谓词中_localctx
的语义未定义。允许的行为包括但不限于以下内容(并且可能在任何发布期间发生变化):
要在谓词中引用当前规则的上下文,您需要使用$ctx
代替。
请注意,这同样适用于谓词中使用的规则参数,局部变量和/或返回值。例如,参数a
不能引用为a
,而必须改为$a
。