2010-10-05 8 views
0

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

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 через зубров --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 

ответ

2

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

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

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

Это устраняет неоднозначность разобрана на уровне грамматики.

+0

+1 Ударьте меня. – eldarerathis

+0

Извините, я должен был указать, что у меня есть приоритет, хотя я не могу точно сказать, является ли это неполным. – mynameisash

+0

В таком случае вы должны отправить больше своих правил для 'expr'. Ничто в том, что вырезали, вы опубликовали, должно быть смещение-сокращение-конфликт. –

 Смежные вопросы

  • Нет связанных вопросов^_^