[antlr-interest] Using antlr to retreive logical expressions
    Miguel Almeida 
    migueldealmeida at gmail.com
       
    Thu Mar  1 10:31:04 PST 2012
    
    
  
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
    
    
More information about the antlr-interest
mailing list