1

私は次の文法を持っています:

rule: q=QualifiedName {System.out.println($q.text);};

QualifiedName
   :   
        i=Identifier { $i.setText($i.text + "_");}
        ('[' (QualifiedName+ | Integer)? ']')*
   ;


Integer
    : Digit Digit*
    ;

fragment
Digit 
    : '0'..'9'
    ;

fragment
Identifier
    :   (   '_'
        |   '$'
        |   ('a'..'z' | 'A'..'Z')
        )
        ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$')*
    ;

およびJavaのコード:

ANTLRStringStream stream = new ANTLRStringStream("array1[array2[array3[index]]]");
TestLexer lexer = new TestLexer(stream);
CommonTokenStream tokens = new TokenRewriteStream(lexer);
TestParser parser = new TestParser(tokens);
try {
    parser.rule();
} catch (RecognitionException e) {
    e.printStackTrace();
}

入力:array1[array2[array3[index]]]、各識別子を変更したい。出力が表示されることを期待していましたarray1_[array_2[array3_[index_]]]が、出力は入力と同じでした。

だから問題は、なぜこのsetText()方法がここで機能しないのかということです。

編集:

私はバートの答えを次のように修正しました:

rule: q=qualifiedName {System.out.println($q.modified);};

qualifiedName returns [String modified]
   :   
        Identifier
        ('[' (qualifiedName+ | Integer)? ']')*
        {
            $modified = $text + "_";
        }
   ;

Identifier
    :   (   '_'
        |   '$'
        |   ('a'..'z' | 'A'..'Z')
        )
        ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$')*
    ;

Integer
    : Digit Digit*
    ;

fragment
Digit 
    : '0'..'9'
    ;

ルールに一致する各トークンを変更したいqualifiedName。上記のコードを試してみましたが、入力array1[array2[array3[index]]]については出力が表示されることを期待していましたarray1[array2[array3[index_]_]_]_が、代わりに最後のトークンのみが変更されました:array1[array2[array3[index]]]_

どうすればこれを解決できますか?

4

1 に答える 1

1

setText(...)トークンが作成された後にのみ使用できます。このトークン再帰的に呼び出し、他のテキストを設定していますが、これは機能しません。QualifiedNameレクサールールの代わりにパーサールールを作成し、 fragmentbeforeを削除する必要がありますIdentifier

rule: q=qualifiedName {System.out.println($q.text);};

qualifiedName
   :   
        i=Identifier { $i.setText($i.text + "_");}
        ('[' (qualifiedName+ | Integer)? ']')*
   ;

Identifier
    :   (   '_'
        |   '$'
        |   ('a'..'z' | 'A'..'Z')
        )
        ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$')*
    ;

Integer
    : Digit Digit*
    ;

fragment
Digit 
    : '0'..'9'
    ;

これで、コンソールに次のように出力されます。array1_[array2_[array3_[index_]]]

編集

なぜあなたがそれをしたいのか分かりませんが、あなたは単にに書き直そうとしているようです。]これ]_は私が上に示したのと同じ方法で行うことができます:

qualifiedName
   :   
        Identifier
        ('[' (qualifiedName+ | Integer)? t=']' {$t.setText("]_");} )*
   ;
于 2012-05-01T10:22:08.610 に答える