_localctx 在 antlr4 语义谓词中为 null 的原因可能是什么?
What could be a reason for `_localctx` being null in an antlr4 semantic predicate?
我正在使用列表标签来收集标记和语义谓词来验证我的解析器语法中的序列。例如
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
而我收到 "no viable alternative" 错误。这些可能是因为失败的谓词保护了各自的规则而没有给出替代方案。
为什么 _localctx
会是 null
是有原因的吗?
更新: this question 的答案似乎表明在预测期间也会调用语义谓词。也许在预测期间没有创建上下文并且 _localctx
设置为 null
.
谓词中 _localctx
的语义未定义。允许的行为包括但不限于以下(并且可能在任何发布期间更改):
- 编译失败(没有具有该名称的标识符)
- 使用了错误的上下文对象
- 没有上下文对象(空)
要从谓词中引用当前规则的上下文,您需要改用 $ctx
。
请注意,这同样适用于谓词中使用的规则参数、局部变量、and/or return 值。例如,参数 a
不能引用为 a
,而必须是 $a
.
我正在使用列表标签来收集标记和语义谓词来验证我的解析器语法中的序列。例如
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
而我收到 "no viable alternative" 错误。这些可能是因为失败的谓词保护了各自的规则而没有给出替代方案。
为什么 _localctx
会是 null
是有原因的吗?
更新: this question 的答案似乎表明在预测期间也会调用语义谓词。也许在预测期间没有创建上下文并且 _localctx
设置为 null
.
谓词中 _localctx
的语义未定义。允许的行为包括但不限于以下(并且可能在任何发布期间更改):
- 编译失败(没有具有该名称的标识符)
- 使用了错误的上下文对象
- 没有上下文对象(空)
要从谓词中引用当前规则的上下文,您需要改用 $ctx
。
请注意,这同样适用于谓词中使用的规则参数、局部变量、and/or return 值。例如,参数 a
不能引用为 a
,而必须是 $a
.