
- •Содержание
- •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. Организация рейтингового контроля по дисциплине «Системное программное обеспечение. Синтаксические анализаторы»
8.6.Советы по подготовке спецификаций
Этот раздел содержит разнообразные рекомендации по подготовке эффективных, легко изменяемых и понятных спецификаций.
8.6.1.Стиль
Трудно написать правила, которые выполняют серьезные действия и к тому же имеют удобочитаемый вид. Ниже приводится несколько рекомендаций, касающихся стиля спецификаций.
Пишите имена лексем прописными буквами, а имена нетерминальных символов - строчными. Так удобнее отлаживать yacc-спецификацию.
Помещайте грамматические правила и действия на отдельных строках. Это облегчает чтение.
Все правила с одинаковой левой частью помещайте вместе. Левую часть пишите только раз, а альтернативы разделяйте вертикальной чертой.
Точку с запятой ставьте на отдельной строке и только после последнего правила в группе правил с одинаковой левой частью. Это позволяет легко добавлять новые правила.
Используйте отступы для выделения действий и их тел.
Сложные действия выделяйте в подпрограммы, определенные в других файлах.
Основная проблема заключается в том, чтобы не утопить грамматические правила в трясине действий.
8.6.2.Использование левой рекурсии
Алгоритм разбора, используемый в утилите yacc, лучше подходит для так называемых леворекурсивных грамматических правил вида
name : name rest_of_rule
;
Правила, подобные
list : item
| list ',' item
;
и
seq : item
| seq item
;
часто возникают при спецификации списков и последовательностей. В каждом из этих случаев первое правило будет использовано только для свертки первого элемента, второе правило будет использоваться для свертки второго и всех последующих элементов.
Для праворекурсивных правил, таких как
seq : item
| item seq
;
алгоритм разбора немного сложнее; элементы выделяются и свертываются справа налево. Более серьезно то, что есть опасность переполнения внутреннего стека при чтении очень длинной последовательности. Поэтому рекомендуется использовать левую рекурсию.
Стоит рассмотреть случай, когда имеет смысл последовательность из нуля элементов. Спецификация такой последовательности включает правило с пустым телом:
seq : /* пусто */
| item seq
;
И вновь первое правило будет использоваться для свертки только перед тем, как прочитан первый элемент, а второе - для свертки всех прочитанных элементов. Допущение пустых последовательностей часто ведет к увеличению общности. Однако могут возникнуть конфликты, поскольку yacc вынужден решать, пустая последовательность чего прочитана, в то время как он еще недостаточно прочитал, чтобы узнать это.
8.6.3.Уловки анализа лексики
Некоторые решения, принимаемые лексическим анализатором, зависят от контекста. Например, лексический анализатор может игнорировать пробелы всюду, но не в текстах, взятых в кавычки, или имена могут включаться в таблицу в описаниях, но не в выражениях. Один из способов обработки таких ситуаций – использование глобального признака, устанавливаемого действиями и опрашиваемого лексическим анализатором. Например, спецификация
%{
int dflag;
... другие определения ...
%%
prog : decls stats ;
decls : /* пусто */
{
dflag = 1;
}
decls declaration
;
stats : /* пусто */
{
dflag = 0;
}
stats statement
;
... другие правила ...
описывает программу, состоящую из нуля или большего числа описаний, за которыми следует нуль или более операторов. Признак dflag равен 0, когда читаются операторы, и 1, когда читаются описания, за исключением первой лексемы в первом операторе. Эта лексема требуется алгоритму разбора для того, чтобы выяснить, что описания закончились и начались операторы.
Можно расценить такие попытки пройти с черного хода как вредные. Однако они позволяют сделать вещи, которые другими способами сделать было бы сложно, если не невозможно.