Skip to content

Commit 1ced7c1

Browse files
committed
Попытка расширить сравнение LL и LR.
1 parent d50d957 commit 1ced7c1

5 files changed

Lines changed: 283 additions & 9 deletions

File tree

book_structure.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
Условные обозначения статусов:
5-
- ✅ — раздел полностью написан
5+
- ✅ — раздел полностью написан и готов к внимательной вычитке. Могут потребоваться доработки, связанные с добавлением новых частей.
66
- ⚠️ — раздел присутствует частично или требует доработки
77
- ❌ — содержание раздела отсутствует, есть только заготовка
88

@@ -79,9 +79,9 @@
7979
### Глава 6. Контекстно-свободные языки и грамматики — `Context-Free_Languages.tex` — ⚠️
8080

8181
- ✅ Раздел "Основные определения"
82-
- ⚠️ Раздел "Расширенная форма Бэкуса-Наура"
82+
- Раздел "Расширенная форма Бэкуса-Наура"
8383
- ✅ Раздел "Рекурсивные автоматы и сети"
84-
- ⚠️ Раздел "Дерево вывода"
84+
- Раздел "Дерево вывода"
8585
- ⚠️ Раздел "Сжатое представление леса разбора"
8686
- ✅ Раздел "Пустота КС-языка"
8787
- ✅ Раздел "Нормальная форма Хомского"
Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
\section{Сравнение классов LL и LR}
2+
\label{sec:LLvsLR}
3+
\tikzsetfigurename{LLvsLR_}
4+
5+
\mytodo{Перечитаь раздел. Провреить корректность. Поправить вёрстку.}
26

37
Иерархию языков, распознаваемых различными классами алгоритмов, можно представить как изображено на рисунке~\ref{fig:ll_lr_comparison}.
48

@@ -10,9 +14,85 @@ \section{Сравнение классов LL и LR}
1014
\label{fig:ll_lr_comparison}
1115
\end{marginfigure}
1216

