I'm using sableCC and I try to built a grammar that accepts conditions like in C.However I'm getting errors when I try to add parentheses on my conditions because there is a conflict with the parentheses I have for the expressions. eg it accepts 4 = 3 or x = 95 mod 5 and 5 = 5 but without any parentheses.Also I feel like the 'not' grammar-rule is not correct.
Helpers
tab = 9;
cr = 13;
lf = 10;
sign = '+' | '-';
digit = ['0'..'9'];
lowercase = ['a'..'z'];
uppercase = ['A'..'Z'];
letter = lowercase | uppercase;
idletter = letter | '_';
idchar = letter | '_' | digit;
Tokens
number = [digit - '0'] digit*;
id = idletter idchar*;
plus = '+';
minus = '-';
times = '*';
div = 'div';
mod = 'mod';
equal = '=';
hash = '#';
greater = '>';
greateq = '>=';
less = '<';
lesseq = '<=';
not = 'not';
and = 'and';
or = 'or';
lparen = '(';
rparen = ')';
eol = cr | lf | cr lf;
blank = ' ' | tab;
Ignored Tokens
eol, blank;
Productions
program = compare*;
expr = {term} term
| {add} expr plus term
| {sub} expr minus term
;
term = {factor} factor
| {times} term times factor
| {div} term div factor
| {mod} term mod factor
;
factor = {number} number
| {id} id
| {expr} lparen expr rparen
;
compare = {cond} cond |
{gr}compare greater cond |
{gq}compare greateq cond |
{ls}compare less cond |
{lq}compare lesseq cond |
{eq}compare equal cond |
{not} not cond
;
cond = {expr} expr |
{and} cond and expr |
{or} cond or expr
;
If you really mean to accept conditions "like in C", then you will just make your conditions another form of expr
, since that is what they are: they are expressions whose value happens to always be in the range {0, 1}
. But they are not otherwise different:
a = (x < y) + 3 * (x == z || x < 6);
is a perfectly acceptable expression (although it probably doesn't appear very often in C programs).
So if you just change the last factor
production to lparen cond rparen
(or rename cond
as expr
and find some other word to name what you are currently calling expr
), and all the problems with parenthetic conditions will disappear.
There are a number of other SO questions which address this issue. Here are a few: