Я вынужден использовать% glr-parser?
Вопрос
Я старался не допускать ошибок сдвига / уменьшения. Теперь, наконец, я думаю, что встретил свой матч.
Int[] a
a[0] = 1
Проблема в том, что int [] определяется как
Type OptSquareBrackets
в то время как [0] определяется как
Var | Var '[' expr ']'
Var и Type оба определены как VAR, который является любой допустимой переменной [a-zA-Z] [a-zA-Z0-9 _]
. Помимо добавления фиктивного токена (такого как ** Decl ** Type OptSquareBrackets
), есть ли способ написать это, чтобы не было конфликта? Из этого правила я получаю 1 предупреждение о смене / уменьшении и 1 предупреждение о снижении / уменьшении.
Решение
Не могли бы вы определить новый токен
VarLBracket [a-zA-Z][a-zA-Z0-9_]*\[
И поэтому определите объявление
Type | VarLBracket ']';
и определите цель назначения как
Var | VarLBracket expr ']';
Другие советы
Создайте правило Lex с помощью [], поскольку [] используется только в объявлении, а везде используется [var]
Технически, эта проблема связана с попыткой связать грамматику с семантическим значением, которое на самом деле не отличается синтаксисом.
ISTM, что вам просто нужна единственная грамматическая конструкция, которая описывает как типы, так и выражения. Различайте в коде, а не в грамматике, особенно если нет синтаксической разницы. Yacc называется генератором компилятора, но это не совсем верно. Это просто делает парсеры.
Сказав это, распознавание []
в качестве символа терминала может быть более простым способом решения проблемы и продолжения работы. Yacc не очень хорошо разбирается в неоднозначных грамматиках, и ему необходимо быстро принять решение о том, по какому пути следовать.