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