
- •Содержание
- •1.Рабочая программа
- •2.Модуль Вводный
- •3.Модуль Формальные грамматики и языки
- •3.1.Языки и цепочки символов. Способы задания языков
- •3.1.1.Цепочки символов. Операции над цепочками символов
- •3.1.2.Понятие языка. Формальное определение языка
- •3.1.3.Способы задания языков
- •3.1.4.Синтаксис и семантика языка
- •3.2.Определение грамматики
- •3.2.1.Особенности языков программирования
- •3.2.2.Определение грамматики. Форма Бэкуса—Наура
- •3.2.3.Принцип рекурсии в правилах грамматики
- •3.2.4.Другие способы задания грамматик
- •3.3.Классификация языков и грамматик
- •3.3.1.Классификация грамматик
- •3.3.2.Классификация языков
- •3.4.Контроль
- •4.Модуль Распознаватели, механизм вывода цепочек символов
- •4.1.Цепочки вывода. Сентенциальная форма.
- •4.1.1.Сентенциальная форма грамматики. Язык, заданный грамматикой
- •4.1.2.Левосторонний и правосторонний выводы
- •4.1.3.Однозначные и неоднозначные грамматики
- •4.1.4.Эквивалентность и преобразование грамматик
- •4.2.Распознаватели. Задача разбора
- •4.2.1.Общая схема распознавателя
- •4.2.2.Виды распознавателей
- •4.2.3.Классификация распознавателей по типам языков
- •4.3.Контроль
- •5.Модуль Регулярные грамматики и языки
- •5.1.Регулярные языки и грамматики
- •5.2.Леволинейные и праволинейные грамматики. Автоматные грамматики
- •5.3.Алгоритм преобразования регулярной грамматики к автоматному виду
- •5.4.Конечные автоматы
- •5.4.1.Определение конечного автомата
- •5.4.2.Детерминированные и недетерминированные конечные автоматы
- •5.4.3.Преобразование конечного автомата к детерминированному виду
- •5.5.Контроль
- •6.Модуль Контекстно-свободные грамматики и языки
- •6.1.Контекстно-свободные языки
- •6.1.1.Распознаватели кс-языков. Автоматы с магазинной памятью. Определение мп-автомата
- •6.2.Классы кс-языков и грамматик. Класс ll(k) грамматик.
- •6.3.Принципы построения распознавателей для ll(k)-грамматик
- •6.4.Левая факторизация
- •6.5.Удаление левой рекурсии
- •6.6.Алгоритм разбора для ll(1)-грамматик
- •6.7.Алгоритм построения множества first(1,a)
- •6.8.Алгоритм построения множества follow(1,a)
- •6.9.Восходящие распознаватели кс-языков без возвратов
- •6.9.1.Определение lr(k)-грамматики
- •6.10.Принципы построения распознавателей для lr(k)-грамматик
- •6.10.1.Грамматики простого предшествования
- •6.11.Распознаватели для lr(0) и lr(1) грамматик
- •6.11.1.Распознаватель для lr(0)-грамматики
- •6.11.2.Распознаватель для lr(1) грамматики
- •6.12.Контроль
- •7.Модуль Инструментальные средства для построения трансляторов
- •7.1.Инструментальные средства для построения компиляторов
- •7.1.1.Построитель лексических анализаторов Lex
- •7.2.Контроль
- •8.Модуль Особенности программирование трансляторов
- •8.1.Использование значений произвольных типов, алгоритм разбора
- •8.1.1.Алгоритм синтаксического разбора
- •8.1.2.Семантический стек
- •8.2.Неоднозначности и конфликты
- •8.3.Старшинство операций
- •8.4.Дополнительные возможности программ yacc и lex
- •8.4.1.Обработка ошибок
- •8.5.Совместное использование lex и yacc
- •8.5.1.Кодировка лексем и интерфейс
- •8.5.2.Сборка yacc-программ
- •8.6.Советы по подготовке спецификаций
- •8.6.1.Стиль
- •8.6.2.Использование левой рекурсии
- •8.6.3.Уловки анализа лексики
- •8.6.4.Входной синтаксис yacc'а
- •8.7.Контроль
- •9.Модуль Заключение
- •10.Обеспечение лабораторного практикума
- •11.Дополнительная информация. Примеры
- •11.4.Пример простейшего интерпретатора формул
- •11.5.Простой пример
- •11.6.Более сложный пример
- •11.7.Генераторы лексических и синтаксических анализаторов
- •11.8.Генераторы лексических и синтаксических анализаторов на java
- •11.9.Пакеты для разработки компиляторов
- •Список сокращений
- •Литература
- •Приложения Приложение 1. Учебно–методическая карта дисциплины “Системное программное обеспечение. Синтаксические анализаторы”
- •Приложение 2. Вопросы для зачета по дисциплине “Системное программное обеспечение. Синтаксические анализаторы”
- •Приложение 3. Методические указания к лабораторным работам по дисциплине «Системное программное обеспечение. Синтаксические анализаторы»
- •Порядок выполнения работы:
- •Контрольные вопросы
- •Лексический анализатор lex. Анализ структуры программ
- •Краткая теория:
- •Рассмотрим примеры:
- •Порядок выполнения работы:
- •Контрольные вопросы
- •Лексический анализатор lex, синтаксический анализатор yacc. Алгебраические вычисления
- •Краткая теория:
- •Порядок выполнения работы:
- •Контрольные вопросы
- •Лексический анализатор lex и синтаксический анализатор yacc. Изображение геометрических фигур
- •Краткая теория:
- •Создание метафайла и работа сним
- •Порядок выполнения работы:
- •Контрольные вопросы
- •Приложение 4. Организация рейтингового контроля по дисциплине «Системное программное обеспечение. Синтаксические анализаторы»
3.Модуль Формальные грамматики и языки
3.1.Языки и цепочки символов. Способы задания языков
3.1.1.Цепочки символов. Операции над цепочками символов
Под цепочкой символов понимают произвольную последовательность символов, записанных один за другим. Иногда цепочку символов называют строкой. Понятие символа или буквы в теории формальных грамматик является базовым, не требующим определения. Множество разрешенных для использования символов составляет алфавит языка. Принято цепочки символов обозначать греческими буквами: , , , . Цепочка символов — это последовательность, в которую могут входить любые символы алфавита в произвольной последовательности.
Важно подчеркнуть, что в теории формальных грамматик рассматривается конструктивная составляющая формальных языков, и процедура парсинга не анализирует смысл разбираемого текста. Семантическое нагружение текста или, иными словами, его интерпретация выходит за рамки синтаксического анализа. Поэтому под строкой мы будем рассматривать и неосмысленные последовательности символов, например «ааввввтт ооонпрвмк.,.!№678»
В цепочке символов это множество символов с установленным на нем отношением строгого порядка следования символов. Поэтому цепочки символов «аб» и «ба» - это различные цепочки.
Цепочки символов и эквивалентны, = , если они имеют один и тот же состав символов, одно и то же их количество и идентичные отношения порядка следования символов в цепочке.
Количество символов в цепочке называют длиной цепочки. Длина цепочки символов обозначается как ||. Очевидно, что если = , то и || = ||.
Основной операцией над цепочками символов является операция конкатенации (объединения или сложения) цепочек.
Конкатенация (сложение, объединение) двух цепочек символов — это дописывание второй цепочки в конец первой. Конкатенация цепочек и обозначается как . Выполнить конкатенацию цепочек просто: например, если = «аб», а = «вг», то = «абвг».
Так как в цепочке важен порядок символов, то очевидно, что операция конкатенации не обладает свойством коммутативности, то есть в общем случае и такие, что . Также очевидно, что конкатенация обладает свойством ассоциативности, то есть ()= ().
Можно выделить еще две операции над цепочками.
Обращение цепочки — это запись символов цепочки в обратном порядке. Обращение цепочки обозначается как R. Если a = «абвг», то aR = «гвба». Для операции обращения справедливо следующее равенство a, : (a)R = RaR.
Итерация (повторение) цепочки n раз, где nN, n > 0 — это конкатенация цепочки самой с собой n раз. Итерация цепочки a n раз обозначается как an. Для операции повторения справедливы следующие равенства а: а1 = а, а2 = аа, а3 = ааа, ... и т. д.
Среди всех цепочек символов выделяется одна особенная — пустая цепочка.
Пустая цепочка символов — это цепочка, не содержащая ни одного символа.
Пустую цепочку здесь везде будем обозначать греческой буквой (в литературе
ее иногда обозначают латинской буквой е или греческой ε).
Для пустой цепочки справедливы следующие равенства:
1. | |=0;
2. a: a = a, = a;
3. R =
4. n≥0; ⁿ =
5. a: a° = .
3.1.2.Понятие языка. Формальное определение языка
В общем случае язык — это заданный набор символов и правил, устанавливающих способы комбинации этих символов между собой для записи осмысленных текстов. Основой любого естественного или искусственного языка является алфавит, определяющий набор допустимых символов языка.
Алфавит — это счетное множество допустимых символов языка. Будем обозначать это множество символом V. Интересно, что согласно формальному определению, алфавит не обязательно должен быть конечным (перечислимым) множеством, но реально все существующие языки строятся на основе конечных алфавитов.
Цепочка символов является цепочкой над алфавитом V: (V), если в нее входят только символы, принадлежащие множеству символов . Для любого алфавита V пустая цепочка , может, как являться, так и не являться цепочкой (V), Это условие оговаривается дополнительно.
Если V — некоторый алфавит, то:
■ V+ — множество всех цепочек над алфавитом V без ;
■ V* — множество всех цепочек над алфавитом V, включая
Справедливо равенство: V* = V+ {}.
Языком L над алфавитом V: L(V) называется некоторое счетное подмножество цепочек конечной длины из множества всех цепочек над алфавитом V. Из этого определения следуют два вывода: во-первых, множество цепочек языка не обязано быть конечным; во-вторых, хотя каждая цепочка символов, входящая в язык, обязана иметь конечную длину, эта длина может быть сколь угодно большой и формально ничем не ограничена.
Все существующие языки подпадают под это определение. Большинство реальных естественных и искусственных языков содержат бесконечное множество цепочек. Также в большинстве языков длина цепочки ничем не ограничена (например, этот длинный текст — пример цепочки символов русского языка). Цепочку символов, принадлежащую заданному языку, часто называют предложением языка, а множество цепочек символов некоторого языка L(V) — множеством предложений этого языка.
Для любого языка L(V) справедливо: L(V) V* V*.
Язык L(V) включает в себя язык L'(V): L'(V)L(V), если L(V): L'(V). Множество цепочек языка L'(V) является подмножеством множества цепочек языка L(V) (или эти множества совпадают). Очевидно, что оба языка должны строится на основе одного и того же алфавита.
Два языка L(V) и L'(V) совпадают (эквивалентны): L'(V) =L(V), если L'(V) L(V) и L(V) L'(V); или, что то же самое: a L'(V): aL(V) и a L'(V): aL(V). Множества допустимых цепочек символов для эквивалентных языков должны быть равны.
Два языка L(V) и L'(V) почти эквивалентны: L'(V)L(V), если L'(V){}=L(V){}. Множества допустимых цепочек символов почти эквивалентных языков могут различаться только на пустую цепочку символов.