Дана контекстно‑свободная грамматика G: S -> S S | 'a' | 'b' — докажите её неоднозначность на конкретном примере строки, затем постройте недвусмысленную грамматику, задающую тот же язык (все непустые строки над {a,b}), и опишите алгоритм синтаксического разбора для вашей грамматики с доказательством корректности
1) Доказательство неоднозначности (конкретный пример). Возьмём строку aaaaaaaaa. Для грамматики S→S S∣a∣bS \to S\,S \mid a \mid bS→SS∣a∣b
есть, например, две различные левого-порядка продуктивности (и соответствующие разные деревья): Вариант A: S⇒S S⇒S S S⇒a S S⇒a a S⇒a a a.
S \Rightarrow S\,S \Rightarrow S\,S\,S \Rightarrow a\,S\,S \Rightarrow a\,a\,S \Rightarrow a\,a\,a. S⇒SS⇒SSS⇒aSS⇒aaS⇒aaa. Вариант B: S⇒S S⇒a S⇒a S S⇒a a S⇒a a a.
S \Rightarrow S\,S \Rightarrow a\,S \Rightarrow a\,S\,S \Rightarrow a\,a\,S \Rightarrow a\,a\,a. S⇒SS⇒aS⇒aSS⇒aaS⇒aaa. Эти два вывода дают разные структуры разбора (разные бинарные скобочные разбиения): ((a a) a)и(a (a a)),
((a\,a)\,a)\quad\text{и}\quad (a\,(a\,a)), ((aa)a)и(a(aa)),
то есть одна и та же строка порождается двумя различными синтаксическими деревьями. Следовательно грамматика неоднозначна. 2) Недвусмысленная грамматика того же языка (все непустые строки над {a,b}\{a,b\}{a,b}). Возьмём грамматику S→a∣b∣a S∣b S.
S \to a \mid b \mid a\,S \mid b\,S. S→a∣b∣aS∣bS.
Она порождает ровно все непустые строки над {a,b}\{a,b\}{a,b}: каждое применение продукции добавляет в начало (первый символ строки), а базовые продукции дают последний символ. 3) Доказательство эквивалентности и недвусмысленности. - Покажем, что грамматика порождает любое w∈{a,b}+w\in\{a,b\}^+w∈{a,b}+. Пусть w=x1x2…xnw=x_1x_2\ldots x_nw=x1x2…xn (xi∈{a,b}x_i\in\{a,b\}xi∈{a,b}, n≥1n\ge1n≥1). Тогда последовательность продукций S⇒x1S⇒x1x2S⇒⋯⇒x1…xn−1S⇒x1…xn
S\Rightarrow x_1 S\Rightarrow x_1 x_2 S\Rightarrow\cdots\Rightarrow x_1\ldots x_{n-1} S\Rightarrow x_1\ldots x_{n} S⇒x1S⇒x1x2S⇒⋯⇒x1…xn−1S⇒x1…xn
(в последнем шаге продукция S→xnS\to x_nS→xn) даёт www. - Обратно, любая продукция данной грамматики либо даёт строку длины 111 (aaa или bbb), либо снимает первый символ и рекурсивно порождает остаток. Значит язык равен {a,b}+\{a,b\}^+{a,b}+. - Недвусмысленность: по индукции по длине строки. Для ∣w∣=1|w|=1∣w∣=1 есть ровно одна продукция (S→aS\to aS→a или S→bS\to bS→b). Пусть для всех строк длины <n<n<n разбор уникален. Для ∣w∣=n≥2|w|=n\ge2∣w∣=n≥2 первый символ x1x_1x1 однозначно определяет, какая продукция использована в корне (S→x1S\to x_1S→x1 если n=1n=1n=1, иначе S→x1SS\to x_1 SS→x1S). После этого остаётся разбирать хвост x2…xnx_2\ldots x_nx2…xn длины n−1n-1n−1, и по предположению индукции его разбор уникален. Следовательно разбор для www единственен. Значит грамматика недвусмысленна. 4) Алгоритм синтаксического разбора (и доказательство корректности). Алгоритм (итеративный, линейный): - Вход: строка www. - Если ∣w∣=0|w|=0∣w∣=0 — отклонить (грамматика даёт только непустые строки). - Для i от 111 до ∣w∣−1|w|-1∣w∣−1: - проверять, что wi∈{a,b}w_i\in\{a,b\}wi∈{a,b}; записать производство S→wiSS\to w_i SS→wiS. - Проверить w∣w∣∈{a,b}w_{|w|}\in\{a,b\}w∣w∣∈{a,b}; записать производство S→w∣w∣S\to w_{|w|}S→w∣w∣. - Построенные последовательность продукций даёт вывод для www. Сложность: один проход по символам, то есть O(∣w∣)O(|w|)O(∣w∣). Доказательство корректности: - Корректность (soundness): каждая записанная продукция допустима в грамматике, и их последовательное применение даёт ровно www (см. конструкцию в пункте 3). - Полнота: если www порождается грамматикой, то первый символ x1x_1x1 обязано появиться из продукции вида S→x1SS\to x_1 SS→x1S (если ∣w∣>1|w|>1∣w∣>1) или S→x1S\to x_1S→x1 (если ∣w∣=1|w|=1∣w∣=1); поэтому алгоритм, который строго следует первому символу и рекурсивно разбирает хвост, восстановит этот единственный разбор. По индукции на длину алгоритм найдёт и единственный возможный разбор. Таким образом предложенная грамматика задаёт тот же язык, она недвусмысленна, и приведённый линейный алгоритм корректно и эффективно строит её единственный синтаксический разбор.
Возьмём строку aaaaaaaaa. Для грамматики
S→S S∣a∣bS \to S\,S \mid a \mid bS→SS∣a∣b есть, например, две различные левого-порядка продуктивности (и соответствующие разные деревья):
Вариант A:
S⇒S S⇒S S S⇒a S S⇒a a S⇒a a a. S \Rightarrow S\,S \Rightarrow S\,S\,S \Rightarrow a\,S\,S \Rightarrow a\,a\,S \Rightarrow a\,a\,a.
S⇒SS⇒SSS⇒aSS⇒aaS⇒aaa.
Вариант B:
S⇒S S⇒a S⇒a S S⇒a a S⇒a a a. S \Rightarrow S\,S \Rightarrow a\,S \Rightarrow a\,S\,S \Rightarrow a\,a\,S \Rightarrow a\,a\,a.
S⇒SS⇒aS⇒aSS⇒aaS⇒aaa.
Эти два вывода дают разные структуры разбора (разные бинарные скобочные разбиения):
((a a) a)и(a (a a)), ((a\,a)\,a)\quad\text{и}\quad (a\,(a\,a)),
((aa)a)и(a(aa)), то есть одна и та же строка порождается двумя различными синтаксическими деревьями. Следовательно грамматика неоднозначна.
2) Недвусмысленная грамматика того же языка (все непустые строки над {a,b}\{a,b\}{a,b}).
Возьмём грамматику
S→a∣b∣a S∣b S. S \to a \mid b \mid a\,S \mid b\,S.
S→a∣b∣aS∣bS. Она порождает ровно все непустые строки над {a,b}\{a,b\}{a,b}: каждое применение продукции добавляет в начало (первый символ строки), а базовые продукции дают последний символ.
3) Доказательство эквивалентности и недвусмысленности.
- Покажем, что грамматика порождает любое w∈{a,b}+w\in\{a,b\}^+w∈{a,b}+. Пусть w=x1x2…xnw=x_1x_2\ldots x_nw=x1 x2 …xn (xi∈{a,b}x_i\in\{a,b\}xi ∈{a,b}, n≥1n\ge1n≥1). Тогда последовательность продукций
S⇒x1S⇒x1x2S⇒⋯⇒x1…xn−1S⇒x1…xn S\Rightarrow x_1 S\Rightarrow x_1 x_2 S\Rightarrow\cdots\Rightarrow x_1\ldots x_{n-1} S\Rightarrow x_1\ldots x_{n}
S⇒x1 S⇒x1 x2 S⇒⋯⇒x1 …xn−1 S⇒x1 …xn (в последнем шаге продукция S→xnS\to x_nS→xn ) даёт www.
- Обратно, любая продукция данной грамматики либо даёт строку длины 111 (aaa или bbb), либо снимает первый символ и рекурсивно порождает остаток. Значит язык равен {a,b}+\{a,b\}^+{a,b}+.
- Недвусмысленность: по индукции по длине строки. Для ∣w∣=1|w|=1∣w∣=1 есть ровно одна продукция (S→aS\to aS→a или S→bS\to bS→b). Пусть для всех строк длины <n<n<n разбор уникален. Для ∣w∣=n≥2|w|=n\ge2∣w∣=n≥2 первый символ x1x_1x1 однозначно определяет, какая продукция использована в корне (S→x1S\to x_1S→x1 если n=1n=1n=1, иначе S→x1SS\to x_1 SS→x1 S). После этого остаётся разбирать хвост x2…xnx_2\ldots x_nx2 …xn длины n−1n-1n−1, и по предположению индукции его разбор уникален. Следовательно разбор для www единственен. Значит грамматика недвусмысленна.
4) Алгоритм синтаксического разбора (и доказательство корректности).
Алгоритм (итеративный, линейный):
- Вход: строка www.
- Если ∣w∣=0|w|=0∣w∣=0 — отклонить (грамматика даёт только непустые строки).
- Для i от 111 до ∣w∣−1|w|-1∣w∣−1:
- проверять, что wi∈{a,b}w_i\in\{a,b\}wi ∈{a,b}; записать производство S→wiSS\to w_i SS→wi S.
- Проверить w∣w∣∈{a,b}w_{|w|}\in\{a,b\}w∣w∣ ∈{a,b}; записать производство S→w∣w∣S\to w_{|w|}S→w∣w∣ .
- Построенные последовательность продукций даёт вывод для www.
Сложность: один проход по символам, то есть O(∣w∣)O(|w|)O(∣w∣).
Доказательство корректности:
- Корректность (soundness): каждая записанная продукция допустима в грамматике, и их последовательное применение даёт ровно www (см. конструкцию в пункте 3).
- Полнота: если www порождается грамматикой, то первый символ x1x_1x1 обязано появиться из продукции вида S→x1SS\to x_1 SS→x1 S (если ∣w∣>1|w|>1∣w∣>1) или S→x1S\to x_1S→x1 (если ∣w∣=1|w|=1∣w∣=1); поэтому алгоритм, который строго следует первому символу и рекурсивно разбирает хвост, восстановит этот единственный разбор. По индукции на длину алгоритм найдёт и единственный возможный разбор.
Таким образом предложенная грамматика задаёт тот же язык, она недвусмысленна, и приведённый линейный алгоритм корректно и эффективно строит её единственный синтаксический разбор.