[antlr-interest] How to get number of children in a tree?

Patrick Masselink patrick at patmas.net
Wed Jun 13 10:53:44 PDT 2007


Hi Tim,

As far as I know this isn't possible in the way you imagine. 

funcCall: ^(FUNC_CALL ID expr*

The rules matches expr nodes, for which it calls the expr rule. There is no 
way for the funcCall rule to know how many expr nodes are in the tree, just 
that there are 0 or more.

What you need to do is add a label to the expr token like this:
funcCall: ^(FUNC_CALL ID v+=expr*
You can then process $v, which is a list of expr rule results, using actions. 
I'm not sure what exacly happens to v when there's no expr, so be sure to 
check if v is actually defined, to prevent nullpointers.

Another way, which might give you more possibilities (like manually iterating 
expressions in reverse order), is to add custom code to the treeparser using 
the codeblocks like @members and @init. You can add code in the output 
language just as if it were a normal source file. This means you can call 
functions in custom class files you wrote. Like make an MyExpression object 
for each matched expr token, add those to MyExpressions hashmap and reverse 
iterate that.

A third and most finegrained solution is to use multiple passes for AST 
generation, a subject I have yet to touch myself.

Hopefully one of the ANTLR guru's can confirm the above, as I'm fairly new to 
ANTLR myself and not entirely sure about possibly simpler solutions.

Regards, Patrick Masselink


On Wednesday 13 June 2007 18:30:39 Tim Clark wrote:
> Hi all
>
> In my parser (output=AST) I have two rules like this:
>
> exprList : expr (COMMA! expr)*  |  // Empty ;
>
> funcCall : ID LPAREN exprList RPAREN -> ^(FUNC_CALL ID exprList) ;
>
> So a sentence fragment like "foobar()" produces ^(FUNC_CALL foo)
>
> and one like "foobar(1,2,3)" produces ^(FUNC_CALL foo 1 2 3)
>
>
> In a later pass, a tree grammar has this:
>
> funcCall: ^(FUNC_CALL ID expr*
>      {
>        within this action, how can I get hold of the number of expressions?
>        or, indeed, iterate over the expressions themselves (say in reverse
> order)?
>      }
> );
>
> I hope that's clear enough for someone to help :)
>
> Regards, Tim




More information about the antlr-interest mailing list