
- •Выпускная квалификационная работа бакалавра
- •Задание на выпускную квалификационную работу бакалавра
- •План-график выполнения работы
- •Реферат
- •Введение
- •1 Языковые процессоры
- •1.1 Практическое применениеискусственных языков
- •1.2 Практический пример
- •1.3 Понятие и структура языкового процессора
- •2Обзор существующих систем и обоснование выбора инструментальных средств и класса грамматики
- •2.1 Обзор существующей символьной спецификации моделей гс в среде исма
- •2.1.1 Лексемы языка исма
- •2.1.2 Грамматика языка исма
- •2.1.3 Семантические действия в языковом процессоре исма
- •2.1.4 Заключение
- •2.2 Обоснование выбора инструментальных средств и класса грамматики
- •3 Постановка задачи исследования
- •3.1 Характеристика задачи исследования
- •3.2 Входная информация
- •3.3 Выходная информация
- •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.2.4 Восстановление после ошибок
- •4.2.5 Иерархия классов модуля
- •4.3 Семантический анализ
- •4.3.1 Промежуточное представление программы
- •4.3.2 Грамматика с семантическими правилами
- •4.3.3 Модифицированныйметодразбора
- •4.3.4 Семантический анализ. Таблица символов
- •4.3.5 Семантический анализ. Проверка корректности типа
- •4.4 Генерация кода
- •4.5 Система сбора диагностических сообщений
- •5 Тестирование
- •5.1 Лексический анализатор
- •5.2 Синтаксическийанализатор
- •5.3 Семантический анализатор
- •Заключение
- •Список использованных источников
- •ПриложениеA Диагностические сообщения
- •Диагностические сообщения сканера
- •Диагностические сообщения парсера
- •Диагностические сообщения семантического анализатора
- •ПриложениеБ
- •Б.1.3 Установка системы
- •Б.2 Работа с системой б.2.1 Запуск системы и начало работы
- •Б.2.2Ввод программной модели
- •Б.2.3Трансляция модели и просмотр результата
- •Б.2.4Сохранение программной модели
- •Б.2.6Завершение работы с системой
- •Приложение в
- •Листинг программы
- •В.1 Модуль лексического анализатора
- •Файл abstractLexer.H
- •Файл lexer.H
- •Файл lexer.Cpp
- •В.2 Модуль синтаксического анализатора Файл abstractParser.H
- •Файлparser_ll1.H
- •Файл parser_ll1.Cpp
- •В.3 Модуль семантического анализатора Файл symbolTable.H
- •Файл SymbolTableFactory.H
- •Файл checker.H
- •В.4 Модулькодогенератора ФайлastVisitor.H
- •Файл astCodeGen.H
4.3.3 Модифицированныйметодразбора
После того как мы расширили грамматику добавлением нетерминалов, указывающих семантические действия, можно выполнять трансляцию непосредственно в процессе синтаксического анализа путём добавления дополнительного стека, для хранения частей уже созданного синтаксического дерева, ирасширения стека синтаксического анализатора таким образом, чтобы он хранил семантические действия[1].
Семантические действия заключаются в снятии, если необходимо, с вершины семантического стека узлов – составляющих, и в создании нового узла и помещении его на вершину стека. Все семантические действия выполняются, когда на вершине стека синтаксического анализатора оказываются соответствующие им нетерминалы. Таким образом,к моменту снятия со стека последнего символа тела выводимой продукции, все дочерние узлы узла заголовка этой продукции будут находиться на вершине семантического стекев обратном порядке (справа налево).
Модифицированный алгоритм разбора представлен на рис. 4.8.Входными данными для модифицированного алгоритма также служит входной поток токенов и таблица синтаксического анализа M, выходными данными – построенное синтаксическое дерево, иначе сообщение об ошибке. Изначально стартовый символ грамматики Programнаходится на вершине стека. В случае обнаружении хотя бы одной синтаксической ошибки, семантические действия игнорируются.
Рисунок 4.8 – Модифицированный алгоритм предиктивного синтаксического анализа
4.3.4 Семантический анализ. Таблица символов
После стадии синтаксического анализа, на выходе которой будет построенное абстрактное синтаксическое дерево, будет идти непосредственно стадия семантического анализа.Эту стадию также называют статическим анализом, так как она ищет только те ошибки, которые непосредственно вытекают из входной программы, в отличие от динамического анализа, который анализирует программу во время её выполнения.
Статический анализ семантических соглашений может сообщить об ошибке, которая была не обнаружена на ранних стадиях языкового процессора. Это вызвано тем, что некоторые особенности входного языка являются контекстно-чувствительными (не контекстно-свободными).
Выделены следующие виды семантических проверок:
корректность типаоперанда в операторе или операции, напримерпеременной при индексации и т.п.
уникальность идентификаторов;
отсутствие необъявленных идентификаторов;
специфические проверки, например полнота системы уравнений и др.
Таким образом, семантический анализ преследует две цели. Первая – это, конечно, семантическая корректность. Вторая цель – это подготовить абстрактное синтаксическое дерево к стадии кода генерации. Поэтому в ходе семантического анализа создаётся таблица символов, в которую записывается информация об идентификаторах, используемых в программе. Далее эта информация используется при проверках корректности типа и при генерации выходной программы.
Прежде чем рассматривать алгоритм построения таблицы опишем её структуру. Таблица символов представляет ассоциативный массив. Ключевым полем является имя идентификатора, а полем данных –тип программного объекта, обозначаемого этим идентификатором.
В программе выделено семь основных типов объектов:
массивы (ArrayType)
переменные (VarType)
счётчики (CountType)
вещественные константы (ConstFloatType)
целочисленные константы (ConstIntType)
макро определение (MacroType)
макро определение с параметром (MacroIndexType)
На рис. 4.9 приведена иерархия классов представляющих типы объектов с обозначением их элементов данных, где ObjType это абстрактный класс, от которого унаследованы все остальные классы.
Рисунок 4.9 – Иерархия классов представляющих типы программных объектов
Как видно из рисунка помимо просто указания типа объекта в этих структурах данных хранятся дополнительная информация, связанная с программным объектом, например в типе массива хранится его размер(size) и число(first), с которого начинается нумерация элементов (по умолчанию равное единице).
В методах для работы с таблицей символов реализованы семантические проверки: на уникальность идентификатора при вставке нового элемента в таблицу и на необъявленные идентификаторы при поиске в таблице по ключу.
На рис. 4.10 представлен алгоритм построения таблицы символов. Входными данными является указатель на корневой узел синтаксического дерева, а выходными – построенная таблица символов, либо сообщение об ошибке.
Рисунок 4.10 – Алгоритм построения таблицы символов
Продолжение рисунка 4.10
Продолжение
рисунка 4.10
При построении алгоритма учитывались следующие соглашения по структуре языка:
константа может быть декларирована не явно, т.е. без указания ключевого словаconst. Таким образом, задание ГНУ без индекса пересекается с неявным определением константы;
объявление переменных уравнения не обязательно, поэтому алгоритм должен с начало просмотреть все левые части уравнений и, если какая-нибудь переменная отсутствует в таблице символов, то добавить её;
В левой части уравнений без индексов может стоять только идентификатор типа VarType.В левой части уравнений с индексами может стоять только идентификатор типа ArrayType.;
Поэтому алгоритм с начало добавляет в таблицу символы по мере разрешения противоречий. В первую очередь добавляются все идентификаторы, тип которых очевидно следует из их объявления. К таким идентификаторам относятся макро определения, явно определённые константы,массивы, счётчики. Далее алгоритм просматривает все левые части уравнений в программе и, если переменная отсутствует в таблице символов, то добавляет её, иначе проверяет на соответствие типу. Заключительной стадией является проход по операторам, отвечающим как за задание ГНУ, так и за определение константы. К этому моменту времени в таблице символов находятся уже все переменные, поэтому определение типа идентификатора однозначно: если он отсутствует в таблице символов, то относим его к константному типу.
К концу построения таблицы символов собрана вся информация об идентификаторах, она потребуется при последующих проверках на корректностьтипов переменных операторам.