LL(k)-грамматики, множества FIRST и FOLLOW — различия между версиями
Shersh (обсуждение | вклад) |
Shersh (обсуждение | вклад) (добавлены два следствия) |
||
| Строка 11: | Строка 11: | ||
* <tex> S \Rightarrow^* p A \beta \Rightarrow p \alpha \beta \Rightarrow^* p y \eta </tex> | * <tex> S \Rightarrow^* p A \beta \Rightarrow p \alpha \beta \Rightarrow^* p y \eta </tex> | ||
* <tex> S \Rightarrow^* p A \beta \Rightarrow p \alpha' \beta \Rightarrow^* p y \xi </tex> | * <tex> S \Rightarrow^* p A \beta \Rightarrow p \alpha' \beta \Rightarrow^* p y \xi </tex> | ||
| − | где <tex> p </tex> и <tex> y </tex> {{---}} цепочки из терминалов, уже разобранная часть слова <tex> w </tex>, <tex> A </tex> {{---}} нетерминал грамматики, в которой есть правила <tex> A \ | + | где <tex> p </tex> и <tex> y </tex> {{---}} цепочки из терминалов, уже разобранная часть слова <tex> w </tex>, <tex> A </tex> {{---}} нетерминал грамматики, в которой есть правила <tex> A \to \alpha </tex> и <tex> A \to \alpha' </tex>, причём <tex> \alpha, \alpha', \beta, \eta, \xi </tex> {{---}} последовательности из терминалов и нетерминалов.<br> |
Тогда если при выполнении условий, что <tex> |y| = k </tex> или <tex> |y| < k, \eta = \xi = \varepsilon </tex>, верно, что <tex> \alpha = \alpha' </tex>, то <tex> \Gamma </tex> называется '''LL(k)-грамматикой'''. | Тогда если при выполнении условий, что <tex> |y| = k </tex> или <tex> |y| < k, \eta = \xi = \varepsilon </tex>, верно, что <tex> \alpha = \alpha' </tex>, то <tex> \Gamma </tex> называется '''LL(k)-грамматикой'''. | ||
}} | }} | ||
| Строка 36: | Строка 36: | ||
Множества <tex> \mathrm{FIRST} </tex> и <tex> \mathrm{FOLLOW} </tex> могут отличаться даже для одной грамматики, если она задана разными правилами. Рассмотрим пример двух различных грамматик для языка правильных скобочных последовательностей. | Множества <tex> \mathrm{FIRST} </tex> и <tex> \mathrm{FOLLOW} </tex> могут отличаться даже для одной грамматики, если она задана разными правилами. Рассмотрим пример двух различных грамматик для языка правильных скобочных последовательностей. | ||
| − | * <tex> A \ | + | * <tex> A \to (A)A \mid \varepsilon </tex> |
| − | * <tex> B \ | + | * <tex> B \to BB \mid (B) \mid \varepsilon </tex> |
{| style="background-color:#CCC;margin:0.5px" | {| style="background-color:#CCC;margin:0.5px" | ||
| Строка 58: | Строка 58: | ||
|id=thLL1 | |id=thLL1 | ||
|statement= <tex>\Gamma =\langle \Sigma, N, S, P \rangle</tex> {{---}} LL(1)-грамматика <tex> \Leftrightarrow </tex> | |statement= <tex>\Gamma =\langle \Sigma, N, S, P \rangle</tex> {{---}} LL(1)-грамматика <tex> \Leftrightarrow </tex> | ||
| − | # <tex> A \ | + | # <tex> A \to \alpha,\ A \to \beta, A \in N \ \Rightarrow \ \mathrm{FIRST}(\alpha) \cap \mathrm{FIRST}(\beta) = \varnothing</tex> |
| − | # <tex> A \ | + | # <tex> A \to \alpha,\ A \to \beta, A \in N,\ \varepsilon \in \mathrm{FIRST}(\alpha) \ \Rightarrow \ \mathrm{FOLLOW}(A) \cap \mathrm{FIRST}(\beta) = \varnothing</tex> |
|proof= | |proof= | ||
* <tex> \Leftarrow </tex> | * <tex> \Leftarrow </tex> | ||
| Строка 67: | Строка 67: | ||
}} | }} | ||
=== Следствия === | === Следствия === | ||
| + | Сформулируем несколько важных cледствий из теоремы. | ||
| + | ==== Левая рекурсия ==== | ||
| + | {{Утверждение | ||
| + | |author=1 | ||
| + | |statement=Грамматика <tex> \Gamma </tex> cодержит левую рекурсию <tex> \Rightarrow \ \Gamma </tex> не является LL(1)-грамматикой. | ||
| + | |proof= | ||
| + | Если грамматика содержит левую рекурсию, значит, в ней существует какой-то нетерминал <tex> A </tex> с правилами <tex> A \to A \alpha \mid \beta </tex>, где <tex> \beta </tex> {{---}} строка из терминалов и нетерминалов, не начинающаяся с <tex> A </tex>. | ||
| + | |||
| + | Тогда понятно, что <tex> \mathrm{FIRST}(A\alpha) \cap \mathrm{FIRST}(\beta) \ne \varnothing </tex>, и это противоречит первому условию [[#thLL1 | теоремы]]. | ||
| + | }} | ||
| + | Чтобы избавиться от левой рекурсии, можно воспользоваться [[Устранение левой рекурсии | алгоритмом устранения левой рекурсии]]. | ||
| + | ==== Левая факторизация ==== | ||
| + | {{Утверждение | ||
| + | |author=2 | ||
| + | |statement=Грамматика <tex> \Gamma </tex> cодержит правое ветвление <tex> \Rightarrow \ \Gamma </tex> не является LL(1)-грамматикой. | ||
| + | |proof= | ||
| + | Наличие в грамматике правого ветвления означает, что существует правило <tex> A \to \alpha \beta \mid \alpha \gamma </tex>. | ||
| + | |||
| + | Очевидно, что <tex> \mathrm{FIRST}(\alpha \beta) \cap \mathrm{FIRST}(\alpha \gamma) \ne \varnothing </tex>. Поэтому грамматика не будет LL(1)-грамматикой по первому условию [[#thLL1 | теоремы]]. | ||
| + | }} | ||
| + | ===== Алгоритм устранения правого ветвленения ===== | ||
| + | <tex> A \to \alpha \beta_1 \mid \ldots \mid \alpha \beta_n \mid \gamma_1 \mid \ldots \mid \gamma_m </tex> | ||
| + | Однако отсутствие левой рекурсии и правого ветвления в грамматике не является необходимым условием того, что она будет LL(1)-грамматикой. После их устранения грамматика всё ещё может остаться не LL(1)-грамматикой. | ||
== См. также == | == См. также == | ||
== Источники информации == | == Источники информации == | ||
Версия 13:27, 28 июня 2014
Наибольший интерес в построении синтаксических анализаторов (парсеров) представляют LL(1)-грамматики, так как для них возможно построение нисходящих парсеров без возврата, то есть без корректировки выбранных правил в грамматике. LL(1)-грамматики являются подмножеством КС-грамматик. Однако для достаточно большого количества формальных языков можно построить LL(1)-грамматику, например, для языка арифметических выражений и даже для некоторых языков программирования, в частности можно и для языка Java.
Содержание
LL(k)-грамматика
Дадим теперь формально определение LL(k)-грамматики.
| Определение: |
| Пусть — КС-грамматика. Рассмотрим два произвольных левосторонних вывода слова в этой грамматике:
где и — цепочки из терминалов, уже разобранная часть слова , — нетерминал грамматики, в которой есть правила и , причём — последовательности из терминалов и нетерминалов. |
LL(1)-грамматика является частным случаем. Её определение почти такое же, только вместо строки один символ .
Неформально это означает, что, посмотрев на очередной символ после уже выведенной части слова, можно однозначно определить, какое правило из грамматики выбрать.
FIRST и FOLLOW
Ключевую роль в построении парсеров для LL(1)-грамматик играю множества и .
Пусть — символ из алфавита , — строки из нетерминалов и терминалов (возможно пустые), — нетерминалы грамматики (начальный и произвольный соответственно), — символ окончания слова. Тогда определим и следующим образом:
| Определение: |
| Определение: |
Другими словами, — все символы (терминалы), с которых могут начинаться всевозможные выводы из , а — всевозможные символы, которые встречаются после нетерминала во всех правилах грамматики, достижимых из начального.
Примеры
Множества и могут отличаться даже для одной грамматики, если она задана разными правилами. Рассмотрим пример двух различных грамматик для языка правильных скобочных последовательностей.
| Правило | FIRST | FOLLOW |
|---|---|---|
| A | ||
| B |
Теорема о связи LL(1)-грамматики с множествами FIRST и FOLLOW
Далее будет показано, как множества и связаны с понятием LL(1)-грамматики.
| Теорема: |
— LL(1)-грамматика
|
| Доказательство: |
|
очевидно |
Следствия
Сформулируем несколько важных cледствий из теоремы.
Левая рекурсия
| Утверждение (1): |
Грамматика cодержит левую рекурсию не является LL(1)-грамматикой. |
|
Если грамматика содержит левую рекурсию, значит, в ней существует какой-то нетерминал с правилами , где — строка из терминалов и нетерминалов, не начинающаяся с . Тогда понятно, что , и это противоречит первому условию теоремы. |
Чтобы избавиться от левой рекурсии, можно воспользоваться алгоритмом устранения левой рекурсии.
Левая факторизация
| Утверждение (2): |
Грамматика cодержит правое ветвление не является LL(1)-грамматикой. |
|
Наличие в грамматике правого ветвления означает, что существует правило . Очевидно, что . Поэтому грамматика не будет LL(1)-грамматикой по первому условию теоремы. |
Алгоритм устранения правого ветвленения
Однако отсутствие левой рекурсии и правого ветвления в грамматике не является необходимым условием того, что она будет LL(1)-грамматикой. После их устранения грамматика всё ещё может остаться не LL(1)-грамматикой.