2017-05-16 3 views
0

このSOの質問の助けを借りてHow to create AST with ANTLR4?私はASTノードを作成することができましたが、受け入れられた答えの例に示されているようにBuildAstVisitorをコーディングしています。ANTLR4 ASTの作成 - AstVistorの作成方法

私はこのように始まり文法があります。

mini: (constDecl | varDef | funcDecl | funcDef)* ; 

そして、私は(antlr4がlabel X assigned to a block which is not a setを言う)のブロックにラベルを割り当てることはできませんどちらも、私は次のノードを訪問するか見当がつかないを。

public Expr visitMini(MiniCppParser.MiniContext ctx) { 
    return visitConstDecl(ctx.constDecl()); 
} 

私は上記のコードでは、次の問題がある:私はそれが私が唯一visitConstDecl機能のための一つの要素を必要とするのに対し、constDeclvarDefまたは他のオプションとctx.constDecl()List<ConstDeclContext>を返すのかどうかを判断する方法がわかりません。

編集:

もっと文法規則:

mini: (constDecl | varDef | funcDecl | funcDef)* ; 

//-------------------------------------------------- 

constDecl: 'const' type ident=ID init ';' ; 
init:  '=' (value=BOOLEAN | sign=('+' | '-')? value=NUMBER) ; 
// ... 

//-------------------------------------------------- 

OP_ADD: '+'; 
OP_SUB: '-'; 
OP_MUL: '*'; 
OP_DIV: '/'; 
OP_MOD: '%'; 

BOOLEAN  : 'true' | 'false' ; 
NUMBER   : '-'? INT ; 
fragment INT : '0' | [1-9] [0-9]* ; 
ID    : [a-zA-Z]+ ; 
// ... 

私はまだBuildAstVisitorを実装する方法については、完全にはよく分かりません。 visitVarDef()visitConstDecl()(あなたは、個々のサブルールを取得したい場合は、彼らのためにvisitXXX機能を実装

@Override 
public Expr visitMini(MiniCppParser.MiniContext ctx) { 
    for (MiniCppParser.ConstDeclContext constDeclCtx : ctx.constDecl()) { 
    visit(constDeclCtx); 
    } 
    return null; 
} 

@Override 
public Expr visitConstDecl(MiniCppParser.ConstDeclContext ctx) { 
    visit(ctx.type()); 
    return visit(ctx.init()); 
} 
+0

あなたは式の周りにクリーンな星座 '*'を置いています。これは、各項目が何度も出現することがあり、まったく出現しないことを意味します。そのため、 'ctx.constDecl()'は 'すべての* constDecl'子ノードを含むリストを返します。最上位の代替要素(つまり、 'rule:foo#labelA | bar#labelB;')にのみラベルを割り当てることができます。そのため、ANTLRはそれを拒否しています。私は実際にあなたが何をしようとしているのか分からないので、ここでの解決策は実際にはわかりませんが、*星を1つだけ見つけて一致させるか、各子ノードを訪問する必要があります最初のものの代わりに。 –

+0

もし私が各子ノードを訪問するならば、 'visitMini'関数は何を返しますか?あなたの例では、 'nodes'のリストにアクセスする必要はありません。 – Johannes

答えて

1

...私は今、次の線に沿って何かを持っているが、それは確かに右に私には見えません。等)を使用してください。入力に実際に一致するものがある場合にのみ呼び出されます。したがって、発生のチェックを行う必要はありません。

+0

私はビジターを実装する場合、ノードを自分で訪問する必要はありませんか?私はこれを行う理由は、私はそれからASTを構築する自分自身をCSTを横断することができると思った。したがって、私は 'visitMini()'関数を実装する必要があります。これは、入力された最初のルールになるためです。申し訳ありませんが、私はこれが間違っている! – Johannes

+0

私は間違いを見つけました。私は 'XBaseVisitor'を拡張するのではなく、' Visitor'を実装していました。 – Johannes

関連する問題