views:

472

answers:

2

What is the correct way to solve this problem in ANTLR:

I have a simple grammar rule, say for a list with an arbitrary number of elements.

list
: '[]' 
| '[' value (COMMA value)* ']'

If I wanted to assign a return value for list, and have that value be the actual list of returned values from the production, what is the proper way to do it? The alternatives I'm entertaining are:

  • create my own stack in the global scope to keep track of these lists
  • Try to inspect the tree nodes below me and extract information that way
  • Access it in some slick and cool way that I'm hoping to find out about in which I can get easy access to such a list from within the action associated with the rule.

I guess the question is: How do the cool kids do it?

(FYI I'm using the python API for ANTLR, but if you hit me with another language, I can handle that)

+2  A: 

In C# it might look like this:

list returns [ List<string> ValueList ]
    @init
    {
     $ValueList = new List<string>();
    }
    : '[]'
    | '[' value {$ValueList.Add(value);} (COMMA value {$ValueList.Add(value);})* ']'
    ;
Don Reba
And that's very close to how it looks in Java, as well. Thanks! However, Antlr required me to assign names to each "value": a=expr {$valueList.add( $a.value);} (b=expr {$valueList.add($b.value);})*
Andy Thomas-Cramer
A: 

I guess a more straightforward way could be

list returns [ List values ]
: '[]' 
| '[' vs+=value (COMMA vs+=value)* ']' {
        $values = $vs;
}
antispam
The author's "Definitive ANTLR Reference" shows this pattern in several places -- but what I found it giving me was a list of AST subtrees, not a list of their values.
Andy Thomas-Cramer