2013-10-15 8 views
14

一般的に解析ツリーを横断しながらANTLR4で代替ラベルにアクセスするにはどうすればよいですか?あるいは、ANTLR3の^オペレータの機能を複製する方法はありますか?一般的に解析ツリーを横断しながら、ANTLR4の代替ラベルにアクセスするにはどうすればよいですか?

私は、単純な方法論(代替ラベル付きのプロダクションの命名など)に準拠したANTLR4文法のために、ASTのきれいなプリンタを作成しようとしています。ので、私は効果的plusminus制作に名前を付けることができません

int_expression 
    : int_expression '+' int_expression # plus 
    | int_expression '-' int_expression # minus 
    | raw_int       # int_literal 
    ; 
raw_int 
    : Int 
    ; 
Int : [0-9]+ ; 

:私は次のような文法を考えると、かなり(int_expression (plus (int_literal 3) (int_literal 5)))、または似たよう3 + 5のような用語を印刷できるようにしたいのですがそれらを独自のプロダクションに引き出すと、ツールはルールが相互に左回帰的であると不満を持ちます。私はそれらを引き出すことができない場合、どのようにこれらの作品の名前を与えることができますか?

注1:私は特別な作品(制作はraw_のように、特別な接頭辞で始まる)に「良い」の端末(例えば、上記Int)を置くことによって、方法論+引数を取り除くことができました。それで親作品の名前が "raw_ ..."で、他のものはすべて省略した端末だけを印刷することができました。これは、出力に35を維持しながら、+を取り除くのに役立ちました。これは、ANTLR3の!で行うことができます。

注2:特定の美しいプリンタを作成したり、特定の言語のプロダクションごとにアクションを使用することができますが、ANTLR4を使用して様々な言語のASTを解析して生成したいと考えていますそのようなシンプルでかわいいプリンタを一般的に書くことができるはずです。言い換えれば、私はASTを手に入れることだけを気にしています。ちょうどASTを取得するために、ちょうどきれいなプリンターで各文法を邪魔する必要はありません。おそらく私はANTLR3に戻るべきでしょうか?

答えて

1

さまざまなコンテキストオブジェクトの名前を取得するために、ネストされたビジタークラスを持つリスナーの実装としてprettyプリンタを実装することをお勧めします。

private MyParser parser; // you'll have to assign this field 
private StringBuilder builder = new StringBuilder(); 

@Override 
public void enterEveryRule(@NotNull ParserRuleContext ctx) { 
    if (!builder.isEmpty()) { 
     builder.append(' '); 
    } 

    builder.append('('); 
} 

@Override 
public void visitTerminalNode(@NotNull TerminalNode node) { 
    // TODO: print node text to builder 
} 

@Override 
public void visitErrorNode(@NotNull TerminalNode node) { 
    // TODO: print node text to builder 
} 

@Override 
public void exitEveryRule(@NotNull ParserRuleContext ctx) { 
    builder.append(')'); 
} 

protected String getContextName(@NotNull ParserRuleContext ctx) { 
    return new ContextNameVisitor().visit(ctx); 
} 

protected class ContextNameVisitor extends MyParserBaseVisitor<String> { 
    @Override 
    public String visitChildren() { 
     return parser.getRuleNames()[ctx.getRuleIndex()]; 
    } 

    @Override 
    public String visitPlus(@NotNull PlusContext ctx) { 
     return "plus"; 
    } 

    @Override 
    public String visitMinus(@NotNull MinusContext ctx) { 
     return "minus"; 
    } 

    @Override 
    public String visitInt_literal(@NotNull MinusContext ctx) { 
     return "int_literal"; 
    } 
} 
+0

私は、各言語用の特別なかわいいプリンタを作成せずにこれを行う一般的な方法を探しています。これを行う方法はありませんか?ユーザーの観点からは、なぜ代替ラベルが存在するのか理解できません。 –

関連する問題