assignment -> ID ASSIGN expr | expr
(я игнорирую часть typ
, потому что полагаю, что она попала туда случайно)
Проблема здесь в том, что и ID ASSIGN expr
, и expr
могли бы начинаться с ID
(или, по крайней мере, могли бы, если бы T
содержал ID
в качестве опции, что, как я полагаю, было намерением), поэтому это не LL (1). Однако это LL (2), поэтому, если вы в порядке с этим, вы можете просто добавить andalso next_token = ASSIGN
к условию if
в вашем анализаторе и покончить с этим.
Если вам нужно, чтобы это был LL (1), вам придется настроить язык, разрешенный вашим парсером, я боюсь (то есть, нет грамматики LL (1), которая точно соответствует тому же языку как ваша текущая грамматика). Одним из простых способов было бы просто добавить ключевое слово, например SET
, до назначения, хотя, по общему признанию, это ужасно.
Другая альтернатива - разрешить произвольные выражения в качестве левого операнда =
, что делает ваше правило присваивания:
assignment -> exp (ASSIGN exp)?
Что такое LL (1). Недостатком этого является то, что он допускает много бессмысленного кода, такого как 1+2 := 42
, но вы можете исправить это за пределами грамматики. То есть, ваш код для разбора назначений может просто вызвать parse_exp
, а затем, если следующий токен - ASSIGN
, а выражение, возвращаемое parse_exp
- не просто идентификатор, выдает ошибку, что левая часть присвоение должно быть идентификатором.