I have written this grammar:
expr : multExpr ( ('+' | '-') multExpr )*;
multExpr : atom ( ('*' | '/') atom )*;
atom : INT | FLOAT | ID | '(' expr ')';
condition : cond ('or' cond)*;
cond : c1 ('and' c1)*;
c1 : ('not')? c2;
c2 : '(' condition ')' | boolean;
boolean : expr (relop expr | ²) | 'true' | 'false';
relop : '<' | '<=' | '>' | '>=' | '==' | '!=';
I have omitted the lexer rules for INT,FLOAT,ID as it is obvious.
The problem is c2 rule, it is ambiguous because of ‘(‘, I could not find the solution, can you offer me a solution?
Why not simply do:
The unary
notusually has a higher precedence than you’re trying to do now.This will allow for expressions like
42 > true, but checking such semantics can come when you’re walking the AST/tree.EDIT
The input
"not(a+b >= 2 * foo/3.14159) == false"would now be parsed like this (ignoring spaces):And if you set the output to AST and mix in some tree rewrite operators (
^and!):you’d get: