[antlr-interest] Using antlr to retreive logical expressions
Kunal Naik
kunal.a.naik at gmail.com
Thu Mar 1 11:12:11 PST 2012
Hi Miguel,
I think this blog post might be beneficial to you:
http://www.alittlemadness.com/2006/06/05/antlr-by-example-part-1-the-language/
In part 4 he explains the process of writing a tree grammar where you can
inject your code that can evaluate your expressions.
HTH,
Kunal
On Thu, Mar 1, 2012 at 1:31 PM, Miguel Almeida <migueldealmeida at gmail.com>wrote:
> Dear all,
>
> I need to parse and evaluate expressions which are in the format:
> - x eq 1 && y eq 10
> - (x lt 10 && x gt 1) || x eq -1
>
> I have the evaluator part working (ie, I have code that evaluates all the
> gt/lt/eq/neq expressions. All I need is the part that breaks the clause
> into these expressions and then applies the logical and/or's
>
> I saw a recommendation on ANTLR to do this. My idea is to:
> 1) Build a tree
> 2) Execute the leafs using my already existing code (eg, replace "1 eq 10"
> with false)
> 3) Execute a method that then applies the logical operation to get the
> result of the tree
>
> While I've spend the last couple of days reading things about ANTLR, I am
> kind of lost at the moment: I can't seem to be able to get a tree structure
> whose tokens hold either the && and || or the complete expressions.
>
> My current grammar is [1]. An example test case is [2]
> - If I omit the | ' ' from the ID, "x eq 1" will be 3 tokens instead of the
> one token I need
> - If I leave it there, then for example this "1 eq 1 && (bb eq 1)"
> expression won't work (No viable alternative at input '(' )
>
>
> Could you shed some light on what could be wrong?
>
> [1]
> grammar Logic;
>
> options {
> output = AST;
> }
>
> tokens {
> AND = '&&';
> OR = '||';
> }
>
> // parser/production rules start with a lower case letter
> parse
> : expression EOF! // omit the EOF token
> ;
>
> expression
> : implication
> ;
>
> implication
> : or ('->'^ or)* // make `->` the root
> ;
>
> or
> : and ('||'^ and)* // make `||` the root
> ;
>
> and
> : not ('&&'^ not)* // make `&&` the root
> ;
>
> not
> : '~'^ atom // make `~` the root
> | atom
> ;
>
> atom
> : ID+
> | '('! expression ')'! // omit both `(` and `)`
> ;
>
>
> // lexer/terminal rules start with an upper case letter
> ID
> :
> (
> 'a'..'z'
> | 'A'..'Z'
> | '0'..'9'
> | ' '
> )+
> ;
>
> Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
>
>
>
> [2] Example test case
> @Test
> public void complexAndOr() throws RecognitionException{
> // the expression
> String src = "(1 eq 1 && 2 eq 2) || 3 eq 3";
>
> // create a lexer & parser
> LogicLexer lexer = new LogicLexer(new ANTLRStringStream(src));
> LogicParser parser = new LogicParser(new CommonTokenStream(lexer));
>
> // invoke the entry point of the parser (the parse() method) and
> get the AST
> CommonTree tree = (CommonTree)parser.parse().getTree();
>
> assertEquals("||",tree.getText());
> Tree child1 = tree.getChild(0);
> assertEquals("&&",or.getText());
> assertEquals("1 eq 1",child1.getChild(0));
> assertEquals("2 eq 2",child1.getChild(1));
> assertEquals("3 eq 3",tree.getChild(1).getText());
> }
>
> Thank you,
>
> Miguel
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe:
> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>
More information about the antlr-interest
mailing list