1

I'm trying to allow my grammar to support variable declarations where you don't have to repeat the variable type such as int i = 3, j = 4, k;

The problem I have is with my generated tree. This is my rule...

varDeclaration
:   type ID (ASSIGN expression)? (COMMA ID (ASSIGN expression)?)* SEMICOLON -> ^(VAR_DECL type ID expression?)+;

It successfully splits apart the declaration into separate variable declarations, but it is repeating the expression tree for all of them.

So for int x = 4, y = 5, they both have value 4 in the AST.

Any help with an operator or something I can use would be appreciated.

Seki
  • 11,135
  • 7
  • 46
  • 70
David James Ball
  • 903
  • 10
  • 26

1 Answers1

2

ANTLR cannot make a distiction between the expressions. AFAIK, you'll have to create a "helper" rule.

A quick demo:

options {
  output=AST;
  ASTLabelType=CommonTree; // <- important, otherwise `$t.tree` returns an Object instead of a CommonTree
}

tokens {
  VAR_DECLS;
  VAR_DECL;
}

// ...

varDeclaration 
 : t=type assign[$t.tree] (COMMA assign[$t.tree])* SEMICOLON -> ^(VAR_DECLS assign+)
 ;

assign[CommonTree type]
 : ID (ASSIGN expression)? -> ^(VAR_DECL {type} ID expression?)
 ;

// ...

Now your input will produce the following AST:

enter image description here

EDIT

Note that the type-node will be the same for all VAR_DECL nodes. This might not be an issue (since this node is most probably not going to change), but if you want each VAR_DECL node to have its own instance of a type node, do something like this:

assign[CommonTree type]
 : ID (ASSIGN expression)? -> ^(VAR_DECL {new CommonTree(type)} ID expression?)
 ;

Or something similar. You can use plain target code inside the { and } in the rewrite rule.

Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
  • Thank you for your help Bart. The weird thing is I have passed trees between rules before, but my mind had gone blank on this example. Thank you for clearing up my confusion. – David James Ball Sep 10 '12 at 20:57
  • I now have another problem in that the type node is being shared rather than being copied for each subtree. I'm using a custom node type, but that derives from CommonTree so I doubt that is the problem. Compiling 'real a = 0, b = 1, c;' gives me this AST... https://dl.dropbox.com/u/46743877/AST.png – David James Ball Sep 10 '12 at 21:17
  • How to do it in antlr4, where it doesn't support rewrite operator? – Sriteja Sugoor Nov 25 '20 at 20:28
  • @SritejaSugoor you don't. There isn't support for it in ANTLR4. See: https://stackoverflow.com/questions/29971097/how-to-create-ast-with-antlr4 and https://github.com/antlr/antlr4/issues/2428 – Bart Kiers Nov 25 '20 at 20:33
  • So we can't do it in grammar, and we have to do it during AST construction. This is what you are saying? – Sriteja Sugoor Nov 25 '20 at 20:40
  • No, there is no "during AST construction" phase. ANTLR creates parse trees. You can create your own AST once ANTLR gives you the parse tree. So the whole AST creation is done outside of ANTLR. – Bart Kiers Nov 25 '20 at 20:47