Изменение/уменьшение конфликта с грамматикой LALR

#compiler-construction #bison #yacc #lalr

Вопрос:

Я пишу грамматику, в которой я хотел бы, чтобы определенные функции находились только на верхнем уровне выражения, в то время как арифметические операции могут быть где угодно. Например, 4 (5 * 9) является правильным, ФУНКЦИЯ(2 4) * 8-ФУНКЦИЯ(4) также правильна, но ФУНКЦИЯ(2 * ФУНКЦИЯ(8)) является неправильной причиной, вложенная ФУНКЦИЯ не является функцией верхнего уровня. Вот моя грамматика:

 start : F

F : F   F
F : F - F
F : F * F
F : F / F
F : ( F )
F : FUNC( E )
F : E

E : E   E
E : E - E
E : E * E
E : E / E
E : ( E )
E : num

FUNC : MAX
FUNC : MIN
 

Я использую YACC, и я получаю конфликт сдвига/уменьшения в приведенной выше грамматике. Похоже, в грамматике нет двусмысленностей, но все равно что-то не так, так как возникают конфликты. Мне интересно, как правильно было бы написать такую грамматику?

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

1. Покажите все, включая объявления приоритета. Как написано, грамматика, безусловно, неоднозначна

2. Кроме того, стиль bison заключается в том, чтобы записывать нетерминалы lower_case и резервировать UPPER_CASE токены. Если токен является ключевым словом, еще лучше использовать кавычки ( "max" ) или, для односимвольных операторов, одинарные кавычки: ' ' . Строки в двойных кавычках должны быть объявлены в %token объявлении, если вы хотите, чтобы лексер мог их возвращать.