[antlr-interest] How does one handle variable number of function parameters?

Martin Probst mail at martin-probst.com
Tue Nov 29 06:48:18 PST 2005


> Yes, I think this is where I need help. I've currently got the
> function defined as this (identifier piece, of course):
> 
> term
> 	: NUMBER
> 	| LPAREN! expression RPAREN!
> 	| IDENTIFIER^ ( LPAREN! expression (COMMA! expression)* RPAREN! )?
> 	;
> 
> I see:
> 1) You've made the LPAREN the root - why? I figured I'd have the
> IDENTIFIER as the root with the expressions as the children. Probaby
> doesn't matter if I get the tree parser setup right...?

Yes, that's a matter of style. Just make sure you can easily identify a
function call as a whole, plus the single arguments (and can make out
the difference between a list of arguments and an argument that is a
list, if your language allows that).

> 
> 2) What the heck does this mean? I've seen it mentioned in the ANTLR
> documentation, but I didn't grok it.
>     args  :  expr ( COMMA! expr )* { ## = #( #[ARGLIST,"ARGLIST"], ## ); } ;

## is the AST subtree of the current rule, e.g. in "foo: bar;" it's the
same as #foo. The statement means: create a new Tree "#( ... )" which
roots at a newly created node of type ARGLIST "#[ ... ]" and append as
it's children the current tree "##". Then assign this new AST to the
current tree "## = ...". This basically inserts ARGLIST as a new root to
the current AST, very handy.

> 
> 3) I'd like to have the parenthesis optional. Do I want to have two
> definitions to pick up the parenthesis in the parser grammar file?
> 	| (IDENTIFIER LPARN) => IDENTIFIER^ LPAREN! expression (COMMA!
> expression)* RPAREN!
> 	| IDENTIFIER^

What happens with this:
> myfunc (foo), bar
Is that FUNCTION LPAREN ARGUMENT RPAREN ... syntax error
or FUNCTION ARGUMENT ARGUMENT where (foo) is a single argument? And how
do you want to make out the difference?


> 4) and, finally, I need to figure out how to "process" this. With my
> expression parser, I'm basically doing an interpreter, so that seems
> to make everything a lot simpler. All the other functions are working
> (you'll see it at the bottom of the expression.g file.

Well, if you have something like
expr returns [Result res]: ...
Then you could do:
functionCall {Result arg;}: 
  id:IDENTIFIER ( arg=expr { arguments.add(arg); })*
  { callFunc(#id.getText(), arguments); }

HTH,
Martin



More information about the antlr-interest mailing list