Зубр жаловался на «конфликты: 1 сдвиг / уменьшение»

#bison #yacc

#bison #yacc

Вопрос:

Зубр жаловался на «конфликты: 1 сдвиг / уменьшение». Я не вижу, что не так. Пожалуйста, помогите. Спасибо,

 %token OR AND NUMBER
%%

search_condition:
        |       search_condition AND search_condition { printf(" AND "); }
        |       '(' search_condition ')'
        |       predicate
        ;

predicate:
                NUMBER { printf("%dn", $1);  }
        ;
 

Комментарии:

1. У меня нет опыта работы с Bison / Yacc, но ваш search_condition соответствует пустой строке (epsilon): search_condition : /* epsilon */ | search_condition AND ... , возможно, удалить первый канал? search_condition : search_condition AND ... ?

2. Добавление% осталось и решило проблему. Спасибо

Ответ №1:

Конфликт означает, что грамматика, которую вы передали bison, не является LALR(1), поэтому он не может решить, какое действие предпринять в каждом возможном случае, чтобы правильно проанализировать грамматику.

В вашем случае проблема в том, что ваша грамматика неоднозначна. Если вы введете ему ввод, подобный

 NUMBER AND NUMBER AND NUMBER
 

он не может решить, должен ли он анализировать его как эквивалент

 ( NUMBER AND NUMBER ) AND NUMBER
 

или

 NUMBER AND ( NUMBER AND NUMBER )
 

Есть несколько способов решить эту проблему:

  • вы можете использовать %left AND или %right AND , чтобы сообщить bison, что он должен обрабатываться AND как левый или правый ассоциативный инфиксный оператор
  • вы можете реорганизовать search_condition правило, чтобы сделать его однозначным:
     search_condition : search_condition AND primary
                     | primary
                     ;
    primary : '( search_condition ')'
            | predicate
            ;