Как должны быть определены бинарные операторы в зубрах? - PullRequest
0 голосов
/ 05 октября 2010

Я пишу синтаксический анализатор в C с бизоном, и, хотя он, кажется, работает правильно при любых обстоятельствах, которые я до сих пор пытался, я получаю кучу предупреждений сдвига / уменьшения на моих бинарных операторах (и одно на моих унарных)Оператор НЕ также).

binary_op :
      PLUS { }
      | MINUS { }
      | TIMES { }
      | SLASH { }
      | POWER { }
      | AND { }
      | OR { }
      | LE { }
      | LT { }
      | GE { }
      | GT { }
      | EQ { }
      | NE { }
      | MOD { }
    ;

unary_op :
    NOT { }
    ;

expr :
    ...
    | unary_op expr { }
    | expr binary_op expr { }

Когда я запускаю свой файл .y через bison --verbose, я вижу:

state 51
   11 set_existence: expr . IN set
   12              | expr . NOT IN set
   34 expr: expr . binary_op expr
   34     | expr binary_op expr .

   ...
   NOT    shift, and go to state 26
   AND    shift, and go to state 27
   OR     shift, and go to state 28
   ....
   NOT     [reduce using rule 34 (expr)]
   AND     [reduce using rule 34 (expr)]
   OR      [reduce using rule 34 (expr)]

Я не вижу никаких проблем, фактически анализирующих двоичный файлоператоры, но, похоже, я должен, вероятно, решить проблемы сдвига / уменьшения в любом случае.Я не могу понять, где конфликт - произведения set_existence кажутся совершенно не связанными.Мое лучшее предположение (выстрел в темноте) состоит в том, что это может иметь какое-то отношение к тому факту, что EQ используется как бинарный оператор (сравнение равенства), а также присваивание (например, "foo = bar = baz;" установитfoo в true / false в зависимости от того, равны ли bar и baz).Если я изменю свое равенство сравнения на == ("foo = bar == baz;"), мой синтаксический анализатор будет работать, как и ожидалось, но все равно будет иметь такие же конфликты сдвига / уменьшения.

EDIT : У меня указана ассоциативность:

%left OR
%left AND
%left NOT
%left LT LE GT GE NE EQ
%left PLUS MINUS
%left TIMES MOD SLASH
%left POWER

1 Ответ

2 голосов
/ 05 октября 2010

Есть несколько способов избежать этого. Первый - использовать команды %left, %right и %nonassoc для указания уровня приоритета (см. руководство ).

Другой вариант, который я лично предпочитаю, это закодировать приоритет непосредственно в грамматику. Например, вот BNF для простых арифметических выражений:

expr ::= term | expr + term
term ::= factor | term * factor
factor ::= number | ( expr )

Это устраняет неоднозначный анализ на уровне грамматики.

...