LR(0)-разбор — различия между версиями
Shersh (обсуждение | вклад) м (→Построение автомата) |
м (rollbackEdits.php mass rollback) |
||
(не показано 9 промежуточных версий 4 участников) | |||
Строка 1: | Строка 1: | ||
− | LR(0)-разборщик это частный случай [[LR(k)-грамматики#LR-разборщик|LR(k)-разборщикa]]. Заметим, что в данном случае <tex>k=0</tex>, то есть решение о своих действиях принимается только на основании содержимого стека, | + | LR(0)-разборщик {{---}} это частный случай [[LR(k)-грамматики#LR-разборщик|LR(k)-разборщикa]]. Заметим, что в данном случае <tex>k=0</tex>, то есть решение о своих действиях принимается только на основании содержимого стека, символы входной цепочки не учитываются. |
== Построение автомата и управляющей таблицы == | == Построение автомата и управляющей таблицы == | ||
− | |||
− | |||
=== Автомат === | === Автомат === | ||
Каждое состояние автомата будет состоять из LR(0)-ситуации. | Каждое состояние автомата будет состоять из LR(0)-ситуации. | ||
Строка 9: | Строка 7: | ||
|id=def_LR0_item) | |id=def_LR0_item) | ||
|definition= | |definition= | ||
− | Пусть <tex>\Gamma =\langle \Sigma, N, S, P \rangle</tex> {{---}} КС-грамматика и <tex>A \to w_1 w_2 \in P</tex>. Композицию <tex>[A \to w_1 \cdot w_2] </tex> назовем '''LR(0)-ситуацией''' (англ. ''LR(0)-item'') | + | Пусть <tex>\Gamma =\langle \Sigma, N, S, P \rangle</tex> {{---}} КС-грамматика и <tex>A \to w_1 w_2 \in P</tex>. Композицию <tex>[A \to w_1 \cdot w_2] </tex> назовем '''LR(0)-ситуацией''' (англ. ''LR(0)-item''). |
}} | }} | ||
В начале работы стек пуст, и указатель входной цепочки находится перед ее первым символом. Этому состоянию соответствует ситуация <tex>[E_0 \to \cdot E]</tex>, где <tex>E_0</tex> {{---}} нетерминал, добавленный при пополнении грамматики, <tex>E</tex> {{---}} стартовый нетерминал. Назовем это состояние <tex>0</tex>. Входная цепочка может начинаться с любого терминального символа, с которого начинается правая часть любого правила с левой частью <tex>E</tex>. Построим соответствующий переход по следующей схеме: | В начале работы стек пуст, и указатель входной цепочки находится перед ее первым символом. Этому состоянию соответствует ситуация <tex>[E_0 \to \cdot E]</tex>, где <tex>E_0</tex> {{---}} нетерминал, добавленный при пополнении грамматики, <tex>E</tex> {{---}} стартовый нетерминал. Назовем это состояние <tex>0</tex>. Входная цепочка может начинаться с любого терминального символа, с которого начинается правая часть любого правила с левой частью <tex>E</tex>. Построим соответствующий переход по следующей схеме: | ||
Строка 21: | Строка 19: | ||
<tex>{[} A \to \alpha \cdot B \beta] \xrightarrow{\text{B}} {[} A \to \alpha B \cdot \beta] </tex> | <tex>{[} A \to \alpha \cdot B \beta] \xrightarrow{\text{B}} {[} A \to \alpha B \cdot \beta] </tex> | ||
− | Таким образом, мы определяем новые состояния, в | + | Таким образом, мы определяем новые состояния, в которые автомат перейдет после переноса того или иного терминала или нетерминала. |
Можно заметить, что алгоритм LR-разбора похож на [[Алгоритм Эрли|алгоритм Эрли]]. | Можно заметить, что алгоритм LR-разбора похож на [[Алгоритм Эрли|алгоритм Эрли]]. | ||
Строка 27: | Строка 25: | ||
==== Базовые операции ==== | ==== Базовые операции ==== | ||
− | Заметим, что хранить в каждом состоянии только по одной ситуации не имеет смысла, поэтому пусть | + | Заметим, что хранить в каждом состоянии только по одной ситуации не имеет смысла, поэтому пусть каждое состояние будет представлять множество ситуаций, а переходы {{---}} терминалы и нетерминалы. Для этого определим базовые операции <tex>closure (I)</tex> и <tex>goto (I, X)</tex>, где <tex>I</tex> {{---}} множество ситуаций, <tex>X</tex> {{---}} символ грамматики (терминал или нетерминал). |
− | * Операция <tex>closure</tex> добавляет ситуации к множеству ситуаций, у которых точка стоит слева от нетерминала. Добавляются те ситуации, которые получаются из правил, в левой части | + | * Операция <tex>closure</tex> добавляет ситуации к множеству ситуаций, у которых точка стоит слева от нетерминала. Добавляются те ситуации, которые получаются из правил, в левой части которых находится этот нетерминал. |
* Операция <tex>goto</tex> "переносит" точку после символа <tex>X</tex>. Это означает переход из одного состояния в другое под воздействием символа <tex>X</tex>. | * Операция <tex>goto</tex> "переносит" точку после символа <tex>X</tex>. Это означает переход из одного состояния в другое под воздействием символа <tex>X</tex>. | ||
Строка 41: | Строка 39: | ||
=== Управляющая таблица === | === Управляющая таблица === | ||
− | После | + | После построения автомата можно перейти к построению управляющей таблицы. |
Обращение к таблице происходит следующим образом <tex>\mathtt{T[state, token]}</tex>, где | Обращение к таблице происходит следующим образом <tex>\mathtt{T[state, token]}</tex>, где | ||
Строка 72: | Строка 70: | ||
=== Пополнение грамматики=== | === Пополнение грамматики=== | ||
− | Для начала переходим к '' | + | Для начала переходим к ''пополненной грамматике'': |
<tex> | <tex> | ||
Строка 86: | Строка 84: | ||
[[Файл:eps-dfa.png|600px]] | [[Файл:eps-dfa.png|600px]] | ||
+ | |||
+ | На картинке в двойной рамке обозначены терминальные состояния {{---}} это такие состояния, из которых можно производить свертку по правилу грамматики, а из остальных возможен только перенос. Этот термин не используется в алгоритме, а нужен только для лучшего визуального восприятия. | ||
Теперь в одно состояние перемещаем все ситуации, в которые идут <tex>\varepsilon</tex>-переходы. Получаем [[Детерминированные конечные автоматы|ДКА]]: | Теперь в одно состояние перемещаем все ситуации, в которые идут <tex>\varepsilon</tex>-переходы. Получаем [[Детерминированные конечные автоматы|ДКА]]: |
Текущая версия на 19:33, 4 сентября 2022
LR(0)-разборщик — это частный случай LR(k)-разборщикa. Заметим, что в данном случае , то есть решение о своих действиях принимается только на основании содержимого стека, символы входной цепочки не учитываются.
Построение автомата и управляющей таблицы
Автомат
Каждое состояние автомата будет состоять из LR(0)-ситуации.
Определение: |
Пусть | — КС-грамматика и . Композицию назовем LR(0)-ситуацией (англ. LR(0)-item).
В начале работы стек пуст, и указатель входной цепочки находится перед ее первым символом. Этому состоянию соответствует ситуация
, где — нетерминал, добавленный при пополнении грамматики, — стартовый нетерминал. Назовем это состояние . Входная цепочка может начинаться с любого терминального символа, с которого начинается правая часть любого правила с левой частью . Построим соответствующий переход по следующей схеме:
Теперь мы должны выяснить, что произойдет, если анализатор выполнит перенос. Предположим, что мы выполним перенос
или перенос :
Таким образом, мы определяем новые состояния, в которые автомат перейдет после переноса того или иного терминала или нетерминала.
Можно заметить, что алгоритм LR-разбора похож на алгоритм Эрли.
Базовые операции
Заметим, что хранить в каждом состоянии только по одной ситуации не имеет смысла, поэтому пусть каждое состояние будет представлять множество ситуаций, а переходы — терминалы и нетерминалы. Для этого определим базовые операции
и , где — множество ситуаций, — символ грамматики (терминал или нетерминал).- Операция добавляет ситуации к множеству ситуаций, у которых точка стоит слева от нетерминала. Добавляются те ситуации, которые получаются из правил, в левой части которых находится этот нетерминал.
- Операция "переносит" точку после символа . Это означает переход из одного состояния в другое под воздействием символа .
Построение автомата
Теперь обсудим алгоритм построения конечного автомата. Обозначим
множество состояний, — множество переходов.- Изначальное состояние содержит одно правило: .
- Для текущего состояния делаем операцию .
- По всем возможный символам для каждой ситуации добавляем переходы, используя операцию .
- Если множество или во втором или третьем пункте изменилось, возвращаемся ко второму шагу.
Управляющая таблица
После построения автомата можно перейти к построению управляющей таблицы.
Обращение к таблице происходит следующим образом
, где- — состояние автомата,
- — входной символ;
В соответствии со структурой управляющей таблицы будем действовать следующим образом:
- Для каждого ребра
- (сокр. от shift) , если — терминал,
- , если — нетерминал.
(из состояния в состояние по ) мы поместим в позицию
- Для состояния
- Поместим (сокр. от reduce), где — это номер правила в изначальной грамматике.
, содержащего ситуацию в позицию для каждого терминала
- Запись означает допуск.
- Пустая ячейка означает ошибочную ситуацию.
Пример
Для иллюстрации алгоритма LR(0)-разборщика мы будем использовать грамматику:
Обратим внимание, что данная грамматика является леворекурсивной, поэтому нисходящий разборщик не сможет осуществить разбор слова из этой грамматики.
Пополнение грамматики
Для начала переходим к пополненной грамматике:
Построение автомата
НКА:
состоянию будет соответствует ситуация . Добавляем остальные состояния и получаем следующийНа картинке в двойной рамке обозначены терминальные состояния — это такие состояния, из которых можно производить свертку по правилу грамматики, а из остальных возможен только перенос. Этот термин не используется в алгоритме, а нужен только для лучшего визуального восприятия.
Теперь в одно состояние перемещаем все ситуации, в которые идут ДКА:
-переходы. ПолучаемЗаполнение управляющей таблицы
Пронумеруем правила для выполнения свертки:
Управляющая таблица будет выглядеть так:
LR(0)-разбора конкретной строки
Пример будет для строки
Строка | Стек | Комментарий | |||
---|---|---|---|---|---|
Перенос | . Переход в состояние.|||||
Перенос | . Переход в состояние.|||||
Свертка: | . Удаление из стека . Переход в состояние. Добавление в стек . Переход в состояние.|||||
Свертка: | . Удаление из стека . Переход в состояние. Добавление в стек . Переход в состояние.|||||
Перенос | . Переход в состояние.|||||
Перенос | . Переход в состояние.|||||
Свертка: | . Удаление из стека . Переход в состояние. Добавление в стек . Переход в состояние.|||||
Свертка: | . Удаление из стека . Переход в состояние. Добавление в стек . Переход в состояние.|||||
Перенос | . Переход в состояние.|||||
Свертка: | . Удаление из стека . Переход в состояние. Добавление в стек . Переход в состояние.|||||
Свертка: | . Удаление из стека . Переход в состояние. Добавление в стек . Переход в состояние.|||||
Перенос | . Переход в состояние.|||||
Перенос | . Переход в состояние.|||||
Свертка: | . Удаление из стека . Переход в состояние. Добавление в стек . Переход в состояние.|||||
Свертка: | . Удаление из стека . Переход в состояние. Добавление в стек . Переход в состояние.|||||
Так как свертка по нулевому правилу — осуществляем допуск. |
См. также
Источники информации
- Альфред Ахо, Рави Сети, Джеффри Ульман. Компиляторы. Принципы, технологии, инструменты. Издательство Вильямс, 2003. Стр. 301-326.
- Терехов Ан.А., Вояковская Н., Булычев Д., Москаль А. Разработка компиляторов на платформе .NET — Восходящие анализаторы
- Б.К.Мартыненко. Языки и трансляции. Стр. 198-223
- Лекции по теории формальных языков, LR(0)-, SLR(1)-, LR(1)- и LALR(1)-анализ