How can I execute an ANTLR parser action for each item in a rule that can match more than one item?
Posted
by Chris Farmer
on Stack Overflow
See other posts from Stack Overflow
or by Chris Farmer
Published on 2010-02-01T19:31:47Z
Indexed on
2010/05/29
14:12 UTC
Read the original article
Hit count: 254
I am trying to write an ANTLR parser rule that matches a list of things, and I want to write a parser action that can deal with each item in the list independently.
Some example input for these rules is:
$(A1 A2 A3)
I'd like this to result in an evaluator that contains a list of three MyIdentEvaluator
objects -- one for each of A1, A2, and A3.
Here's a snippet of my grammar:
my_list returns [IEvaluator e]
: { $e = new MyListEvaluator(); }
'$'
LPAREN
op=my_ident+ {
/* want to do something here for each 'my_ident'. */
/* the following seems to see only the 'A3' my_ident */
$e.Add($op.e);
}
RPAREN
;
my_ident returns [IEvaluator e]
: IDENT { $e = new MyIdentEvaluator($IDENT.text); }
;
I think my_ident
is defined correctly, because I can see the three MyIdentEvaluators
getting created as expected for my input string, but only the last my_ident
ever gets added to the list (A3 in my example input).
How can I best treat each of these elements independently, either through a grammar change or a parser action change?
It also occurred to me that my vocabulary for these concepts is not what it should be, so if it looks like I'm misusing a term, I probably am.
EDIT in response to Wayne's comment:
I tried to use op+=my_ident+
. In that case, the $op
in my action becomes an IList
(in C#) that contains Antlr.Runtime.Tree.CommonTree
instances. It does give me one entry per matched token in $op
, so I see my three matches, but I don't have the MyIdentEvaluator
instances that I really want. I was hoping I could then find a rule attribute in the ANTLR docs that might help with this, but nothing seemed to help me get rid of this IList
.
Result...
Based on chollida's answer, I ended up with this which works well:
my_list returns [IEvaluator e]
: { $e = new MyListEvaluator(); }
'$'
LPAREN
(op=my_ident { $e.Add($op.e); } )+
RPAREN
;
The Add
method gets called for each match of my_ident.
© Stack Overflow or respective owner