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

Rob Greene robgreene at gmail.com
Tue Nov 29 18:58:41 PST 2005


> Don't give up.  You're very close to groking ANTLR.  I think you tried
> to merge what several people suggested, but there were not really
> meant to work together.  They were more ideas bouncing around.

Not a problem - I'm finding the syntax confusing, which is ironic
since I'm working on writing an expression parser and a compiler,
isn't it? If you've been following my questions, I've got a project at
home to do a BASIC compiler, and we think having a good expression
parser at work will really allow us to enhance our product (my
"lunchtime" projects sometimes get carried away). I've then created a
simpler version of the expression parser at home to work out issues
(evaluates to doubles; the one at work is capable of handling Doubles,
Dates, Booleans, and Strings), plus the little sideline ones for WTF
resolution.  I'm confused myself - I have at least 4 grammars going
right now.  :-|

> If you are lost, then we failed in our attempt to assimilate you into
> the uber-ANTLR collective, and we must try again :-)

I think part of it is that my single compiler course was between 1988
and 1990, so that's 15 years ago. I've forgotton a lot, plus I've
never used lex or yacc (or bison or flex or ...) so the terminology
and capabilities are a mystery. I've got the Dragon Book, but that's
all I have for resources and I've only spot-checked stuff since my
compiler class.

> The lexer appears okay (even to the "evil DOS" comment!).

That was stolen from an example I read, so I can take no credit.

> The parser and the tree parser both look "correct", but they don't
> play well together.

You may have hit the nail on the head. When I'm working on this, I'm
not thinking of the AST created. From what you're saying, that's
something I better try to pay attention to... and maybe why I've
gotten lost on the argument list - I may need pictures (or verbal
descriptions of them).

> The parser you have written... (snip)

The good news is that with your suggestions, my simple expression
parser WORKS now. I'm not actually performing any functions, but I'm
getting output for the arguments before I see that the function is
being evaluated.

Let me walk the AST for the functions...

(1) In the parser, "IDENTIFIER LPAREN^ argList RPAREN!" instructs
ANTLR to build an AST with LPAREN (literally "(") as the root node.
This becomes my "key" to seeing the function call. IDENTIFIER becomes
the first child and argList is the second child.

(2) Still in the parser, for argList, "expression (COMMA! expression)*
{ ## = #( #[ARGLIST,"ARGLIST"], ## ); }" requires one expression
optionally followed by additional expressions separated by commas. The
comma is not stored in the AST.

I *think*, after re-reading this thread, that "##" stuff creates one
AST tree with "ARGLIST" as the root and each expression being appended
as a child... ?  I think this is instead of having multiple
parent-children structures?

Ok, I cannot figure out what it would look like without the ARGLIST
building stuff. I'd have "(" as the parent, first child would be
IDENTIFIER, and then... additional children with expression? Which
wouldn't be a problem, except I have no way to match the argument list
in the tree parser??

(3) In the tree parser, the expression rule, "#(LPAREN i:IDENTIFIER
args:argList) { System.out.println("i=" + i + ", args=" + args); }" is
sort of a regex expression to match the AST created by (1). "i" and
"args" are just AST trees. "i" is useful because that gives me the
function name, but "args" is worthless - right? It's just an AST
without any of the evaluated values. I need to track those in the
argList rule.

(4) Finally, in the tree parser,

argList
{ double v; }
	:	#( ARGLIST
			(
				v=expression
				{
					System.out.println("expression = " + v);
				}
			)*
  		)
  	;

This mess matches the fake token "ARGLIST" and then forces the
argument expressions to be evaluated. "v", in this case, is a double.
I think I need to create a List somewhere and start collecting the
value which the function call would reference and then clear up.

----

Close?

I hope so... 'cause then I'll have more questions, but I think this is
plenty enough for you kind souls to answer!!! Plus I don't want to go
too far overboard...

Thanks!
-Rob


More information about the antlr-interest mailing list