[antlr-interest] Function Call,
Craig Main
craig at palantir.co.za
Wed Jun 29 06:31:11 PDT 2005
Hi,
I am *still* struggling.
What am I missing here?
I have tried the following rule.
#(METHOD_CALL( #(ELIST (expression)*))) {log.Info("Method Call");}
I also tried to match just
#(ELIST ( expression )* ) {log.Info("ELIST");}
It also doesn't match. The log output is never produced.
It still doesn't match.
The output is as follows.
rules.g:33:60: warning:Rule 'expression' returns a value
RuleLexer.cs(108,12): warning CS0219: The variable '_token' is assigned but
its value is never used
Tree Printout, trying to match TEMP = 4 + func[10+1,2];
-------------------------------------------------------
( RULESET ( = FRED 100 ) ( = TEST ( + 10 10 ) ) ( = ITEM ( + TEST 10 ) ) ( =
TE
MP ( + 4 ( func ( ELIST ( + 10 1 ) 2 ) ) ) ) )
---------------------------------------
[SimpleAppConfig]: term
[SimpleAppConfig]: FRED = 100
[SimpleAppConfig]: TEST = 20
[SimpleAppConfig]: ITEM = TEST10
<AST>: unexpected AST node: func
[SimpleAppConfig]: TEMP = 4
---------------------------------------
I cannot match the function.
Here is the new grammar.
rules
: #(RULESET (statement)*)
;
statement {object result = null;}
: #(ASSIGN id:ID result=expression {
log.Info(string.Format("{0} = {1}", id.getText(), result)); } )
;
expression
returns [object result] {result = null;object l,r;}
: #(PLUS l=term r=term)
{result=ExpressionOperation.Add(l,r);}
| #(MINUS l=term r=term)
{result=ExpressionOperation.Subtract(l,r);}
| #(MULTIPLY l=term r=term)
{result=ExpressionOperation.Multiply(l,r);}
| #(DIVIDE l=term r=term)
{result=ExpressionOperation.Divide(l,r);}
| #(METHOD_CALL( #(ELIST (expression)*)))
{log.Info("E-Exp");}
| result=term {log.Info("term");}
;
term
returns [object result] {result = null;}
: result=literal
;
//value : function | literal
// ;
literal
returns [object result] {result = null;}
: id:ID { result = id.getText(); }
| fl:FLOAT { result =
double.Parse(fl.getText()); }
;
AND THE PARSER
rules : (statement)*
{#rules = #([RULESET, "RULESET"], #rules);}
EOF!
;
statement : assignment_statement SEMI!
;
assignment_statement : id:ID ASSIGN^ expression
;
expression : term ((PLUS^|MINUS^) term)*
;
term : factor ((MULTIPLY^|DIVIDE^) factor)*
;
factor : value
;
value : (ID LPAREN) => function
| literal
;
function : id:ID^ {#id.setType(METHOD_CALL);} LPAREN!
arguments RPAREN!
;
arguments : (expression (COMMA! expression)*)?
{#arguments = #(#[ELIST,"ELIST"], arguments);}
;
literal : id:ID^
| fl:FLOAT^
;
-----Original Message-----
From: antlr-interest-bounces at antlr.org
[mailto:antlr-interest-bounces at antlr.org] On Behalf Of Bryan Ewbank
Sent: 29 June 2005 12:45 PM
To: ANTLR Interest
Subject: Re: [antlr-interest] Function Call,
I find it's a great help to use the tracing utility in ANTLR, because
it shows a list of the productions matched, rather than letting my
eyes go where I "know" it will go. Sometimes the two are very
different.
There's two problems; the first is that the alternative for
METHOD_CALL explicitly matches ELIST:
// problem in original tree grammar - doesn't dive into ELIST tree
#( METHOD_CALL ELIST )
It should instead use a subrule; perhaps it should be:
// tree grammar to drill into the subtree rooted at ELIST
#( METHOD_CALL expression )
The second problem is that the tree grammar for ELIST doesn't match
the parser output. The parser produces this tree for a function call:
#( METHOD_CALL #(ELIST e1 e2 e3) )
// the name of the function is the text of the METHOD_CALL node
However, the tree walker (and your example) don't match this because
they place an ID node below the ELIST:
// problem in original tree grammar
#(ELIST ID expression)
To match the input grammar, this should instead read:
// tree production to match that produced by the parser
#(ELIST ( expression )* )
You can also collapse these into one production in the tree grammar, thus:
// may as well write it this way; first two levels are known...
#( METHOD_CALL #( ELIST ( expression )* ) )
Hope this helps,
- Bryan Ewbank
More information about the antlr-interest
mailing list