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 に答える