[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