Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторные работы по СПО.doc
Скачиваний:
6
Добавлен:
30.10.2018
Размер:
370.18 Кб
Скачать

Содержание отчета

  1. Исходное задание;

  2. Полное описание автомата;

  3. Алгоритм программной реализации автомата;

  4. Листинг программы.

Контрольные вопросы

    1. Работа какой компоненты транслятора формализуется в виде конечного автомата?

    2. В чем специфика детерминированного конечного автомата?

    3. Какими формальными средствами описывается переходная функция конечного автомата?

    4. Может ли быть у автомата несколько начальных вершин?

    5. Может ли быть у автомата несколько конечных вершин?

Лабораторная работа № 4

Диагностические сообщения компилятора

Цель работы: формирование практических навыков по определению возможных причин синтаксических и семантических ошибок в программе, а также синтез программной поддержки данной процедуры.

Введение

Одной из важнейших функций компилятора является определение синтаксических и семантических ошибок и оповещение об этом автора программного кода. Компилятор должен максимально полно проинформировать программиста о типе ошибки и месте ее возникновения. В идеале компилятор может предложить пользователю и вариант исправления ошибки.

Разработан ряд рекомендаций по генерируемым компиляторам сообщениям об ошибках [2]:

  • указание места в программе, в котором допущена ошибка;

  • указание сути ошибки;

  • понятность сообщения даже неопытному пользователю;

  • вежливость, краткость, последовательность, конструктивность (т.е. понятность сути ошибки). Отсутствие оскорблений;

  • целесообразность включения в подсказку возможных вариантов исправления ошибок;

  • нецелесообразность сопровождения раздражающими, пугающими сигналами;

  • нецелесообразность использования просто номера ошибки.

В реальных компиляторах трудно, а иногда и невозможно, реализовать эти рекомендации в полном объеме, но разработчик компилятора должен стремиться к максимально возможному результату.

Выполнение лабораторной работы

  1. Для программного фрагмента, заданного в соответствии с вариантом в лабораторной работе № 1, сформировать перечень возможных синтаксических и семантических ошибок. Программный фрагмент может включать и комментарии.

  2. Разработать номенклатуру сообщений компилятора по данным ошибкам.

  3. Разработать программный фрагмент компилятора, реализующий поиск указанных ошибок и выдачу диагностических сообщений в соответствии с изложенными в теоретической части рекомендациями.

Содержание отчета

  1. Исходное задание;

  2. Перечень возможных ошибок и соответствующих сообщений компилятора;

  3. Алгоритм программной реализации задания;

  4. Листинг программы.

Контрольные вопросы

  1. На какой фазе компиляции генерируются сообщения об ошибках?

  2. Рекомендуется ли сопровождать сообщения об ошибках звуковыми сигналами?

  3. Каким образом можно при выдаче сообщения об ошибке указывать место этой ошибки?

  4. Можно ли одновременно выдавать сообщения о двух и более ошибках?

  5. Нужно ли ориентировать содержание сообщения об ошибке на квалификацию пользователя?

Лабораторная работа № 5

Лексический сканер

Цель работы: изучение основных функций фазы лексического анализа при компиляции и практическое закрепление теоретического материала.

Введение

Первой фазой компиляции является лексический анализ (сканирование). Его суть – разделение текста программы на отдельные языковые конструкции – лексемы. Лексема является аналогом слова в естественном языке. Каждая лексема имеет свое смысловое значение, т.е. обладает семантикой. Лексемы являются листьями (конечными вершинами) дерева разбора программы. В это же время строится таблица лексем (идентификаторов). В ней все лексемы, имеющие разную длину, заменяются кодами одинаковой длины, т.е. исходный листинг заменяется текстом на некотором промежуточном языке [3], что упрощает последующие фазы компиляции. В эту же таблицу могут заноситься и типы переменных программы. Во время данной фазы удаляются из программы пробелы и комментарии, а также фиксируются лексические ошибки (недопустимые символы, неправильные идентификаторы).

Лексема – структурная единица языка, состоящая из элементарных символов языка и не содержащая в своем составе других структурных единиц языка.

