Необходимую дополнительную информацию можно найти в литературе по компиляторам и системам программирования [1–4, 7].
Пример выполнения курсовой работы
В качестве примера для иллюстрации выполнения курсовой работы будет взят входной язык, который, с одной стороны, не совпадает ни с одним из вариантов задания, а с другой стороны – позволяет хорошо проиллюстрировать все методы и технические приемы, которые полезны при выполнении работы.
Многие методы, технические приемы и их реализация в курсовой работе будут взяты из лабораторных работ № 1–4, которые были рассмотрены ранее. Другие методы, наоборот, будут реализованы иначе, чтобы проиллюстрировать все существующие возможности, их преимущества и недостатки. В каждом случае будет дано пояснение, почему использован тот или иной метод.
В примере проиллюстрированы следующие интересные моменты:
• разделение лексического и синтаксического анализаторов с целью упрощения работы последнего (на примере унарной арифметической операции «-» и операции сравнения типа «не равно»);
• обнаружение присваивания значений константам на этапе синтаксического разбора (в лабораторных работах № 3 и 4 эта же операция выполнялась на этапе семантического анализа перед генерацией кода);
• возможности преобразования исходной грамматики, изменения синтаксиса входного языка и модификации алгоритма синтаксического разбора на основе анализа правил грамматики (на примере условного оператора);
• модификация остовной грамматики при необходимости различать правила;
• методы обработки логических операций и операций сравнения;
• простейший семантический анализ и модификация результирующего кода на этапе семантического анализа (на примере обработки переменных InpVar и CornpileTest);
• элементарные методы машинно-зависимой оптимизации результирующего кода.
Для реализации курсовой работы будут использоваться программные модули, созданные при выполнении лабораторных работ № 1–4, код которых не зависит от входного языка. Такой подход иллюстрирует, насколько удобно и эффективно выделять не зависящую от входного языка часть компилятора в отдельные модули или библиотеки.
Задание для примера выполнения работы
В качестве примера возьмем следующие условия для входного языка:
1. Тип допустимых констант: десятичные.
2. Дополнительная операция: унарный арифметический минус (-).
3. Оператор цикла: while (<���выражение>) do <���оператор>.
4. Оптимизация: оба метода (1 и 2).
5. Тип данных: Long integer (longint, 32 бит).
6. Тип комментария: фигурные скобки ({… }).
Кроме того, модифицируем синтаксис условного оператора (два типа):
• if (<���выражение>) <���оператор> else <���оператор>;
• if (<���выражение>) <���оператор>;
и дополним перечень операций сравнения операцией «не равно» (<>).
Получим входной язык, сочетающий в себе элементы синтаксиса языков C++ (элементы оператора цикла и условный оператор) и Object Pascal (оператор цикла, составной оператор begin… end, оператор присваивания и комментарии).
В качестве результирующего (выходного) языка компилятора будем использовать язык ассемблера процессоров типа Intel 80386 и более поздних модификаций в модификации для системы программирования Delphi 5 [9, 23, 28, 41, 44]. Чтобы исключить неоднозначности при работе с этой системой программирования, изменим семантические ограничения входного языка:
• сделаем допустимым использование имени переменной CompileTest в любых операторах входного языка (а не только в операторах присваивания);
• запретим использование переменных с именем Result, так как такое имя переменной является предопределенным в целевой вычислительной системе.
Кроме того, в именах переменных во входном языке не должны различаться строчные и прописные буквы (например, переменные с именами i и I должны восприниматься как одна и та же переменная).
Грамматика входного языка
Грамматику входного языка построим на основе фрагментов грамматик, рассмотренных в заданиях по лабораторной работе № 3. Там имеются правила для линейных операций (арифметические и логические операции) и для условного оператора. По аналогии с условным оператором построим оператор цикла. Для составного оператора и всей программы в целом останется определить еще одно понятие – последовательность операторов. Будем рассматривать последовательность операторов как цепочку операторов, разделенных знаком «точка с запятой».
Читать дальше
Конец ознакомительного отрывка
Купить книгу