简体   繁体   中英

Antlr - Expression parser and evaluator

I am required to write a boolean expression parser/evaluator. The expressions would be of the form and would be enclosed in parenthesis :

exp1 : (A = B)
exp2 : ((A = B) AND (C = D))
exp3 : ((A = B) AND ((C = D) OR (E = F)))
exp4: (((A = B) AND (C = D)) OR (E = F))

and it goes on. The rule may contain 'n' number of expressions with proper grouping 2 in each group. My grammar file looks like this:

/*
Expression grammar
 */

grammar Exparser;

options

{
    language = Java;
}
cond    :   
tc EOF;

tc:
      exp
  | binary_exp
| leftparen* exp ( binaryop leftparen* exp rightparen+)*
| leftparen* exp ( binaryop leftparen* exp rightparen*)*

;

binary_exp:
 '(' exp BINARYOP exp ')'
;

binaryop:
            BINARYOP
        ;
leftparen:
             LEFTPARN
         ;

rightparen:
              RIGHTPARN
          ;

exp:
LEFTPARN VARIABLE COMPOP VARIABLE RIGHTPARN

;

variable:
            VARIABLE;


BINARYOP: AND | OR;
COMPOP: EQUAL | LT | GT | LTE | GTE | NE;
VARIABLE: (CHAR)+;
LEFTPARN: '(';
RIGHTPARN: ')';
EQUAL: '=' | 'EQ';
LT: '<' | 'LT';

GT:'>' | 'GT';
LTE: '<=';
GTE: '>=';
NE  :   '!=' | 'NE';
AND: 'AND' | '&' | 'and';

OR: 'OR' | 'or';

CHAR  :   'a'..'z'|'A'..'Z'|'_' |'0'..'9'|'-' | '.'
   ;

this grammar works fine, but I am not able to achieve the depth in the AST. for example exp3 is parsed as three exp and not as one exp and one binary_exp . Also how do I evaluate a boolean expression using my parser? How does my grammar enforce balancing of parenthesis? Though Nested Boolean Expression Parser using ANTLR give some idea for evaluating an expression, I am not able to apply in my case

The parser generated from the following grammar parses all your example input:

grammar Exparser;

parse
 : expr EOF
 ;

expr
 : expr binop expr
 | VARIABLE
 | '(' expr ')'
 ;

binop
 : AND | OR | EQUAL | LT | GT | LTE | GTE | NE
 ;

EQUAL     : '=' | 'EQ';
LT        : '<' | 'LT';
GT        : '>' | 'GT';
LTE       : '<=';
GTE       : '>=';
NE        : '!=' | 'NE';
AND       : 'AND' | '&' | 'and';
OR        : 'OR' | 'or';
VARIABLE  : [a-zA-Z0-9_.-]+;
SPACE     : [ \t\r\n] -> skip;

Evaluating these expressions should be the same as the Q&A you linked to in your question .

Caveat: I don't know antlr. However, I think you need to make your grammar more explicit. You are overloading exp too much. Try something like this pseudocode:

tc <- binary_exp ;
binary_exp <- comparison_exp
            | LEFTPARN binary_exp RIGHTPARN
            | LEFTPARN binary_exp BINARYOP binary_exp RIGHTPARN ;
comparison_exp <- LEFTPARN VARIABLE COMPOP VARIABLE RIGHTPARN ;
  • Every tc is a binary expression binary_exp .
  • A binary expression is one of:
    • a comparison expression comparison_exp ,
    • a binary expression surrounded by parentheses ( LEFTPARN and RIGHTPARN ),
    • or a sequence of left-parenthesis LEFTPARN , a binary_exp , a binary operator BINARYOP , a binary_exp , and a right-parenthesis RIGHTPARN .
  • a comparison expression is a sequence of left-parenthesis LEFTPARN , a variable VARIABLE , a comparison operator COMPOP , a VARIABLE , and a right-parenthesis RIGHTPARN .

This grammar would allow binary expressions to be nested inside extra parentheses or nested inside one another, but comparison expressions cannot have other expressions nested inside them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM