
- •Выпускная квалификационная работа бакалавра
- •Задание на выпускную квалификационную работу бакалавра
- •План-график выполнения работы
- •Реферат
- •Введение
- •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.1.4 Иерархия классов модуля
На рис. 4.2 представлена иерархия классов сканера. Где AbstractLexer- интерфейс, посредством которого осуществляется взаимодействие с синтаксическим анализатором;Lexer–реализацияклассаAbstractLexer;Token – класс, абстракция сущности токен; а Word , IntLiteral и FloatLiteralклассы производные от класса Tokenпредставляют лексемы с атрибутом – внутреннее представление лексемы,например целое число или строка.
Использование интерфейсного класса в архитектуре приложения даёт возможностипоменять реализацию лексического анализатора без изменения других модулей.
Рисунок 4.2– Иерархия классов лексического анализатора
Листинг этого модуля представлен в Приложении В в разделе лексический анализатор.
4.2 Синтаксический анализатор
4.2.1 Функции синтаксического анализатора
При выполнении синтаксический анализатор получает строку токенов от лексического анализатора и проверяет, может ли эта строка порождаться грамматикой исходного языка.Синтаксический анализатор также называют парсером.
В случае установления непринадлежности входной цепочки множеству цепочек порождаемых грамматикой синтаксический анализатор долженсообщить обо всех выявленных ошибках, а кроме того обработать обычные, часто встречающиеся ошибки и продолжить работу с оставшейся частью программы, т.е. произвести их нейтрализацию.
В случае корректной программысинтаксический анализатор строит дерево разбора и передаёт его следующей части языкового процессора. Явное построение дерева разбора вызвано невозможностью выполнения некоторых семантических проверок непосредственно в процессе синтаксического анализа.
4.2.2 Спецификация грамматики
Грамматика представляет собой совокупность четырех компонент:
Терминалы. Они представляют собой базовые символы, из которых формируются строки. Термин “имя токена” является синонимом слова “терминал”;
Нетерминалы. Они представляют собой синтаксические переменные, которые обозначают множество строк. Эти множества строк, обозначаемые нетерминалами, помогают определить язык, порождаемы грамматикой;
Стартовый символ.Один из нетерминалов грамматики считается стартовым символом, и множество строк, которые он обозначает, является языком, определяемым грамматикой;
Продукции. Продукции грамматики определяют способ, которым терминалы и нетерминалы могут объединяться для создания строк. Каждая продукция состоит из следующих частей:
Заголовок или левая часть продукции, обычно представлена нетерминалом;
символ →;
Тело, или правая часть, состоящая из нуля или некоторого количества терминалов и нетерминалов. Эти компоненты тела описывают один из способов, которым могут быть построены строки нетерминалов в заголовке.
По
классификации Хомского разработанная
грамматика языкаLISMA
является контекстно-свободной(КС). На
КС-грамматики распространяется
единственное ограничение: вид левой
части каждой продукции может быть
ограничен лишь единственным нетерминальным
символом. Или грамматика G[S]
= <N, T, P, S> называется КС-грамматикой,
если каждая ее продукция имеет вид A→β,
где A
N,
β
(N
T)*.
Для анализа грамматики выбран нисходящий метод, в котором дерево разбора строится сверху (от корня) вниз (к листьям).Это в свою очередь накладывает ограничения на вид грамматики.Класс грамматик, для которых можно использовать нисходящие методы разбора, просматривающие к символов во входном потоке, часто называются классом LL(k).
Для грамматик класса LL(k) существует ряд требований:
отсутствие левой рекурсии, т.е. отсутствие продукций вида: A→+ Aa, где A N, а T;
наличие левой факторизации, т.е. отсутствие продукций вида: A→aB1 | aB2 , где A N, а T, B1 (N T)*,B2 (N T)*;
должна быть однозначна (обязательное требование для любой грамматики). Это означает существование единственного дерева разбора для каждой программы.
Таким образом, разработанная грамматика принадлежит к классу LL(2) без возврата с просмотром вперёд двух символов.
Просмотр
вперед
используется, когда в грамматиках
встречаются альтернативные правила,
начинающиеся с одинаковых цепочек
символов. Возникающая неоднозначность
может быть разрешена путем предварительного
просмотра правила на
символов вперед до той границы, начиная
с которой данное правило можно отличить
от альтернативных.
Просмотр вперед – это один из возможных вариантов упорядочивания подстановок, обеспечивающий решение проблемы недетерминированности. Наряду с ним используются: преобразование грамматик к детерминированным и анализ с возвратами.
Возвраты производятся для альтернативных правил, начинающихся с одинаковых подцепочек. В этом случае появление отказа при разборе правила ведет к восстановлению текущей позиции в то положение, в котором находился анализатор до входа в данное правило. Использование возвратов может выступать в качестве альтернативы просмотру вперед.
Привести грамматику полностью к классу LL(1) не удалось ввиду особенностей языка, но ситуации, где используется просмотр вперёд двух символов, сведены к минимуму.
Терминальный словарь грамматики представлен токенами из таблицы 4.2.
Далее представлены пронумерованные (двойной номер обозначает альтернативные продукции) продукции грамматики в форме Бэкуса-Наура (BNF) с названием языковых конструкций, в некоторых случаях с комментариями. Все терминалы обозначены строками из прописных символов и выделены жирным шрифтом,нетерминалы обозначаются строками из строчных символов. Отдельно выделены продукции, в которых происходит просмотр вперёд на два символа, это понадобится при реализации метода разбора.
Программа - стартовый символ.Состоит из трёх частей: блока деклараций, классической части, гибридной части
program → declsDefins classicPart hybridPart
Блок деклараций переменных и макросов, а также задания глобальных начальных условий СДУ
declsDefins → declsDefins1 declsDefins
declsDefins → ε
выбор из 2.1 или 2.2 (предо смотр 2)
Макрос (с параметром или без)
declsDefins1 → MACROID param = expr ;
Явное определение константы
declsDefins1 → CONST ID = sign ;
Объявление массива
declsDefins1 → ARRAY ID [ NUM ] ;
Определение счётчика
declsDefins1 → COUNT ID = [ list_inter ] ;
Задание глобального начального условия с индексом (явно или неявно) или без индекса,неявное определение константы
declsDefins1 → ID index= sign;
Вспомогательные продукции
list_inter → interval list_inter1
list_inter1 → , interval list_inter1
list_inter1 → ε
interval → NUM – NUM
param → [ID ]
param → ε
sign → –sign
sign → literal
index → [ expr_i ]
index → ε
Классическая часть состоит из уравнений алгебраических и дифференциальных и условного оператора
classicPart → classicPart1 classicPart
classicPart → ε
выбор 10.1 или 10.2 (предо смотр 2)
classicPart1 → equation
classicPart1 → condition
Условный оператор
condition → IF ( bool ) THEN localValues ENDIF ;
Уравнение алгебраическое или дифференциальное
equation → IDder index = expr ;
localValues → localValue localValues1
localValues1 → localValue localValues1
localValues1 → ε
Локальное начальное условие с индексом (явное или неявное) и без него
localValue → ID index = expr ;
der → ‘
der → ~
Логическое выражение
bool → join bool1
bool1 → OR join bool1
bool1 → ε
join → equality join1
join1 → AND equality join1
join1 → ε
equality → rel equality1
equality1 → EQ rel
equality1 → NE rel
equality 1 → ε
rel → expr rel1
rel1 → < expr
rel1 → > expr
rel1 → LE expr rel1
rel1 → GE expr rel1
rel1 → ε
Арифметическоевыражение
expr → term expr1
expr1 → – term expr1
expr1 → + term expr1
expr1 → ε
term → unary term1
term1 → / unary term1
term1 → * unary term1
term1 → ε
unary → factor
unary → – unary
unary → NOT unary
factor → ( bool )
factor → ID spec
factor → REAL
factor → NUM
spec → index
Список фактических параметров функции
spec → (list _expr)
list _expr → expr list _expr1
list _expr1 → , expr list _expr1
list _expr1 → ε
Гибридная часть
hybridPart → localState hybridPart
hybridPart → ε
Локальное состояние
localState → ver IS body FROM list_ver ;
Условно-адресная пара
ver → ID cond
cond → [bool ]
cond → ε
Операторы – локальное начальное условие или уравнение
body → body1 body
body → ε
body1 → localValue
body1 → equation
выбор 40.1 или 40.2 (предосмотр 2)
Список условно-адресных пар
list_ver → ver list_ver1
list_ver → ε
list_ver1 → , ver list_ver1
list_ver1 → ε
Вспомогательныепродукции
literal → NUM
literal → REAL
Арифметическиевыражениядляиндексов, введеныдляупрощения семантических проверок
expr_i → term_i expr_i
expr1_i → + term_i expr1_i
expr1_i → – term_i expr1_i
expr1_i → ε
term_i → unary_i term1_i
term1_i → / unary_i term1_i
term1_i → * unary_i term1_i
term1_i → ε
unary_i → factor_i
unary_i → – unary_i
factor_i → (expr_i )
factor_i → ID
factor_i → NUM