
- •Лекция № 3 теория языков и формальных грамматик
- •3.1 Способы определения языков
- •3.2 Формальные грамматики
- •3.3 Грамматики с ограничениями на правила
- •Лекция № 4 способы записи синтаксиса языка. Распознаватели
- •4.1 Метаязык Хомского
- •4.2 Метаязык Хомского-Щутценберже
- •4.3 Бэкуса-Наура формы (бнф)
- •4.4 Расширенные Бэкуса-Наура формы (рбнф)
- •4.5 Диаграммы Вирта
- •Диаграмм Вирта
- •4.6 Распознаватели
- •Лекция № 5 демонстрационный язык программирования dpl
- •5.1 Синтаксис и семантика dpl
- •5.1.1 Элементарные конструкции
- •5.1.2 Составные конструкции. Организация программы
- •5.1.3 Краткое описание семантики языка
- •5.3 Описание пользовательского синтаксиса с использованием диаграмм Вирта
- •6.2 Транслитератор
- •6.3 Грамматики и распознаватели для лексического анализа
- •6.3.1 Связь между диаграммой Вирта и конечным автоматом
- •В эквивалентный конечный автомат
- •Задающая идентификатор
- •6.3.2 Связь между диаграммами Вирта и праволинейными грамматиками. Преобразование правой рекурсии в итерацию
- •Грамматик в диаграммы Вирта
- •В итеративную диаграмму Вирта
- •Идентификатора в итеративную диаграмму Вирта
- •Идентификатора в итеративную диаграмму Вирта (окончание)
- •6.3.3 Связь между диаграммами Вирта и грамматиками с левой рекурсией. Преобразование левой рекурсии в итерацию
- •В итеративную диаграмму Вирта
- •6.4 Методы лексического анализа
- •6.4.1 Организация непрямого лексического анализатора
- •Лексического анализатора
- •6.4.2 Организация прямого лексического анализатора
- •Прямого лексического анализатора
- •Лекция № 7 лексический анализатор демонстрационного языка программирования
- •7.1 Транслитератор dpl
- •7.1.1 Общая организация транслитератора
- •7.1.2 Программная реализация транслитератора
- •7.2 Непрямой лексический анализатор dpl
- •7.2.1 Диаграммы Вирта для отдельных автоматов непрямого лексического анализатора
- •7.2.1 Программная реализация отдельных автоматов
- •7.2.3 Общая структура непрямого лексического анализатора
- •7.3 Прямой лексический анализатор dpl
- •Прямого лексического анализатора
- •Прямого лексического анализатора (продолжение)
- •Прямого лексического анализатора (окончание)
- •Лекция № 8 общие принципы организации синтаксического разбора
- •8.1 Назначение синтаксического разбора
- •8.2 Классификация методов синтаксического разбора
- •Синтаксического разбора
- •8.3 Методы разбора
- •С операции умножения
- •Распознавателя самых нижних ветвей дерева выступает лексический анализатор
- •8.4 Последовательность разбора
- •8.5 Использование просмотра вперед
- •8.6 Использование возвратов
- •8.7 Выводы
- •Лекция № 9 использование автоматов с магазинной памятью для нисходящего разбора слева направо
- •9.1 Организация автомата с магазинной памятью
- •9.1.1 Операции автомата
- •9.1.2 Распознаватель скобочных выражений
- •9.2 Общая связь между грамматиками и автоматами с магазинной памятью
- •9.3 Связь между s-грамматикой и автоматом с магазинной памятью
- •9.3.1 Обобщенный алгоритм построения нисходящего амп
- •9.4 Построение автомата с магазинной памятью по q-грамматике
- •9.4.1 Построение нисходящего автомата
- •Заменить (αr), Сдвиг
- •Вытолкнуть, Сдвиг.
- •Вытолкнуть.
- •9.4.2 Примеры построения амп по q-грамматике
- •Список использованных источников
- •Содержание
Лекция № 3 теория языков и формальных грамматик
3.1 Способы определения языков
Описание языков программирования во многом опирается на теорию формальных языков. Эта теория является фундаментом для организации синтаксического анализа и перевода.
Существует два основных способа определения языков:
– механизм порождения или генератор;
– механизм распознавания или распознаватель.
Они тесно связаны. Первый обычно используется для описания языков, а второй для их реализации. Оба способа позволяют описать языки конечным образом, несмотря на бесконечное число порождаемых ими цепочек.
Неформально язык L - это множество цепочек конечной длины в алфавите T. Механизм порождения позволяет описать языки с помощью системы правил, называемой грамматикой. Цепочки (предложения) языка строятся в соответствии с этими правилами. Достоинство определения языка с помощью грамматик в том, что операции, производимые в ходе синтаксического анализа и перевода, можно делать проще, если воспользоваться структурой, предписываемой цепочкам с помощью этих грамматик.
Механизм распознавания использует алгоритм, который для произвольной входной цепочки остановится и ответит «да» после конечного числа шагов, если эта цепочка принадлежит языку. Если цепочка не принадлежит языку, алгоритм ответит «нет». Распознаватели используются непосредственно при построении синтаксических анализаторов и являются как бы их формальной моделью. Распознаватели строятся на основе теорий конечных автоматов и автоматов с магазинной памятью.
3.2 Формальные грамматики
Грамматикой называется четверка
G = (N, T, P, S), (3.1)
где N - конечное множество нетерминальных символов
(нетерминалов),
T - множество терминалов (не пересекающихся с N),
S - символ из N, называемый начальным,
Р - конечное подмножество множества,
называемого множеством правил:
.
Множество правил Р описывает процесс порождения цепочек языка. Элемент pi = (, ) множества Р называется правилом (продукцией) и записывается в виде . Здесь и - цепочки, состоящие из терминалов и нетерминалов. Данная запись может читаться одним из следующих способов:
– цепочка порождает цепочку ;
– из цепочки выводится цепочка .
Таким образом, правило P
имеет две части: левую, определяемую, и
правую, подставляемую. То есть правило
pi
- это двойка (pi1,
pi2),
где p i1
=
- цепочка, содержащая хотя бы один
нетерминал, pi2
=
произвольная, возможно пустая цепочка
( - цепочка).
Если цепочка содержит pi1, то, в соответствии с правилом pi, можно образовать новую цепочку , заменив одно вхождение pi1 на pi2. Говорят также, что цепочка выводится из в данной грамматике.
Для описания абстрактных языков в определениях и примерах используются следующие обозначения:
– терминалы обозначаются буквами a,b,c,d или цифрами 0,1, ...,9;
– нетерминалы обозначаются буквами A, B, C, D, S (причем нетерминал S - начальный символ грамматики);
– буквы U, V, ..., Z используются для обозначения отдельных терминалов или нетерминалов;
– через , , ... обозначаются цепочки терминалов и нетерминалов;
– u, v, w, x, y, z - цепочки терминалов;
– для обозначения пустой цепочки (не содержащей ни одного символа) используется знак ;
– знак «» отделяет левую часть правила от правой и читается как «порождает» или «есть по определению». Например, A cd, читается как «A порождает cd».
Эти обозначения определяют некоторый язык, предназначенный для описания правил построения цепочек, а значит, для описания других языков. Язык, предназначенный для описания другого языка, называется метаязыком.
Пример грамматики G1:
G1 = ({A, S}, {0, 1}, P, S), (3.2)
где P:
1. S 0A1;
2. 0A 00A1;
3. A .
Выводимая цепочка грамматики G, не содержащая нетерминалов, называется терминальной цепочкой, порождаемой грамматикой G.
Язык L(G), порождаемый грамматикой G, - это множество терминальных цепочек, порождаемых грамматикой G.
Введем отношение G непосредственного вывода на множестве , которое записывается следующим образом:
G (3.3)
Данная запись читается: непосредственно выводима из для грамматики G = (N, T, P, S) и означает: если – цепочка из множества и – правило из Р, то G .
Через G+ обозначим транзитивное замыкание (нетривиальный вывод за один и более шагов). Тогда G+ читается как: выводима из нетривиальным образом.
Через G* обозначим рефлексивное и транзитивное замыкание (вывод за ноль и более шагов). Тогда G* означает: выводима из .
Пусть K – k-я степень отношения . То есть, если K , то существует последовательность 0 1 2 3 ... k из к+1 цепочек
= 0, 1, ... i - 1 i, 1 ≤ i ≤ k и k = (3.4)
Пример выводов для грамматики G1:
S 0A1 00A11 0011; (3.5)
S 1 0A1; S 2 00A11; S 3 0011; (3.6)
S + 0A1; S + 00A11; S + 0011; (3.7)
S * S; S * 0A1; S * 00A11; S * 0011, (3.8)
где 0011 L(G1).