Я вынужден использовать% glr-parser? - PullRequest
1 голос
/ 30 ноября 2009

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

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 предупреждение о снижении / уменьшении.

Ответы [ 3 ]

1 голос
/ 02 декабря 2009

Технически, эта проблема связана с попыткой связать грамматику с семантическим значением, которое фактически не отличается синтаксисом.

ISTM, что вам просто нужна единственная грамматическая конструкция, которая описывает как типы, так и выражения. Различайте в коде, а не в грамматике, особенно если нет синтаксической разницы. Yacc называется генератором компилятора, но это не совсем верно. Это просто делает парсеры.

Сказав это, распознавание [] в качестве символа терминала может быть более простым способом решения проблемы и продолжения работы. Yacc не очень хорошо разбирается в неоднозначных грамматиках, и ему необходимо быстро принять решение, по какому пути идти.

1 голос
/ 02 декабря 2009

Создайте правило Lex с помощью [], поскольку [] используется только в объявлении, а везде будет использоваться [var]

1 голос
/ 01 декабря 2009

Не могли бы вы определить новый токен

VarLBracket [a-zA-Z][a-zA-Z0-9_]*\[

и, следовательно, определить объявление

Type | VarLBracket ']';

и определите цель назначения как

Var | VarLBracket expr ']';
...