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

Filed under:
|
|

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

Related posts about parser

Related posts about antlr