[antlr-interest] "explosion" rewrite

Jim Idle jimi at temporal-wave.com
Sat May 2 09:22:24 PDT 2009


Steve Ebersole wrote:
> sortKey : expression;
>
> expression
>     : QUOTED_IDENTIFIER -> ^( COLUMN ALIAS_REF[Template.TEMPLATE]
> QUOTED_IDENTIFIER[$QUOTED_IDENTIFIER] )
>     // we treat the so-called standard functions differently because
> they are handled differently by the HQL lexer which we also use here...
>     | standardFunction
>     | literal
>     // not identDotIdentStructure because we dont want
> QUOTED_IDENTIFIERs is here
>     | ( IDENTIFIER ( DOT IDENTIFIER )* LEFT_PAREN ) => generalFunction
>     // otherwise we fully expect a dot-identifier series, and then we
> just need to decode the semantic of that structure
>     | identDotIdentStructure
>         -> { ( isFunctionName($identDotIdentStructure.text) ) }?
>               // we have a function with parens (thus no args)
>               ^( FUNCTION[$identDotIdentStructure.start,
> $identDotIdentStructure.text] )
>         -> { ( isPropertyName($identDotIdentStructure.text) ) }?
>               // we have a reference to a mapped property
>               { buildPropertyColumns( $identDotIdentStructure.tree ) }
>         -> { ( $identDotIdentStructure.tree.getType() == DOT ) }?
>               // we have a reference to a column which is already
> qualified
>               identDotIdentStructure
>         ->
>               // we have a reference to a column which is not qualified
>               ^( COLUMN ALIAS_REF[Template.TEMPLATE]
> IDENTIFIER[$identDotIdentStructure.start,$identDotIdentStructure.text] )
>     ;
>
>
> The piece of interest here is fragment in expression that reads
>
> -> { ( isPropertyName($identDotIdentStructure.text) ) }?
>               // we have a reference to a mapped property
>               { buildPropertyColumns( $identDotIdentStructure.tree ) }
>
> buildPropertyColumns() is a java action where I account for the fact
> that in Hibernate a single property might map to multiple columns; in
> that case buildPropertyColumns() returns the VECTOR_EXPR
>
>   
Hi Steve,

As the expression does not give you context as to whether you need the 
vector node or not, I think that you have the following options:

1) Change expression to accept a parameter that says whether you need 
the vector or not, pass this to your Java rule. So that you don't need 
to change every reference to expression you can rename the current one 
to expression_xyz then use expression (which calls xyz with 
needsVector=true) and expression_novector and sets it to false. The 
catch here is if you have any predicates in that expression rule that 
may be hoisted, in which case your local variable will be out of scope 
in the calling generated code.

2) As I think you mention in another email, keep a scope at a level high 
enough in the tree that can hold flags and pass them in to your java code.

3) Have the expression return a value that says whether the expression 
is VECTORABLE or not. In rules that require the node, then call a 
different rule that calls expression and rewrites with a VECTOR node if 
it is required. The ability to do this of course depends on whether the 
return from your Java function can be just rewritten with a node.

It may be that your grammar can be "re-worked" not to need such nodes 
though, or to produce a tree that while it may not be absolutely 
intuitive when you look at it, is obvious when walking it that you 
should treat the children in one way or another. I always try to avoid 
as much logic as I can in parsing and do everything that can be in the 
walkers. Perhaps you can wrap the expression in a higher node which 
means it will take a different path through the tree walk. Many 
different ways to crack a nut of course.

Jim






More information about the antlr-interest mailing list