在一个antlr4语义谓词中,`_localctx`为空可能是什么原因?

时间:2016-01-22 12:11:32

标签: grammar antlr4 semantics predicate rule

我正在使用列表标签来收集令牌和语义谓词,以验证我的解析器语法中的序列。 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,我收到“没有可行的替代”错误。这些可能是因为失败的谓词保护相应的规则而没有给出替代方案。

有没有理由 - 我可能会出错 - 为什么_localctxnull

更新: this question的答案似乎表明在预测期间也会调用语义谓词。也许在预测期间,不会创建任何上下文,并且_localctx设置为null

1 个答案:

答案 0 :(得分:1)

谓词中_localctx的语义未定义。允许的行为包括但不限于以下内容(并且可能在任何发布期间发生变化):

  1. 无法编译(没有该名称的标识符)
  2. 使用错误的上下文对象
  3. 没有上下文对象(null)
  4. 要在谓词中引用当前规则的上下文,您需要使用$ctx代替。

    请注意,这同样适用于谓词中使用的规则参数,局部变量和/或返回值。例如,参数a不能引用为a,而必须改为$a