Условия - разбор грамматики SableCC

Я использую sableCC, и я пытаюсь построить грамматику, которая принимает условия, как в C. Однако я получаю ошибки, когда пытаюсь добавить круглые скобки в моих условиях, потому что есть конфликт с круглыми скобками, которые у меня есть для выражений. например, он принимает 4 = 3 или x = 95 mod 5 и 5 = 5, но без скобок. Также я чувствую, что грамматическое правило "не" неверно.

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
        ;

1 ответ

Решение

Если вы действительно хотите принять условия "как в C", то вы просто сделаете ваши условия другой формой expr, поскольку это то, что они есть: это выражения, значение которых всегда находится в диапазоне {0, 1}, Но они ничем не отличаются

a = (x < y) + 3 * (x == z || x < 6);

является вполне приемлемым выражением (хотя, вероятно, не часто встречается в программах на Си).

Так что если вы просто измените последний factor производство для lparen cond rparen (или переименовать cond как expr и найти другое слово, чтобы назвать то, что вы в настоящее время называете expr), и все проблемы с родительскими условиями исчезнут.

Есть ряд других вопросов SO, которые касаются этой проблемы. Вот несколько из них:

Другие вопросы по тегам