0

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());
}
Community
  • 1
  • 1
Johannes
  • 1,249
  • 3
  • 17
  • 33
  • You've put a Kleene star `*` around your expression, which means each item can occur any number of times, or never at all. That's why `ctx.constDecl()` returns a list, which contains *all* the `constDecl` child nodes. You can only assign labels to top-level alternative elements (ie `rule: 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. – Lucas Trzesniewski May 16 '17 at 21:43
  • If I were to visit each child node, what would the `visitMini` function return then? In your example you don't have the problem of having to visit a list of `nodes`. – Johannes May 17 '17 at 09:48

1 Answers1

1

If you want to get the individual subrules then implement the visitXXX functions for them (visitConstDecl(), visitVarDef() etc.) instead of the visitMini() function. They will only be called if there's really a match for them in the input. Hence you don't need to do any checks for occurences.

Mike Lischke
  • 48,925
  • 16
  • 119
  • 181
  • If I implement the visitor, don't I have to visit the nodes myself? I thought the reason to do this is so that I can traverse the CST myself, building an AST from it. Hence, I do need to implement the `visitMini()` function, because it would be the first rule that's entered. Sorry if I got this wrong! – Johannes May 17 '17 at 09:47
  • I found my mistake: I was implementing the `Visitor` rather than extending the `XBaseVisitor`. – Johannes May 17 '17 at 11:13