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