[antlr-interest] Heterogeneous AST node construction - minor limitation in allowed class names

Tony.Gray at ca.schneider-electric.com Tony.Gray at ca.schneider-electric.com
Wed Jun 23 09:10:16 PDT 2010


Hi All,

I've been using Heterogeneous AST node construction with good success, 
following the nicely laid out example at 

http://www.antlr.org/wiki/display/ANTLR3/Tree+construction#Treeconstruction-heterogeneous

though I've run into a minor snag, for which there is a workaround.  The 
class name that follows the token name in angle brackets can't itself 
contain angle brackets.  So template/generic classes can't be created in 
this way.  The workaround is always to just make individual classes for 
each combination of types you'd use in the templates, but it would be nice 
if I could keep the whole specification in the ANTLR grammar rather than 
having to make classes that just wrap my generic classes.

For example, a node type UnaryOperatorNode<double> can't be emitted by 
ANTLR because if you enter:

unaryFunction:
        ABS     -> ABS<UnaryOperatorNode<double>>[$ABS,operand => 
Math.Abs(operand)]
        ;

you get an ANTLR error:
[08:39:50] ANTLR Parser Generator  Version 3.2 Sep 23, 2009 12:02:23
[08:39:50] error(100): CalcValueFormula.g:141:14: syntax error: antlr: 
CalcValueFormula.g:141:14: unexpected token: <
[08:39:50] error(100): CalcValueFormula.g:141:46: syntax error: antlr: 
CalcValueFormula.g:141:46: unexpected token: >

but without the type parameter on the class name, you're fine.  If I make 
a wrapper class DoubleUnaryOperatorNode: UnaryOperatorNode<double> in my 
code, then I can use it in the above construction without problems.

I have tried escaping with backslashes, no luck.  Not a big deal, the 
workaround is easy, this is just an FYI.

On a related note, I thought there was a similar problem with using square 
brackets within the parameter list to the constructor, but I was wrong. 
You do get an error if you don't escape, but you must only escape the 
CLOSING bracket, not both. 

So 
unaryFunction:  ABS     -> ABS<DoubleUnaryOperatorNode>[$ABS,operand => 
Math.Abs(operand[0])];

fails, and
unaryFunction:  ABS     -> ABS<DoubleUnaryOperatorNode>[$ABS,operand => 
Math.Abs(operand\[0\])];

fails, but 
unaryFunction:  ABS     -> ABS<DoubleUnaryOperatorNode>[$ABS,operand => 
Math.Abs(operand[0\])];

works fine.


More information about the antlr-interest mailing list