Вопрос

Я старался не допускать ошибок сдвига / уменьшения. Теперь, наконец, я думаю, что встретил свой матч.

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 не очень хорошо разбирается в неоднозначных грамматиках, и ему необходимо быстро принять решение о том, по какому пути следовать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top