
- •Выпускная квалификационная работа бакалавра
- •Задание на выпускную квалификационную работу бакалавра
- •План-график выполнения работы
- •Реферат
- •Введение
- •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.2.3 Метод разбора
В качестве метода разбора был выбран нисходящий метод, а именно, не рекурсивный предиктивный синтаксический анализ, в зарубежной литературе его также называют таблично управляемым LL(k) анализом.
В этом методе явно используется стек в отличие от рекурсивного спуска. На рис. 4.3 схематично представлен синтаксический анализатор управляемый таблицей синтаксического анализа. Он имеет входной буфер, стек, содержащий как терминалы, так и нетерминалы, таблицу синтаксического анализа, предварительно построенную, и выходной буфер.
Рисунок 4.3 – Модель синтаксического анализатора, управляемого таблицей
Синтаксический анализатор управляется программой, которая рассматривает символ на вершине стека Xи текущий входной символa. Если Xявляется нетерминалом, синтаксический анализатор выбирает X–продукцию в соответствиис записью M[X,a] в таблице синтаксического анализа M(здесь может выполняться дополнительный код, например, для построения узла дерева разбора илипредо смотра второго символа). В противном случае проверяется соответствие между терминалом Xи текущим входным символом a.
Прежде чем рассматривать алгоритм синтаксического анализа рассмотрим понятие таблицы синтаксического анализа и способ её построения.Таблица представляет собой двумерный массив, каждая ячейка которого адресуется парой [нетерминал, терминал].Ячейка может либо быть пустой,либо содержать продукцию.
Для построения таблицы необходимо ввести понятие функций – FIRSTиFOLLOW, связанные с грамматикой G.
Определим FIRST(a), где a–произвольная строка символов грамматики, как множество терминалов, с которых начинаются строки, порождаемые a. Если a →* ε, то ε FIRST(a).
Определим FOLLOW(A)для нетерминала Aкак множество терминалов a,которые могут располагаться непосредственно справаот Aв некоторой сентенциальной форме, т.е. множество терминалов a, таких,чтосуществует порождение вида S→*aAabдля некоторыхaиb. Кроме того, если Aможет оказаться крайним справа символом некоторой сентенциальной формы, тоEOF FOLLOW(A). Подробное описание пошаговых правил по вычислению этих функций можно найти в литературе [2].
Теперь можно описать метод построения таблицы синтаксического анализа с использованием введённых функций и грамматики G.Он заключается в применение для каждой продукции грамматики следующих действий:
Для каждого терминала aиз FIRST(a) добавляем A→aв ячейку M[A,a];
Если ε FIRST(a), то для каждого терминала bизFOLLOW(A)добавляемA→aв M[A,b].Еслиε FIRST(a) иEOF FOLLOW(A), тодобавляемA→aтак же ивM[A,EOF].
Если после выполнения этих действий ячейка M[A,a] осталась без продукции, устанавливаем её значение равным error (это значение обычно представляется пустой записью таблицы).
На рисунке 4.4 приведена таблица синтаксического анализа для грамматики LISMA+, построенная по описанному методу. Записи чисел в ячейках обозначают номер продукции, запись synуказываетна синхронизирующий токен при восстановлении после ошибки. Далее об этой записи будет рассказано более подробно.
Рисунок 4.4 “Таблица синтаксического анализа”
Продолжение рисунка 4.4
Теперь рассмотрим алгоритм разбора, представленный на рис. 4.5.
Рисунок 4.5– Алгоритм предиктивного синтаксического анализа
Входными данными для него служит входной поток токенов и таблица синтаксического анализа M, выходными данными - подтверждение принадлежности входной строки языку порождаемой данной грамматикой, иначе сообщение об ошибке. Изначально стартовый символ грамматики Programнаходится на вершине стека.Этот алгоритм имитирует левое порождение цепочек языка. По этой причине указатель входного потока указывает на крайний слева символ.