LR(k)-грамматики — различия между версиями
Margarita (обсуждение | вклад) (→LR-разборщик) |
Margarita (обсуждение | вклад) (→LR(k)-грамматика) |
||
Строка 2: | Строка 2: | ||
== LR(k)-грамматика == | == LR(k)-грамматика == | ||
− | |||
{{Определение | {{Определение | ||
|id=def_augmented_grammar) | |id=def_augmented_grammar) | ||
Строка 8: | Строка 7: | ||
Пусть <tex>\Gamma =\langle \Sigma, N, S, P \rangle</tex> {{---}} [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|контекстно-свободная]] грамматика. '''Пополненной грамматикой''' (англ. ''augmented grammar''), полученной из <tex>\Gamma</tex>, назовем грамматику <tex>\Gamma' =\langle \Sigma', N', S', P' \rangle</tex>, где <tex>\Sigma' = \Sigma; N' = N \cup \{S'\}; S' \notin N; P' = P \cup \{S' \to S\}</tex> | Пусть <tex>\Gamma =\langle \Sigma, N, S, P \rangle</tex> {{---}} [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|контекстно-свободная]] грамматика. '''Пополненной грамматикой''' (англ. ''augmented grammar''), полученной из <tex>\Gamma</tex>, назовем грамматику <tex>\Gamma' =\langle \Sigma', N', S', P' \rangle</tex>, где <tex>\Sigma' = \Sigma; N' = N \cup \{S'\}; S' \notin N; P' = P \cup \{S' \to S\}</tex> | ||
}} | }} | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{{Определение | {{Определение | ||
|id=def_LR_K | |id=def_LR_K | ||
|definition= | |definition= | ||
− | Пусть <tex>\Gamma' =\langle \Sigma', N', S', P' \rangle</tex> {{---}} пополненная грамматика для КС-грамматики <tex>\Gamma</tex>. Грамматика <tex>\Gamma</tex> явяется '''LR(k)-грамматикой''', если для любых двух [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора#Лево-_и_правосторонний_вывод_слова|правосторонних выводов]] | + | Пусть <tex>\Gamma' =\langle \Sigma', N', S', P' \rangle</tex> {{---}} пополненная грамматика для КС-грамматики <tex>\Gamma</tex>. Грамматика <tex>\Gamma</tex> явяется '''LR(k)-грамматикой''', если для любых двух [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора#Лево-_и_правосторонний_вывод_слова|правосторонних выводов]]: |
− | * <tex>S' \Rightarrow^* \ | + | * <tex>S' \Rightarrow^* \beta A t z \Rightarrow \beta \alpha t z \Rightarrow^* w, </tex> если <tex>|t|=k</tex> или <tex>|t|<k, |z|=0 (z = \varepsilon)</tex> |
− | * <tex>S' \Rightarrow^* \gamma B | + | * <tex>S' \Rightarrow^* \gamma B t z' \Rightarrow \gamma \xi t z' \Rightarrow^* w', </tex> если <tex> |t|<k \Rightarrow z= \varepsilon </tex> |
− | + | ||
+ | верно, что <tex>\gamma \xi = \beta \alpha</tex>, | ||
+ | |||
+ | следует, что <tex>\beta = \gamma</tex> и <tex>A = B</tex> | ||
}} | }} | ||
+ | Говоря неформально, мы делаем правостороннюю свёртку нашей строки в стартовый нетерминал. Если по не более чем <tex>k</tex> символам неразобранной строки мы можем однозначно определить, во что сворачивается хвост выведенного правила, то грамматика будет LR(k). | ||
+ | |||
+ | Использование в определении LR(k)-грамматики пополненной грамматики существенно для однозначного определения конца анализа. Действительно, если грамматика использует <tex>S</tex> в правых частях правил, то свертка основы в <tex>S</tex> не может служить сигналом приема входной цепочки. Свертка же в <tex>S'</tex> в пополненной грамматике служит таким сигналом, поскольку <tex>S'</tex> нигде, кроме начальной сентенциальной формы, не встречается. | ||
− | + | Существенность использования пополненной грамматики в определении LR(k)-грамматик продемонстрируем на следующем конкретном примере: | |
− | |||
− | |||
− | |||
− | |||
− | + | --- TODO --- | |
LR(k) означает, что | LR(k) означает, что |
Версия 13:13, 29 августа 2015
Восходящий разбор (англ. Bottom-up parsing) предназначен для построения дерево разбора. Мы можем представить себе этот процесс как "свертку" исходной строки к правилу грамматики. Каждый шаг свертки заключается в сопоставлении некоторой подстроки и правой части какого-то правила грамматики, затем происходит замена этой подстроки на нетерминал, являющийся левой частью правила. Восходящий разбор менее интуитивный, чем нисходящий, но зато позволяет разбирать большее множество грамматик.
Содержание
LR(k)-грамматика
Определение: |
Пусть контекстно-свободная грамматика. Пополненной грамматикой (англ. augmented grammar), полученной из , назовем грамматику , где | —
Определение: |
Пусть правосторонних выводов:
верно, что следует, что , и | — пополненная грамматика для КС-грамматики . Грамматика явяется LR(k)-грамматикой, если для любых двух
Говоря неформально, мы делаем правостороннюю свёртку нашей строки в стартовый нетерминал. Если по не более чем
символам неразобранной строки мы можем однозначно определить, во что сворачивается хвост выведенного правила, то грамматика будет LR(k).Использование в определении LR(k)-грамматики пополненной грамматики существенно для однозначного определения конца анализа. Действительно, если грамматика использует
в правых частях правил, то свертка основы в не может служить сигналом приема входной цепочки. Свертка же в в пополненной грамматике служит таким сигналом, поскольку нигде, кроме начальной сентенциальной формы, не встречается.Существенность использования пополненной грамматики в определении LR(k)-грамматик продемонстрируем на следующем конкретном примере:
--- TODO ---
LR(k) означает, что
- входная цепочка обрабатывается слева направо (англ. left-to-right parse);
- выполняется правый вывод (англ. rightmost derivation);
- не более символов цепочки (англ. k-token lookahead) используются для принятия решения.
LR-разборщик
Принцип переноса-свёртки
При LR(k)-анализе применяется метод перенос-свертка (англ. shift-reduce). Суть метода сводится к следующему:
- Программа анализатора читает последовательно символы входной строки до тех пор, пока не накопится цепочка, совпадающая с правой частью какого-нибудь из правил. Рассмотренные символы переносим в стек (операция перенос).
- Далее все символы совпадающей цепочки извлекаются из стека и на их место помещается нетерминал, находящийся в левой части этого правила (операция свертка).
Структура
Метод перенос-свертка использует следующие компоненты:
- Входная строка
- Стек (для запоминания рассмотренных символов)
- Управляющая таблица (для определения, какое действие применить - перенос или свертку)
- Автомат (для запоминания информации о текущем состоянии стека)
Управляющая программа анализатора
Управляющая программа одинакова для всех LR-анализаторов, а таблица и автомат изменяются от одного анализатора к другому.
Для запоминания строки запись в стек имеет вид:
, где — вершина стека. Каждый — символ грамматики(терминал или нетерминал), а — состояние автомата. Каждое состояние суммирует информацию, cодержащуюся в стеке перед ним. — стартовае состояние автомата.Обращение к таблице происходит по паре
, где- — текущее состояние автомата,
- — текущий входной символ;
В таблице информация отображается слудующим образом:
- переход в стостояние
- свертка по правилу ,
- допуск ,
- ошибка .
Алгоритм
- Программа читает символ из входной цепочки.
- Обращается к утравляющей таблице.
- Совершает соответствующее действие.
- Возвращается к первому пункту, пока входная цепочка не закончится.
bool algorithmLR(w: string) curToken — указатель на перый символ в строке w while цепочка не закончилась s = top() a = w[ip] if action [s, a] == shift s’ push(a) push(s’) ip++ else if action [s, a] == reduce Afor j = 1 to pop() pop() s’ = top() push(A) push(goto [s’, A]) Вывод правила (A ) else if action [s, a] == accept return true else return false
|
Функция
получает состояние и символ грамматики и выдает состояние. Функция , строящаяся по грамматике , есть функция переходов детерминированного магазинного автомата, который распознает язык, порождаемый грамматикой .См. также
Источники информации
- Альфред Ахо, Рави Сети, Джеффри Ульман. Компиляторы. Принципы, технологии, инструменты. Издательство Вильямс, 2003. Стр. 301 - 326.
- Терехов Ан.А., Вояковская Н., Булычев Д., Москаль А. - Разработка компиляторов на платформе .NET - Восходящие анализаторы
- Б.К.Мартыненко. Языки и трансляции. Стр. 198 - 223