Дан контекст формальных языков: приведите пример регулярного языка, контекстно-свободного языка и языка, не порождаемого контекстно-свободной грамматикой; объясните методы доказательства нерегулярности и неконтекстно-свободности (например, леммы о накачке) и применимость этих классов к синтаксическому анализу языков программирования
Примеры - Регулярный язык: Lreg={w∈{a,b}∗∣wL_{reg}=\{w\in\{a,b\}^*\mid wLreg={w∈{a,b}∗∣w содержит чётное число символов a}a\}a} (или проще: регулярное выражение (b∗ab∗ab∗)∗(b^*ab^*ab^*)^*(b∗ab∗ab∗)∗). - Контекстно‑свободный язык: Lcf={anbn∣n≥0}L_{cf}=\{a^n b^n\mid n\ge 0\}Lcf={anbn∣n≥0}. - Не порождаемый КС‑грамматикой (не-КС): Lnon={anbncn∣n≥0}L_{non}=\{a^n b^n c^n\mid n\ge 0\}Lnon={anbncn∣n≥0}. Методы доказательства нерегулярности 1. Лемма о накачке для регулярных языков (формулировка): существует число ppp (порог) такое, что любое слово s∈Ls\in Ls∈L с ∣s∣≥p|s|\ge p∣s∣≥p можно разложить как s=xyzs=xyzs=xyz с условиями ∣xy∣≤p|xy|\le p∣xy∣≤p, ∣y∣≥1|y|\ge 1∣y∣≥1, и для всех i≥0i\ge 0i≥0 слово xyiz∈Lx y^i z\in Lxyiz∈L. Применение (пример): допустим язык {anbn}\{a^n b^n\}{anbn} регулярный. Пусть ppp — порог, возьмём s=apbps=a^p b^ps=apbp. По лемме s=xyzs=xyzs=xyz и yyy состоит только из aaa. Для i=0i=0i=0 получаем xzx zxz с меньше чем ppp символами aaa и ppp символами bbb — не в языке. Противоречие → язык не регулярный. 2. Альтернативы/усиления: теорема Майхила–Нерода (количество различимых по префиксам эквивалентных классов бесконечно ⇒ не регулярный) и замыкательные свойства регулярных языков (например, пересечение с регулярным языком даёт регулярный язык) используются для конструктивных доказательств. Методы доказательства неконтекстно‑свободности 1. Лемма о накачке для КС‑языков (Bar‑Hillel): существует порог ppp такой, что любое s∈Ls\in Ls∈L с ∣s∣≥p|s|\ge p∣s∣≥p раскладывается как s=uvwxys=uv w x ys=uvwxy с ∣vwx∣≤p|vwx|\le p∣vwx∣≤p, ∣vx∣≥1|vx|\ge 1∣vx∣≥1 и для всех i≥0i\ge 0i≥0 слово uviwxiy∈Lu v^i w x^i y\in Luviwxiy∈L. Применение (пример): предположим Lnon={anbncn}L_{non}=\{a^n b^n c^n\}Lnon={anbncn} — КС. Пусть ppp и возьмём s=apbpcps=a^p b^p c^ps=apbpcp. По условию ∣vwx∣≤p|vwx|\le p∣vwx∣≤p, значит позиция vwxvwxvwx попадает максимум в две соседние группы символов (не во все три). При накачке i≠1i\ne 1i=1 числа одной либо двух букв изменятся, а остальные останутся прежними → соотношение n,n,nn,n,nn,n,n нарушается → противоречие. Значит LnonL_{non}Lnon не КС. 2. Огден (Ogden) — более сильная лемма: можно пометить ppp позиций так, чтобы образец накачки обязательно затрагивал помечённые позиции; полезна, когда стандартная лемма даёт сложные случаи. 3. Замыкательные свойства: класс КС замкнут относительно пересечения с регулярными языками. Часто берут предполагаемый КС‑язык LLL, пересекают с подходящим регулярным RRR так, чтобы L∩RL\cap RL∩R было равным известному не‑КС языку (или вида, для которого можно применить лемму) — и получают противоречие. Применимость к синтаксическому анализу языков программирования - Лексический анализ: токены обычно описывают регулярными языками (регулярные выражения, ДКА). - Синтаксический анализ (парсинг): большая часть синтаксиса языков программирования описывается КС‑грамматиками; для детерминированных КС‑грамматик используются алгоритмы LL(k), LR(k), LALR, GLR и т.п. Эти алгоритмы эффективны и практичны. - Ограничения: некоторые языковые конструкции по сути контекстно‑чувствительны (например, проверка совпадения объявлений/использований, проверка типов, отступы в Python в некотором смысле) — это решается не расширением формальной грамматики до полной контекстно‑чувствительности, а семантическим анализом, атрибутными грамматиками, либо простыми доп. проверками/предобработкой (либо с помощью механик в PEG, семантических предикатов и т.д.). Вывод: регулярные языки подходят для лексики; КС‑языки покрывают основную часть синтаксиса и позволяют эффективный парсинг; более сложные свойства языка обычно обрабатывают семантикой и дополнительными механизмами, а не чисто более сильными грамматиками.
- Регулярный язык: Lreg={w∈{a,b}∗∣wL_{reg}=\{w\in\{a,b\}^*\mid wLreg ={w∈{a,b}∗∣w содержит чётное число символов a}a\}a} (или проще: регулярное выражение (b∗ab∗ab∗)∗(b^*ab^*ab^*)^*(b∗ab∗ab∗)∗).
- Контекстно‑свободный язык: Lcf={anbn∣n≥0}L_{cf}=\{a^n b^n\mid n\ge 0\}Lcf ={anbn∣n≥0}.
- Не порождаемый КС‑грамматикой (не-КС): Lnon={anbncn∣n≥0}L_{non}=\{a^n b^n c^n\mid n\ge 0\}Lnon ={anbncn∣n≥0}.
Методы доказательства нерегулярности
1. Лемма о накачке для регулярных языков (формулировка): существует число ppp (порог) такое, что любое слово s∈Ls\in Ls∈L с ∣s∣≥p|s|\ge p∣s∣≥p можно разложить как s=xyzs=xyzs=xyz с условиями ∣xy∣≤p|xy|\le p∣xy∣≤p, ∣y∣≥1|y|\ge 1∣y∣≥1, и для всех i≥0i\ge 0i≥0 слово xyiz∈Lx y^i z\in Lxyiz∈L.
Применение (пример): допустим язык {anbn}\{a^n b^n\}{anbn} регулярный. Пусть ppp — порог, возьмём s=apbps=a^p b^ps=apbp. По лемме s=xyzs=xyzs=xyz и yyy состоит только из aaa. Для i=0i=0i=0 получаем xzx zxz с меньше чем ppp символами aaa и ppp символами bbb — не в языке. Противоречие → язык не регулярный.
2. Альтернативы/усиления: теорема Майхила–Нерода (количество различимых по префиксам эквивалентных классов бесконечно ⇒ не регулярный) и замыкательные свойства регулярных языков (например, пересечение с регулярным языком даёт регулярный язык) используются для конструктивных доказательств.
Методы доказательства неконтекстно‑свободности
1. Лемма о накачке для КС‑языков (Bar‑Hillel): существует порог ppp такой, что любое s∈Ls\in Ls∈L с ∣s∣≥p|s|\ge p∣s∣≥p раскладывается как s=uvwxys=uv w x ys=uvwxy с ∣vwx∣≤p|vwx|\le p∣vwx∣≤p, ∣vx∣≥1|vx|\ge 1∣vx∣≥1 и для всех i≥0i\ge 0i≥0 слово uviwxiy∈Lu v^i w x^i y\in Luviwxiy∈L.
Применение (пример): предположим Lnon={anbncn}L_{non}=\{a^n b^n c^n\}Lnon ={anbncn} — КС. Пусть ppp и возьмём s=apbpcps=a^p b^p c^ps=apbpcp. По условию ∣vwx∣≤p|vwx|\le p∣vwx∣≤p, значит позиция vwxvwxvwx попадает максимум в две соседние группы символов (не во все три). При накачке i≠1i\ne 1i=1 числа одной либо двух букв изменятся, а остальные останутся прежними → соотношение n,n,nn,n,nn,n,n нарушается → противоречие. Значит LnonL_{non}Lnon не КС.
2. Огден (Ogden) — более сильная лемма: можно пометить ppp позиций так, чтобы образец накачки обязательно затрагивал помечённые позиции; полезна, когда стандартная лемма даёт сложные случаи.
3. Замыкательные свойства: класс КС замкнут относительно пересечения с регулярными языками. Часто берут предполагаемый КС‑язык LLL, пересекают с подходящим регулярным RRR так, чтобы L∩RL\cap RL∩R было равным известному не‑КС языку (или вида, для которого можно применить лемму) — и получают противоречие.
Применимость к синтаксическому анализу языков программирования
- Лексический анализ: токены обычно описывают регулярными языками (регулярные выражения, ДКА).
- Синтаксический анализ (парсинг): большая часть синтаксиса языков программирования описывается КС‑грамматиками; для детерминированных КС‑грамматик используются алгоритмы LL(k), LR(k), LALR, GLR и т.п. Эти алгоритмы эффективны и практичны.
- Ограничения: некоторые языковые конструкции по сути контекстно‑чувствительны (например, проверка совпадения объявлений/использований, проверка типов, отступы в Python в некотором смысле) — это решается не расширением формальной грамматики до полной контекстно‑чувствительности, а семантическим анализом, атрибутными грамматиками, либо простыми доп. проверками/предобработкой (либо с помощью механик в PEG, семантических предикатов и т.д.).
Вывод: регулярные языки подходят для лексики; КС‑языки покрывают основную часть синтаксиса и позволяют эффективный парсинг; более сложные свойства языка обычно обрабатывают семантикой и дополнительными механизмами, а не чисто более сильными грамматиками.