[antlr-interest] Resolving special key words during processing of AST
Jack Luh
jluh at cellfire.com
Sun Apr 29 11:51:52 PDT 2007
Hello,
I've recently started using ANTLR and have run across a problem that I
can't seem to solve.
I've create a simple logical expression grammar, lex, AST.
I would like to evaluate the following language:
<key_word> OPERATOR <value>
e.g.
today > 20070101 & today < 20071231
I'm currently able to parse and evaluate the Boolean results. The issue
is that I now need to tie this into my business logic where I would
resolve my <key_word> into something meaningful. In the example above,
"today" would resolve to today date. Another keyword could resolve into
the user's date of birth. I currently have a static method
(Variable.resolve()) which I put into the current grammer file. It
takes a single parameter which is the name of the current keyword. For
something non-related to the system, business logic or any user, I can
simple just return the value. However, in the case where I need to look
up a user and return user data how do I pass the user object to the AST
parser so that I can get this information back when I need to resolve
the keyword? I would like to do something like the following:
FilterTreeParser treeParser = new FilterTreeParser();
result = treeParser.expr(t, user); // Is there a way I can pass
user parameter here?
If I'm going about this all wrong is there a better approach?
Thanks,
Jack
==========================[Start Grammer file]==========================
// defines the language
class FilterParser extends Parser;
options {
buildAST=true;
}
expr: mexpr ((AND^|OR^) mexpr)*
;
mexpr: atom (EQ^|NEQ^|GT^|GTE^|LT^|LTE^) atom
| LPAREN! expr RPAREN!
;
atom: VAR
| INT
;
// defines the tokens (i.e. words)
class FilterLexer extends Lexer;
options {
k=2; // needed for newline junk
charVocabulary='\u0000'..'\u007F'; // allow ascii
}
LPAREN : '(' ;
RPAREN : ')' ;
AND : '&';
OR : '|';
EQ : '=';
NEQ : "!=";
GT : '>';
GTE : ">=";
LT : '<';
LTE : "<=";
INT : ('0'..'9')+ ;
VAR : ('a'..'z')+('_'(('a'..'z')|('0'..'9'))+)*;
WS : ( ' ' | '\r' '\n' | '\n' | '\t' )
{$setType(Token.SKIP);}
;
// used to evaluate the expressions
class FilterTreeParser extends TreeParser;
options {
importVocab=FilterParser;
}
@header {
import com.cellfire.jack;
}
// handles the logical operators
expr returns [boolean r=false]
{ boolean a,b; }
: #(AND a=expr b=expr) {r = a&&b;}
| #(OR a=expr b=expr) {r = a||b;}
| (a=mexpr) {r=a;}
;
// handles the comparison operators
mexpr returns [boolean r=false]
{ String a,b; }
: #(EQ a=atom b=atom) {r = a.equalsIgnoreCase(b);}
| #(NEQ a=atom b=atom) {r = !a.equalsIgnoreCase(b);}
| #(LT a=atom b=atom) {r = (a.compareToIgnoreCase(b)<0);}
| #(LTE a=atom b=atom) {r = (a.compareToIgnoreCase(b)<=0);}
| #(GT a=atom b=atom) {r = (a.compareToIgnoreCase(b)>0);}
| #(GTE a=atom b=atom) {r = (a.compareToIgnoreCase(b)>=0);}
;
// handles the variables and values
atom returns [String r=null]
: i:INT {r = i.getText();}
| j:VAR {r = Variable.resolve(j.getText());} //
Variable.Resolve() is the tie to business logic
;
==========================[End Grammer file]==========================
==========================[Start Main Method]==========================
private boolean executeFilter(String expr) {
boolean result = false;
StringReader rdr = new StringReader(expr);
FilterLexer lexer = new FilterLexer(rdr);
FilterParser parser = new FilterParser(lexer);
try {
parser.expr();
}
catch (Exception ex) {
assertTrue(ex.getMessage(), true);
}
AST t = parser.getAST();
FilterTreeParser treeParser = new FilterTreeParser();
try {
result = treeParser.expr(t); // can I pass other parameters
here?
}
catch (Exception ex) {
assertTrue(ex.getMessage(), true);
}
System.out.println("Expr: " + expr);
System.out.println("Tree: " + t.toStringTree());
System.out.println("Result: " + result);
return result;
}
==========================[End Main Method]==========================
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Teach your phone new tricks
Go to cellfire.com <http://www.cellfire.com/> or text '110' to 22888
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/antlr-interest/attachments/20070429/4baaf01a/attachment-0001.html
More information about the antlr-interest
mailing list