With the help of this SO question How to create AST with ANTLR4? I was able to create the AST Nodes, but I'm stuck at coding the BuildAstVisitor
as depicted in the accepted answer's example.
I have a grammar that starts like this:
mini: (constDecl | varDef | funcDecl | funcDef)* ;
And I can neither assign a label to the block (antlr4 says label X assigned to a block which is not a set
), and I have no idea how to visit the next node.
public Expr visitMini(MiniCppParser.MiniContext ctx) {
return visitConstDecl(ctx.constDecl());
}
I have the following problems with the code above: I don't know how to decide whether it's a constDecl
, varDef
or any other option and ctx.constDecl()
returns a List<ConstDeclContext>
whereas I only need one element for the visitConstDecl
function.
edit:
More grammar rules:
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]+ ;
// ...
I'm still not entirely sure on how to implement the BuildAstVisitor
. I now have something along the lines of the following, but it certainly doesn't look right to me...
@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());
}
*
around your expression, which means each item can occur any number of times, or never at all. That's whyctx.constDecl()
returns a list, which contains all theconstDecl
child nodes. You can only assign labels to top-level alternative elements (ierule: foo # labelA | bar # labelB ;
), that's why ANTLR refuses that. I don't really know what's the solution here since I don't know what you're trying to do exactly, but you'll either have to remove that star to get exactly one branch to match, or visit each child node instead of just the first one. – MeatheadvisitMini
function return then? In your example you don't have the problem of having to visit a list ofnodes
. – Listel