13-
Из диаграммы видно, что класс языков, распознаваемых LL(k) алгоритмом уже, чем класс языков, распознаваемый LR(k) алгоритмом, при любом конечном $k$. Приведём несколько примеров.
14-
\begin{enumerate}
15-
\item $L = \{a^mb^nc \mid m \geq n \geq 0\} $ является LR(0), но для него не существует LL(1) грамматики.
16-
\item $L = \{ a^n b^n + a^n c^n \mid n > 0\}$ является LR, но не LL.
17-
\item Больше примеров можно найти в работе Джона Битти~\cite{BEATTY1980193}.
18-
\end{enumerate}
17+
Из диаграммы видно, что класс языков, распознаваемых $LL(k)$ алгоритмом, уже, чем класс языков, распознаваемых $LR(k)$ алгоритмом, при любом конечном $k$. Ниже мы разберём два классических примера языков, демонстрирующих данное различие.
18+
19+
\begin{example}
20+
\label{ex:ll_lr_ambnc}
21+
Рассмотрим язык $L_1 = \{ a^m b^n c \mid m \geq n \geq 0\}$. Покажем, что он является $LR(0)$, но не является $LL(1)$.
22+
23+
Язык $L_1$ порождается следующей грамматикой $G_1 = \langle \{S, T\}, \{a, b, c\}, P, S \rangle$, где $P$ состоит из правил:
24+
\begin{align*}
25+
S &\to a S \mid T c \mid c \\
26+
T &\to a T b \mid a b
27+
\end{align*}
28+
29+
Интуитивно, $T$ порождает $a^n b^n$ (n \geq 1), $S \to a S$ добавляет <<лишние>> $a$, а $S \to T c$ и $S \to c$ завершают вывод, добавляя терминальный символ $c$.
30+
31+
Покажем, что $G_1$ является $LR(0)$. Расширим грамматику, пронумеровав продукции:
32+
\begin{align*}
33+
(0)\; S' &\to S \$ & (3)\; S &\to c \\
34+
(1)\; S &\to a S & (4)\; T &\to a T b \\
35+
(2)\; S &\to T c & (5)\; T &\to a b
36+
\end{align*}
37+
38+
$LR(0)$-автомат для расширенной грамматики $G_1$ \fixit{изображён}{Нормально разложить автомат. Провреить, что он кореектен.} \fixit{на рисунке}{Нормально оформить оисунок и ссылку на него (через figure и т.д.)}
39+
40+
\begin{center}
41+
\input{part_02_Foundations/chapter_07_ClassicalParsing/figures/06_LLvsLR/example1_automaton}
42+
\end{center}
43+
44+
Состояния, содержащие пункты свёртки~--- это 3 ($S \to c\cdot$), 5 ($S \to aS\cdot$), 7 ($T \to ab\cdot$), 8 ($T \to aTb\cdot$) и 9 ($S \to Tc\cdot$). Каждое из них содержит ровно один такой пункт и не содержит пунктов сдвига. Конфликтов нет~--- грамматика $LR(0)$.
45+
46+
Теперь покажем, что $G_1$ не является $LL(1)$. Вычислим множества $\first$:
47+
\[
48+
\first(S) = \{a, c\}, \qquad \first(T) = \{a\}.
49+
\]
50+
Для продукций $S$ \fixit{имеем:}{Поправить вёрстку}
51+
\[
52+
\first(a S) = \{a\}, \qquad \first(T c) = \first(T) \cup (\first(c) \text{ т.к. } \varepsilon \notin \first(T)) = \{a\}.
53+
\]
54+
Пересечение $\first(a S) \cap \first(T c) = \{a\}$ непусто. При предпросмотре символа $a$ $LL(1)$-анализатор не может выбрать между продукциями $S \to a S$ и $S \to T c$~--- конфликт.
55+
56+
Более того, $L_1$ не является $LL(k)$ ни для какого фиксированного $k$. Действительно, в любой момент разбора, когда прочитано несколько $a$, необходимо решить, будут ли эти $a$ впоследствии спарены с символами $b$ или останутся <<лишними>>. Разница между числом $a$ и числом $b$ может быть сколь угодно большой, поэтому для принятия верного решения требуется заглянуть за все символы $a$~--- предпросмотр неограниченной глубины. Следовательно, язык принадлежит классу $LR(0)$, но не принадлежит классу $LL(k)$ ни при каком $k$.
57+
\end{example}
58+
59+
\begin{example}
60+
\label{ex:ll_lr_anbnancn}
61+
Рассмотрим язык $L_2 = \{ a^n b^n \mid n > 0\} \cup \{ a^n c^n \mid n > 0\}$. Покажем, что он является $LR(0)$, но не является $LL(k)$ ни для какого $k$.
62+
63+
Язык $L_2$ порождается грамматикой $G_2 = \langle \{S, A, B\}, \{a, b, c\}, P, S \rangle$, где $P$:
64+
\begin{align*}
65+
S &\to A \mid B \\
66+
A &\to a A b \mid a b \\
67+
B &\to a B c \mid a c
68+
\end{align*}
69+
70+
Интуитивно, $A$ порождает $a^n b^n$, а $B$~--- $a^n c^n$ ($n > 0$).
71+
72+
Пронумеруем продукции расширенной грамматики:
73+
\begin{align*}
74+
(0)\; S' &\to S \$ & (3)\; A &\to a A b & (5)\; B &\to a B c \\
75+
(1)\; S &\to A & (4)\; A &\to a b & (6)\; B &\to a c \\
76+
(2)\; S &\to B
77+
\end{align*}
78+
79+
$LR(0)$-автомат для расширенной грамматики $G_2$ \fixit{изображён}{Нормально разложить автомат. Провреить, что он кореектен.} \fixit{на рисунке}{Нормально оформить оисунок и ссылку на него (через figure и т.д.)}.
80+
81+
\begin{center}
82+
\input{part_02_Foundations/chapter_07_ClassicalParsing/figures/06_LLvsLR/example2_automaton}
83+
\end{center}
84+
85+
Состояния, содержащие пункты свёртки~--- это 2 ($S \to A\cdot$), 3 ($S \to B\cdot$), 8 ($A \to ab\cdot$), 9 ($B \to ac\cdot$), 10 ($A \to aAb\cdot$) и 11 ($B \to aBc\cdot$). Как и в первом примере, каждое из них содержит ровно один пункт и не содержит пунктов сдвига. Конфликтов нет~--- грамматика $LR(0)$.
86+
87+
Покажем, что $G_2$ не является $LL(k)$ ни для какого $k$. Вычислим $\first$:
88+
\[
89+
\first(A) = \first(B) = \{a\}.
90+
\]
91+
Поскольку $\first(A) \cap \first(B) = \{a\} \neq \varnothing$, $LL(1)$-анализатор не может выбрать между $S \to A$ и $S \to B$ при предпросмотре символа $a$.
92+
93+
Более того, при любом фиксированном $k$ предпросмотр $k$ символов не помогает: для $n > k$ первые $k$ символов цепочки~--- это $a^k$, и на основании них невозможно определить, с каким символом~--- $b$ или $c$~--- эти $a$ должны быть спарены. Различающий символ находится на позиции $n$, которая может быть сколь угодно большой. Таким образом, $L_2$ не является $LL(k)$ ни для какого конечного $k$.
94+
95+
Данный пример особенно наглядно демонстрирует принципиальное различие между восходящими и нисходящими анализаторами: $LR$-анализатор принимает решение о свёртке, уже увидев различающий символ ($b$ или $c$), в то время как $LL$-анализатор вынужден предсказывать, какую продукцию применять, до того как релевантная информация становится доступной.
96+
\end{example}
97+
98+
Больше примеров языков, разделяющих классы $LL(k)$ и $LR(k)$, можно найти в работе Джона Битти~\sidecite{BEATTY1980193}.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
\begin{tikzpicture}[> = stealth,node distance=3.25cm, on grid, scale=0.8, every node/.style={scale=0.8}]
2+
\node[r_state] (s0)
3+
{
4+
$
5+
\begin{aligned}
6+
S' &\to \cdot S\$ \\
7+
S &\to \cdot aS \\
8+
S &\to \cdot Tc \\
9+
S &\to \cdot c \\
10+
T &\to \cdot aTb \\
11+
T &\to \cdot ab
12+
\end{aligned}
13+
$
14+
};
15+
\node[r_state] (s1) [right=of s0]
16+
{
17+
$ S' \to S \cdot \$ $
18+
};
19+
\node[r_state] (s2) [right=of s1]
20+
{
21+
$ S' \to S\$ \cdot $
22+
};
23+
\node[r_state] (s3) [below=2.5cm of s0]
24+
{
25+
$
26+
\begin{aligned}
27+
S &\to a \cdot S \\
28+
T &\to a \cdot Tb \\
29+
T &\to a \cdot b \\
30+
S &\to \cdot aS \\
31+
S &\to \cdot Tc \\
32+
S &\to \cdot c \\
33+
T &\to \cdot aTb \\
34+
T &\to \cdot ab
35+
\end{aligned}
36+
$
37+
};
38+
\node[r_state] (s4) [right=of s3]
39+
{
40+
$ S \to aS \cdot $
41+
};
42+
\node[r_state] (s5) [right=of s4]
43+
{
44+
$ T \to aT \cdot b $
45+
};
46+
\node[r_state] (s6) [right=of s5]
47+
{
48+
$ T \to aTb \cdot $
49+
};
50+
\node[r_state] (s7) [below=2.5cm of s3, xshift=-1.5cm]
51+
{
52+
$ S \to T \cdot c $
53+
};
54+
\node[r_state] (s8) [below=2.5cm of s4]
55+
{
56+
$ S \to c \cdot $
57+
};
58+
\node[r_state] (s9) [below=2.5cm of s5]
59+
{
60+
$ T \to ab \cdot $
61+
};
62+
\node[r_state] (s10) [below=2.5cm of s6]
63+
{
64+
$ S \to Tc \cdot $
65+
};
66+
67+
\node[num_state] at (s0.north west) {0};
68+
\node[num_state] at (s1.north west) {1};
69+
\node[num_state] at (s2.north west) {acc};
70+
\node[num_state] at (s3.north west) {4};
71+
\node[num_state] at (s4.north west) {5};
72+
\node[num_state] at (s5.north west) {6};
73+
\node[num_state] at (s6.north west) {8};
74+
\node[num_state] at (s7.north west) {2};
75+
\node[num_state] at (s8.north west) {3};
76+
\node[num_state] at (s9.north west) {7};
77+
\node[num_state] at (s10.north west) {9};
78+
79+
\path[->]
80+
(s0) edge [above] node {$S$} (s1)
81+
edge [left] node {$a$} (s3)
82+
edge [right, bend right=25] node {$c$} (s8)
83+
edge [left, bend left=25] node {$T$} (s7)
84+
(s1) edge [above] node {$\$$} (s2)
85+
(s3) edge [loop below] node {$a$} ()
86+
edge [above] node {$S$} (s4)
87+
edge [above, bend left=15] node {$T$} (s5)
88+
edge [above right, bend left=15] node {$c$} (s8)
89+
edge [above right, bend right=20] node {$b$} (s9)
90+
(s5) edge [above] node {$b$} (s6)
91+
(s7) edge [above, bend left=20] node {$c$} (s10)
92+
;
93+
\end{tikzpicture}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
\begin{tikzpicture}[> = stealth,node distance=3.25cm, on grid, scale=0.8, every node/.style={scale=0.8}]
2+
\node[r_state] (s0)
3+
{
4+
$
5+
\begin{aligned}
6+
S' &\to \cdot S\$ \\
7+
S &\to \cdot A \\
8+
S &\to \cdot B \\
9+
A &\to \cdot aAb \\
10+
A &\to \cdot ab \\
11+
B &\to \cdot aBc \\
12+
B &\to \cdot ac
13+
\end{aligned}
14+
$
15+
};
16+
\node[r_state] (s1) [right=of s0]
17+
{
18+
$ S' \to S \cdot \$ $
19+
};
20+
\node[r_state] (s2) [right=of s1]
21+
{
22+
$ S' \to S\$ \cdot $
23+
};
24+
\node[r_state] (s3) [below=2.5cm of s0]
25+
{
26+
$
27+
\begin{aligned}
28+
A &\to a \cdot Ab \\
29+
A &\to a \cdot b \\
30+
B &\to a \cdot Bc \\
31+
B &\to a \cdot c \\
32+
A &\to \cdot aAb \\
33+
A &\to \cdot ab \\
34+
B &\to \cdot aBc \\
35+
B &\to \cdot ac
36+
\end{aligned}
37+
$
38+
};
39+
\node[r_state] (s4) [right=of s3]
40+
{
41+
$ S \to A \cdot $
42+
};
43+
\node[r_state] (s5) [right=of s4]
44+
{
45+
$ S \to B \cdot $
46+
};
47+
\node[r_state] (s6) [below=2.5cm of s3]
48+
{
49+
$ A \to aA \cdot b $
50+
};
51+
\node[r_state] (s7) [below=2.5cm of s4]
52+
{
53+
$ B \to aB \cdot c $
54+
};
55+
\node[r_state] (s8) [below=2.5cm of s6]
56+
{
57+
$ A \to ab \cdot $
58+
};
59+
\node[r_state] (s9) [right=2cm of s8]
60+
{
61+
$ A \to aAb \cdot $
62+
};
63+
\node[r_state] (s10) [below=2.5cm of s7]
64+
{
65+
$ B \to ac \cdot $
66+
};
67+
\node[r_state] (s11) [right=2cm of s10]
68+
{
69+
$ B \to aBc \cdot $
70+
};
71+
72+
\node[num_state] at (s0.north west) {0};
73+
\node[num_state] at (s1.north west) {1};
74+
\node[num_state] at (s2.north west) {acc};
75+
\node[num_state] at (s3.north west) {4};
76+
\node[num_state] at (s4.north west) {2};
77+
\node[num_state] at (s5.north west) {3};
78+
\node[num_state] at (s6.north west) {6};
79+
\node[num_state] at (s7.north west) {7};
80+
\node[num_state] at (s8.north west) {8};
81+
\node[num_state] at (s9.north west) {10};
82+
\node[num_state] at (s10.north west) {9};
83+
\node[num_state] at (s11.north west) {11};
84+
85+
\path[->]
86+
(s0) edge [above] node {$S$} (s1)
87+
edge [left] node {$a$} (s3)
88+
edge [above, bend left=10] node {$A$} (s4)
89+
edge [above, bend right=10] node {$B$} (s5)
90+
(s1) edge [above] node {$\$$} (s2)
91+
(s3) edge [loop below] node {$a$} ()
92+
edge [left] node {$A$} (s6)
93+
edge [left, bend right=20] node {$b$} (s8)
94+
edge [above, bend left=15] node {$B$} (s7)
95+
edge [above left, bend left=25] node {$c$} (s10)
96+
(s6) edge [right] node {$b$} (s9)
97+
(s7) edge [above] node {$c$} (s11)
98+
;
99+
\end{tikzpicture}

tex/part_02_Foundations/chapter_07_ClassicalParsing/main.tex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
\chapter{Классические алгоритмы синтаксического анализа для строк}
33
\tikzsetfigurename{ClassicalParsing_}
44

5+
\mytodo{Унифицировать вёрстку стеков в примерах для LL и LR}
6+
57
В данной главе мы рассмотрим классические алгоритмы синтаксического анализа для строк.
68
Эти алгоритмы составляют фундамент, на котором далее будут построены алгоритмы поиска путей с контекстно-свободными ограничениями в графах (главы~\ref{chpt:CFPQ_CYK}--\ref{chpt:GLR}).
79

0 commit comments

Comments
 (0)