0

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
        ;
Alex R.
  • 459
  • 5
  • 16

1 Answers1

2

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:

Community
  • 1
  • 1
rici
  • 234,347
  • 28
  • 237
  • 341
  • Isn't this approach wrong since whenever you want an expression parser can accept condition as well. eg. for value assignment : id = expr; or should I do I deal with it @ semantic analysis? – Alex R. May 17 '17 at 15:16
  • 1
    @AlexF: That was my point about C, including the example which shows two conditions being used as expressions. If you don't want it to be like C, then you need a different strategy, but (as is indicated in several of the linked questions) it is easiest to do that with a semantic check in the reduce action. (Also you shouldn't say that you want to do it like C :-) ) – rici May 17 '17 at 15:20