I'm attempting to create a boolean expression language/grammar for a personal project. The user will be able to write a string in a Java-like syntax, with provision for variables, which will be evaluated at a later time when the variables have been initialised. Rain For example, a user might enter the string
@FOO+7 > 4*(5+@BAR);
Later, when the variable FOO is initialised and equal to 6, and BAR is equal to 1, the expression evaluates to 13>24 and thus returns false.
I'm using ANTLRworks to generate the grammar and whilst it LOOKS fine, it doesn't correctly interpret negative signs. The input in the ANTLRworks is (for some reason) changed: "(8-3)>6" is read as "(8>6" (which fails to run as it is missing the closing bracket). I haven't implemented the variable lookups yet, but here is the grammar so far for just integers:
grammar BooleanCalculator;
@header {
package test;
}
prog : rule+
;
rule : boolean_expr ';' NEWLINE {System.out.println($boolean_expr.b);}
| NEWLINE
;
boolean_expr returns [boolean b]
: v1=num_statement
('<' v2=num_statement {$b = $v1.d < $v2.d;}
|'<=' v2=num_statement {$b = $v1.d <= $v2.d;}
|'=' v2=num_statement {$b = $v1.d == $v2.d;}
|'!=' v2=num_statement {$b = !($v1.d == $v2.d);}
|'>=' v2=num_statement {$b = $v1.d >= $v2.d;}
|'>' v2=num_statement {$b = $v1.d > $v2.d;})
;
num_statement returns [double d]
: v1=mult_statement {$d = $v1.d;}
('+' v2=mult_statement {$d += $v2.d;}
|'-' v2=mult_statement {$d -= $v2.d;})* //HERE IS THE OFFENDING LINE
;
mult_statement returns [double d]
: v1=var {$d = $v1.d;}
('*' v2=var {$d *= $v2.d;}
|'/' v2=var {$d /= $v2.d;}
|'%' v2=var {$d = $d/100*$v2.d;})*
;
var returns [double d]
: NUMBER {$d = Double.parseDouble($NUMBER.text);}
| '(' v1=num_statement ')' {$d = $v1.d;}
;
NUMBER : '0'..'9'+
;
It is working correctly for everything except the '-' sign. Does anyone know a way to fix this?
Also (I'm very new to ANTLR): am I doing the evaluation correctly? Or should I just let the grammar define the structure and use another method to determine if the statement is true/false?