4
path[Scope sc] returns [Path p]
@init{
List<String> parts = new ArrayList<String>();
}
    :   ^(PATH (id=IDENT{parts.add($id.text);})+ pathIndex? )
{// ACTION CODE
 // need to check if pathIndex has executed before running this code.
    if ($pathIndex.index >=0 ){
        p = new Path($sc, parts, $pathIndex.index);
    }else if($pathIndex.pathKey != ""){
        p = new Path($sc, parts, $pathIndex.pathKey);
}
;

有没有办法检测 pathIndex 是否被执行?在我的操作代码中,我尝试测试 $pathIndex == null,但 ANTLR 不允许您这样做。ANTLRWorks 给出了一个语法错误,上面写着“在规则范围内缺少属性访问:pathIndex。”

我需要这样做的原因是因为在我的操作代码中我​​这样做:

$pathIndex.index

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

4

2 回答 2

4

有几个选项:

1

将您的代码放在可选的 pathIndex 中:

rule
 : ^(PATH (id=IDENT{parts.add($id.text);})+ (pathIndex {/*pathIndex cannot be null here!*/} )? )
 ;

2

使用布尔标志来表示 的存在(或不存在)pathIndex

rule
@init{boolean flag = false;}
 : ^(PATH (id=IDENT{parts.add($id.text);})+ (pathIndex {flag = true;} )? )
   {
     if(flag) {
       // ...
     }
   }
 ;

编辑

您也可以pathIndex不匹配任何内容,这样您就不需要在内部将其设为可选path

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 */ )?
 ;

PS。意识到表达式$pathIndex.pathKey != ""很可能会计算为false。要比较 Java 中字符串的内容,请改用它们的equals(...)方法:

!$pathIndex.pathKey.equals("")

或者如果$pathIndex.pathKey可以null,您可以通过以下方式规避 NPE:

!"".equals($pathIndex.pathKey)
于 2012-08-17T06:11:54.043 回答
0

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

 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()); }
      ;

为了测试,我创建了这些简单的解析器和词法分析器规则:

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

/** lexer rules **/
DIGIT  :   '0'..'9' ;
IDENT  : LETTER+ ;
fragment LETTER : ('a'..'z' | 'A'..'Z') ;

当输入中存在索引时,如 中path a b c 5,输出为:

Tree = (PATH a b c 5)
path index = 5

当输入中不存在索引时,如 中path a b c,输出为:

Tree = (PATH a b c)
path index is null
于 2012-08-17T06:26:18.240 回答