Оператор if-else в бизоне
Я пытаюсь сделать заявление если-то в зубре. Проблема в том, что я работаю над решением, которое все говорят, что работает, но это не так:(мой код:
заявление: matchedstmt
| unmatchedstmt
; matchedstmt: if '(' expression ')' matchedstmt иначе matchedstmt
| otherstmt
;
оператор unmatchedstmt: if '(' expression ')'
| if '('expression ')' matchedstmt else unmatchedstmt
;
otherstmt: expressionstmt
| compoundstmt
| iterationstmt
| returnstmt
;
...
где "если" и "еще" - токен%
!! в терминале это говорит, что у меня есть одна смена / уменьшение.
Я также пробовал%nonassoc и% оставил
А что я могу сделать??
2 ответа
Лучший способ решить эту проблему, используя %nonassoc
,
%nonassoc THEN
%nonassoc ELSE
%%
statement: TIF TLPAREN expression TRPAREN TTHEN statement %prec THEN
| TIF TLPAREN expression TRPAREN TTHEN statement TELSE statement
%%
Следующее может быть обработано зубрами без каких-либо конфликтов:
statement : matchedstmt
| unmatchedstmt
;
matchedstmt : if '(' expression ')' matchedstmt else matchedstmt
| otherstmt
;
unmatchedstmt : if '(' expression ')' statement
| if '('expression ')' matchedstmt else unmatchedstmt
;
otherstmt : expressionstmt
| compoundstmt
| iterationstmt
| returnstmt
;
Это неудивительно, поскольку вы используете стандартный механизм устранения неоднозначности if ... else
заявление.
Предположительно, конфликт сдвига-уменьшения находится где-то еще в вашей грамматике, возможно, вовлекая взаимодействие с этим фрагментом. Я предлагаю вам добавлять больше типов операторов по одному, пока не найдете правило, вызывающее конфликт. К сожалению, грамматики LR плохо сочетаются: вполне возможно, что два совершенно бесконфликтных фрагмента приводят к конфликту, когда они объединяются в грамматику.
В целом вы обнаружите, что получите лучшие ответы по Stackru, если будете следовать инструкциям в разделе Как спрашивать. В частности, вы должны сначала попытаться найти самую маленькую программу, в которой показана проблема, которую вы испытываете, а затем поставить все это на свой вопрос. Это то, что мы называем MCVE: минимальный, полный и проверяемый пример, который имеет то преимущество, что кто-то, пытающийся ответить на ваш вопрос, может точно видеть, что вы делаете.
Выдержка из вашего кода, которая не может быть скомпилирована или выполнена, не является MCVE. Создание MCVE может показаться большой работой, а иногда и так. Но помимо помощи людям в ответе на ваш вопрос, это также помогает вам ответить на ваш собственный вопрос, потому что это помогает вам сосредоточиться на проблеме. Так что это очень полезное упражнение.