[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