Odd case for rewrite rule
0 posts in topic
Flat View  Flat View
TOPIC ACTIONS:
 

Posted By:   Ernest_Mishkin
Posted On:   Monday, March 2, 2009 09:14 AM

Hello, I'm building a grammar that supports boolean expressions. I'm using the usual expression grammar pattern, however in my case there's a slight complication: operator OR is implied when there's no operator between the two adjacent terms. I've pulled sufficient amount of hair trying to generate the expected AST fragment for the or_expr rule. I just can't figure out how to use rewrite rule syntax to achieve what I need, namely "if there's only one and_expr then just output it, don't create new nodes; otherwise, create new subtree with OR token as root and the two and_expr as children. Any advise will be appreciated. I tried using multiple rewrites as mentioned in the "Definitive ANTLR Reference" book   More>>

Hello,

I'm building a grammar that supports boolean expressions. I'm using the usual expression grammar pattern, however in my case there's a slight complication: operator OR is implied when there's no operator between the two adjacent terms.

I've pulled sufficient amount of hair trying to generate the expected AST fragment for the or_expr rule. I just can't figure out how to use rewrite rule syntax to achieve what I need, namely "if there's only one and_expr then just output it, don't create new nodes; otherwise, create new subtree with OR token as root and the two and_expr as children.

Any advise will be appreciated.
I tried using multiple rewrites as mentioned in the "Definitive ANTLR Reference" book (bottom of page 168), but oddly enough I'm getting syntax errors...


Here's the grammar:

			
grammar SearchQuery;
options {
output = AST;
backtrack = true;
}
query : or_expr+ EOF! ;
or_expr : and_expr (OR? and_expr)* ;
and_expr : atom (AND^ atom)* ;
atom : TERM | NOT^ TERM | LEFT_PAREN! or_expr RIGHT_PAREN! ;

// lexer
AND : 'and' ;
OR : 'or' ;
NOT : 'not' ;
LEFT_PAREN : '(' ;
RIGHT_PAREN : ')' ;
TERM : (LETTER | NUMBER)+ ;
WS : (~(LETTER | NUMBER | SYMBOL)+) { skip(); } ;
fragment LETTER : 'a'..'z' | 'A'..'Z' ;
fragment NUMBER : '0'..'9' ;
fragment SYMBOL : LEFT_PAREN | RIGHT_PAREN ;
   <<Less
About | Sitemap | Contact