Все лексемы делятся на два класса: заранее определенные лексемы (зарезервированные слова, операторы, разделители) и производные лексемы, введенные пользователем (идентификаторы, константы). Поскольку первые известны заранее, то исходно известны и их коды, т.е. их не надо описывать. Про вторых известны только правила их формирования. Поэтому процедура кодирования включает следующие шаги:

  • если лексема известна заранее, то она просто заменяется заранее известным кодом;

  • если лексема принадлежит к виду «определяемая пользователем», то она должна быть закодирована, помещена в таблицу имен и заменена в исходной цепочке на код. При этом надо провести проверку – есть ли уже эта лексема в таблице. Кодирование обычно учитывает тип имени (константы, переменные, разделители или строки и т.п.).

Вот почему на выходе лексического сканера обычно представлены две таблицы: одна включает перечень заранее определенных лексем с их предопределенными кодами, а вторая формируется из определяемых в процессе компиляции лексем.

Классификация лексем зависит от исходного языка программирования. Для языка Паскаль она может иметь вид, представленный на рис. 5.1.

Рис. 5.1

Из этого следует, что каждый компилятор имеет ограничения по числу типов и по количеству лексем.

Выделение лексемы происходит через их границы, в качестве которых выделяются: пробелы, знаки операций, символы комментариев, разделители (запятая, точка с запятой, двоеточие, скобки) – все они являются терминальными символами.

После лексического анализа и замены исходного листинга на кодированную цепочку исходный листинг, по большому счету, не нужен. Но он сохраняется для выдачи диагностики. Для дальнейших фаз компиляции лексема является наименьшей единицей языка (терминальным символом).

В таблицах указываются свойства лексем, причем для разных лексем они разны. В таблице стандартных лексем, существующих исходно, для арифметических и логических операторов указывается старшинство операций. Оно требуется для построения синтаксического дерева, т.е. данная таблица может иметь такой вид:

Символ операции

Код

Класс символа

Старшинство

Для функций указывается имя, количество и типы формальных аргументов, тип возвращаемого результата и т.д. Для массива нужно указать количество элементов и тип элемента, поскольку это понадобится в дальнейшем при выделении памяти.

Возможны варианты, когда отдельно формируются таблица идентификаторов и таблица литералов (целых, вещественных чисел и т.п.).

При этом решается весьма важная проблема – порядок размещение в таблице лексем, поскольку время работы с таблицей характеризует качество транслятора. К настоящему времени известно несколько вариантов формирования таких таблиц. Наиболее простыми являются:

В порядке поступления

Очередная лексема добавляется в конец таблицы, т.е. таблица не упорядочена. Добавление в таблицу реализуется весьма просто, но поиск требует, в общем случае, последовательного (линейного) просмотра всей таблицы, т.е. время поиска в общем случае при числе элементов таблицы N пропорционально tп ~ N/2.

Время записи tз не зависит от числа элементов таблицы.

При большом числе лексем такой метод организации таблиц является неэффективным, поскольку таблицы чаще просматриваются, чем дополняются.

Сортировка таблицы

Все лексемы сортируются в алфавитном порядке. Поиск в этом случае более эффективен, поскольку он реализуется по бинарному или логарифмическому алгоритмы. Для таблицы длиной N

tп ~ 1 + log2(N).

Пример: длина таблицы 128 лексем. В неупорядоченной таблице потребуется в среднем провести для поиска 64 сравнения, а в упорядоченной – 8.

Известны также реализации таблиц в виде бинарного дерева, на основе хэш-адресации и др.

Выполнение лабораторной работы

  1. Для программного фрагмента, заданного в соответствии с вариантом в лабораторной работе № 1, сформировать перечень возможных типов лексем в соответствии с рис. 5.1.

  1. Для терминальных символов-разделителей, идентификаторов и констант, заданных вариантом задания, разработать систему кодирования в виде буквы и двузначного числа;

  2. Разработать программу лексического сканирования Паскаль-программы с заменой терминальных символов, идентификаторов и констант кодами, разработанными на предыдущем шаге. Попутно должна формироваться таблица идентификаторов и констант на основе сортировки лексем. Таблица заранее предопределенных лексем и их кодов формируется заранее и представляется на бумажном носителе. Листинг программы может включать комментарии.