Antlr 有没有办法检测在操作中是否执行了可选的(?运算符)树语法规则?

Antlr 有没有办法检测在操作中是否执行了可选的(?运算符)树语法规则?,antlr,Antlr,如果变量$pathIndex转换为空,则返回0。当您访问属性时,ANTLR会生成pathIndex7=null?pathIndex7.index:0这会导致对象出现问题,因为它将我预设为-1的值作为错误标志更改为0。有两个选项: 1. 将代码放入可选路径索引中: $pathIndex.index 2. 使用布尔标志表示路径索引的存在(或不存在): rule : ^(PATH (id=IDENT{parts.add($id.text);})+ (pathIndex {/*pathIndex c

如果变量$pathIndex转换为空,则返回0。当您访问属性时,ANTLR会生成
pathIndex7=null?pathIndex7.index:0
这会导致对象出现问题,因为它将我预设为-1的值作为错误标志更改为0。

有两个选项:

1. 将代码放入可选路径索引中:

$pathIndex.index
2. 使用布尔标志表示路径索引的存在(或不存在):

rule
 : ^(PATH (id=IDENT{parts.add($id.text);})+ (pathIndex {/*pathIndex cannot be null here!*/} )? )
 ;
编辑 您还可以使
路径索引
不匹配任何内容,这样您就不需要在
路径
中将其设置为可选:

rule
@init{boolean flag = false;}
 : ^(PATH (id=IDENT{parts.add($id.text);})+ (pathIndex {flag = true;} )? )
   {
     if(flag) {
       // ...
     }
   }
 ;
请注意,表达式
$pathIndex.pathKey!=“
很可能计算为
false
。要比较Java中字符串的内容,请使用它们的
equals(…)
方法:

path[Scope sc] returns [Path p]
 : ^(PATH (id=IDENT{parts.add($id.text);})+ pathIndex)
   {
     // code
   }
 ;

pathIndex returns [int index, String pathKey]
@init {
  $index = -1;
  $pathKey = "";
}
 : ( /* some rules here */ )?
 ;
或者,如果
$pathIndex.pathKey
可以
null
,则可以通过执行以下操作绕过NPE:

!$pathIndex.pathKey.equals("")

更多的信息会有所帮助。但是,如果我理解正确,当输入中不存在索引值时,您要测试
$pathIndex.index==null
。这段代码使用pathIndex规则将整数$index返回到路径规则:

!"".equals($pathIndex.pathKey)
为了进行测试,我创建了以下简单的解析器和lexer规则:

 path
    : ^(PATH IDENT+ pathIndex?)
            { if ($pathIndex.index == null)
                    System.out.println("path index is null");
              else      
                System.out.println("path index = " + $pathIndex.index); }
    ;

 pathIndex returns [Integer index]
      : DIGIT 
            { $index = Integer.parseInt($DIGIT.getText()); }
      ;
当索引出现在输入中时,如路径a b c 5中所示,输出为:

path    : 'path' IDENT+ pathIndex? -> ^(PATH IDENT+ pathIndex?)
        ;
pathIndex : DIGIT
        ;

/** lexer rules **/
DIGIT  :   '0'..'9' ;
IDENT  : LETTER+ ;
fragment LETTER : ('a'..'z' | 'A'..'Z') ;
Tree = (PATH a b c 5)
path index = 5
当输入中不存在索引时,如路径a b c中的
中,输出为:

path    : 'path' IDENT+ pathIndex? -> ^(PATH IDENT+ pathIndex?)
        ;
pathIndex : DIGIT
        ;

/** lexer rules **/
DIGIT  :   '0'..'9' ;
IDENT  : LETTER+ ;
fragment LETTER : ('a'..'z' | 'A'..'Z') ;
Tree = (PATH a b c 5)
path index = 5

我已经为这个问题添加了更多信息。希望这将有助于使它更清楚。Thx,我现在理解并同意巴特的选择2是干净和简单的。谢谢巴特!选项2-在我看来是最干净、最简单的。@JeffreyGuenther,啊,是的,在树语法中,选项3不起作用(我删除了它)。