[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