Reputation: 458
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
Upvotes: 3
Views: 4468
Reputation: 170128
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.
Upvotes: 2
Reputation: 1812
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 ;
tc
is a binary expression binary_exp
.comparison_exp
,LEFTPARN
and RIGHTPARN
),LEFTPARN
, a binary_exp
, a binary operator BINARYOP
, a binary_exp
, and a right-parenthesis RIGHTPARN
.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.
Upvotes: 0