В статье Теодора Норвелла (1999) « Разбор выражений по рекурсивному спуску» автор начинает со следующей грамматики для арифметических выражений:
E --> E "+" E | E "-" E | "-" E | E "*" E | E "/" E | E "^" E | "(" E ")" | v
что довольно плохо, потому что это неоднозначно и леворекурсивно. Поэтому он начинает с удаления левой рекурсии, и его результат таков:
E --> P {B P}
P --> v | "(" E ")" | U P
B --> "+" | "-" | "*" | "/" | "^"
U --> "-"
Но я не могу понять, как он добился этого результата. Когда я пытаюсь удалить левую рекурсию самостоятельно, я делаю это следующим образом:
Во-первых, я группирую производства, которые не оставили рекурсии в одной группе, и другие (леворекурсивные) в другой группе:
E --> E "+" E | E "-" E | E "*" E | E "/" E | E "^" E // L-recursive E --> v | "(" E ")" | "-" E
Далее я назову их и фактор для более легкой манипуляции:
E --> E B E // L-recursive; B stands for "Binary operator" E --> P // not L-recursive; P stands for "Primary Expression" P --> v | "(" E ")" | U E // U stands for "Unary operator" B --> "+" | "-" | "*" | "/" | "^" P --> "-"
Теперь мне нужно иметь дело только с первыми двумя постановками, с которыми теперь легче иметь дело.
Я переписываю эти первые два производства, начиная с не L-рекурсивного производства (то есть просто
P
, Первичное выражение) и следуя за ним дополнительным хвостомT
, который я определяю как остальную часть исходного производства за исключением первого леворекурсивного нетерминала. (то есть простоB E
), за которым следует хвостT
, или который может быть пустым:E --> P T T --> B E T |
(обратите внимание на пустую альтернативу для хвоста).
Эти два произведения я теперь могу переписать в EBNF следующим образом:
E --> P {B E}
это почти то, что получает автор, но у меня есть
E
вместоP
этого внутри шаблона повторения ноль или более (Хвост). Другие постановки, которые я получаю, такие же, как у него:P --> v | "(" E ")" | U E B -> "+" | "-" | "*" | "/" | "^" U -> "-"
но и здесь у меня
E
вместоP
первого производства дляP
.
Итак, мой вопрос: что мне не хватает? Какое алгебраическое преобразование синтаксиса мне нужно выполнить сейчас, чтобы получить ту же самую точную форму, которую получает автор? Я пытался заменить на E
, но это только приводит меня в петли. Я подозреваю , что мне нужно как - то заменить P
на E
, но я не знаю , какой - либо правовой трансформации , чтобы оправдать его. Может быть, вы знаете, какой последний пропущенный шаг?
Ответы:
Недостающий шаг:
переписать E в T:
Упростить T:
Эквивалентно:
И вот вы здесь.
источник
T
вместе в одинT
? Есть ли какое-то правило для этого? (Я подозреваю, что это может быть как-то похоже на правило в булевой алгебраической логике, которое говорит «aa = a».)*
? Я видел в «Книге Дракона» (3.3, стр.91) этоx** = x*
. Это то же правило, которое вы использовали?