Введение
В настоящее время языки высокого уровня стали основным средством разработки программ. Поэтому компиляторы составляют существенную часть системного программного обеспечения ЭВМ. Сегодня только очень малая часть программного обеспечения, требующая особой эффективности, разрабатывается с помощью ассемблеров. В настоящее время имеет применение довольно большое количество языков программирования. Наряду с традиционными языками, такими, например, как Фортран, широкое распространение получили так называемые «универсальные» языки (Паскаль, Си, Модула-2, Ада) и др., а также некоторые специализированные (например, язык обработки списочных структур Лисп). Кроме того, большое распространение получили языки, связанные с узкими предметными областями, такие, как входные языки пакетов прикладных программ.
Для ряда названных языков имеется довольно много реализаций для различных операционных систем и архитектур ЭВМ.
В рамках традиционных последовательных машин развивается большое число различных направлений архитектур. Примерами могут служить архитектуры CISC, RISC. Такие ведущие фирмы, как Intel, Motorola, Sun, начинают переходить на выпуск машин с RISC-архитектурами. Естественно, для каждой новой системы команд требуется полный набор новых компиляторов с распространенных языков.
Поэтому важную роль компиляторов в современном системном ПО для ЭВМ невозможно переоценить.
В данной контрольной работе делается попытка создания простого компилятора-интерпретатора с целью изучения принципов строения и работы этого вида системного ПО.
Техническое задание
В данной контрольной работе требуется: создать программу-интерпретатор, способную принимать на вход текстовый файл в ASCII-кодировке с текстом программы, разработать синтаксис для записи текста входной программы. Результатом работы программы является вывод на экран значения комплексного числа, являющегося результатом вычислений.
Интерпретатор должен воспринимать и обрабатывать следующие инструкции:
а) Присвоение значений переменным:
<ИмяПеременной> = <Значение> (например, X=1,5 – j0.8),
или <ИмяПеременной> = <Выражение> (например, F = X + j17);
б) Вывод результатов на экран:
OUT(<ИмяПеременной>) (например, OUT(X)),
или OUT(<Выражение>) (например, OUT(X + F));
в) В выражении допускаются следующие операции и встроенные функции:
+ - сумма;
– - разность;
|…| или ABS(…) - модуль комплексного числа;
* - произведение;
Re(…) - действительная часть числа;
Im(…) - мнимая часть числа;
~ - унарный минус;
j - умножение на мнимую единицу
г) Приоритет операций регулируется скобками.
Разработка грамматики
Список допустимых лексем (слов языка).
Допустимыми являются:
1. имя переменной <имя переменной> = L<L|C>; (L - буква, C - цифра)
2. числовые константы <числовая константа> = С<|C|.|C|>
3. зарезервированные слова <зарезервированные слова> = <'OUT', 'ABS', 'RE', 'IM', 'j'>
4. используемые символы <символы> = <'+', '-', '*', '|', '(', ')', '~',>
Все буквы - заглавные латинские, исключение только для j - обозначения мнимой единицы
В лексической свертке каждая лексема заменяется дескриптором. Дескриптор имеет единый формат для всех типов лексем, и содержит два поля: (<тип лексемы>, <указатель>)
<тип лексемы> – это, как правило, числовой код класса лексемы. Выделим 6 классов:
1. Идентификаторы (имена переменных) - PEREM;
2. Числовые константы (вещественные). Лексическая свертка вещественного числа включает дескриптор целой части числа и дескриптор дробной части числа, разделенные '.' - CONST;
3. Обозначение арифметических операций ('+', '–', '*', 'j', '~') - OPERAC;
4. Арифметические функции ('ABS', 'RE', 'IM', '|') - FUNC;
5. Разделители ('.', ')', '(', '=') - SPECSIMV;
6. Служебное слово ('OUT');
Лексемы собираются в таблицы – для каждого класса своя таблица. В поле дескриптора <указатель> содержится ссылка на строку соответствующей таблицы. Коды ключевых слов и разделителей всегда одни и те же в лексической свертке обрабатываемых текстов программ. Таблицы лексем для классов идентификаторов и числовых констант формируются на этапе лексического анализа. Поскольку тексты программ отличаются числом и именами переменных, количеством встречающихся числовых констант, коды идентификаторов и чисел различаются в лексической свертке различных программ (организованы в виде динамических списков).
В качестве кодов классов лексем будем использовать числа: 1 – имя переменной, 2 – числовая константа, 3 – арифметическая операция, 4 – арифметическая функция, 5 - разделители, 6 - служебное слово.
Внутренние таблицы лексического анализатора:
Таблица имен переменных
№ п/п | Идентификатор имени | Значение | |
Re | Im | ||
… | X V R … | 3.6 6.89 … | 3.6 0.3 … |
Таблица числовых констант
№ п/п | Значение | |
Re | Im | |
… | 7.6 2.1 … | 3.9 0.3 … |
Таблица арифметических операций
№ п/п | Разделитель | Приоритет |
+ – * j ~ |
Таблица арифметических функций
№ п/п | Имя |
ABS RE IM | |
Таблица разделителей
№ п/п | Имя |
. ) ( = |
Таблица служебного слова
№ п/п | Имя |
OUT |