Дана контекстно-свободная грамматика, порождающая арифметические выражения с левой рекурсией: E -> E + T | T; T -> T * F | F; F -> (E) | id — уберите левую рекурсию и преобразуйте грамматику в форму, пригодную для построения рекурсивного нисходящего парсера

17 Ноя в 10:02
2 +1
0
Ответы
1
Начальная грамматика:
E→E+T∣T;T→T∗F∣F;F→(E)∣id E \to E + T \mid T;\quad T \to T * F \mid F;\quad F \to (E) \mid id
EE+TT;TTFF;F(E)id

Правило устранения немедленной левой рекурсии: для формы A→Aα∣βA \to A\alpha \mid \betaAAαβ заменить на
A→βA′;A′→αA′∣ε A \to \beta A';\qquad A' \to \alpha A' \mid \varepsilon
AβA;AαAε

Применяя это к EEE и TTT, получаем грамматику, пригодную для рекурсивного нисходящего парсера:
E→T E′ E \to T\ E'
ET E
E′→+ T E′∣ε E' \to +\ T\ E' \mid \varepsilon
E+ T Eε
T→F T′ T \to F\ T'
TF T
T′→∗ F T′∣ε T' \to *\ F\ T' \mid \varepsilon
T F Tε
F→( E )∣id F \to (\,E\,) \mid id
F(E)id

Краткое пояснение: левой рекурсии нет, порядок правил сохраняет приоритеты операций (∗* выше +++). Для реализации в рекурсивном нисходящем парсере удобно реализовать E′E'E и T′T'T как циклы: например
parseE():
- node = parseT()
- while lookahead == '+': consume('+'); rhs = parseT(); node = makePlus(node, rhs)
- return node
parseT() аналогично для '*'.
Эта грамматика пригодна для рекурсивного нисходящего парсера и позволяет построить левоассоциативные суммы и произведения.
17 Ноя в 10:51
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир