[antlr-interest] Using antlr to retreive logical expressions

Miguel Almeida migueldealmeida at gmail.com
Fri Mar 2 02:32:39 PST 2012


Thank you for your answers,

Both links touch parts of the problem -
http://www.alittlemadness.com/2006/06/05/antlr-by-example-part-1-the-language/
is pretty similar to what I have. However, it doesn't deal with precisely
what I'm having problems with: whitespaces.

Every possible token in these examples doesn't have whitespace. In my case,
however, I want a token with spaces (eg: "1 eq 1"). Where should I include
this so that the correct expression is in the tree leaf? I take it is
should be in the ID lexer, but I'm not quite sure how.
If, on the other hand, I try to go the parser rule route, like:
clause: ID operator ID;
operator: 'eq' | 'neq' | 'gt' | 'lt' ;

Then I won't have a leaf like "1 eq q", but a node "clause" composed of 3
child leafs: "1", "eq", "1", which I take it is not appropriate. I can't
just test if the tree node is a clause an combine all children if it is,
can I?

I appreciate your feedback,

Miguel

On Thu, Mar 1, 2012 at 7:30 PM, Bart Kiers <bkiers at gmail.com> wrote:

> Only that tutorial is based on ANTLR v2.7, whose syntax differs
> considerably from the most recent ANTLR version (3.4).
>
> Regards,
>
> Bart.
>
>
> On Thu, Mar 1, 2012 at 8:12 PM, Kunal Naik <kunal.a.naik at gmail.com> wrote:
>
>> 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
>> >
>>
>> 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