
- •Постановка задачи.
- •Теоретический раздел. Основные понятия.
- •Некоторые возможности Макроязыка
- •Структуры данных Макропроцессора
- •Основные алгоритмы программы.
- •Руководство пользователя.
- •Описание макроязыка.
- •Описание разработанных модулей.
- •Описание разработанных тестов.
- •Список использованной литературы.
- •Листинг программы. Модуль mp.
- •Модуль Assembler.
- •Модуль Main.
- •Модуль MacroGen.
- •Модуль Expr.
- •Модуль Strings.
Структуры данных Макропроцессора
Таблица макроопределений, строго говоря, не таблица, а просто массив строк, в который записываются тексты всех макроопределений (от оператора MACRO до оператора MEND), найденных в обрабатываемом модуле.
Таблица имен макроопределений содержит имена макроопределений и указатель на размещение текста макроопределения в таблице макроопределений, как показано на рисунке.
Таблица глобальных переменных имеет такую структуру:
Все таблицы имеют переменный размер и заполняются в процессе работы.
Индекс уникальных меток - число, используемое для формирования уникальной части имен меток, встречающихся в макроопределениях
Для обработки каждого макровызова создаются:
Таблица параметров, содержащая информацию о параметрах макроопределения.
Таблица локальных переменных, содержащая информацию о локальных переменных макроопределения.
Структура этих таблиц - такая же, как и таблицы глобальных переменных, эти две таблицы могут быть объединены в одну таблицу параметров и локальных переменных.
Таблица меток макроопределения, структура которой:
Основные алгоритмы программы.
Алгоритм первого прохода.
Устанавливаем уровень вложенности макроса (level) в ноль.
Организуем цикл по обработке строк исходного файла:
Если в поле МКОП встретилась директива macro, то проверяем значение level:
Если level>0. Увеличиваем level на единицу, заносим строку в таблицу макроопределений (ТМО).
Если level=0. Организуем поиск имени макроса в таблице имен макросов:
Если поиск удачен – ошибка.
Если не нашли. Заносим имя макроса, указатель на начало макроса в ТМО, параметры макроса в ТИМ. Увеличиваем level на единицу.
Если в поле МКОП встретилась директива mend, то проверяем значение level:
Если level=0 – ошибка.
Если level>0. Заносим строку в ТМО, уменьшаем level на единицу.
Если level=1. Записываем в ТИМ указатель на конец макроса в ТМО. Уменьшаем level на единицу.
Если в поле МКОП директива end. Проверяем значение переменной level:
Если level>0 – ошибка.
Если level=0 – завершение прохода.
Если level>0 – заносим строку в ТМО.
Ошибка. Директива end не найдена.
Алгоритм второго прохода.
Устанавливаем значение переменной level=0.
Организуем цикл по обработке строк исходной программы:
Если в поле МКОП директива end, то завершение прохода.
Если macro. Увеличиваем level на единицу.
Если mend. Уменьшаем level на единицу.
Если level>0, переход к следующей итерации.
Если в поле МКОП имя макроса, вызов процедуры обработки макровызова.
Если в поле МКОП команда ассемблера, то выводим строку в выходной файл, если же в поле МКОП неизвестная команда – ошибка.
Алгоритм обработки макровызова.
Поиск имени макроса в ТИМ. Если не нашли – ошибка. Если нашли, считываем указатели на начало – переменная fi, и конец макроса – переменная li, в ТМО.
Сопоставляем фактические и формальные параметры. Если фактические параметры не соответствуют формальным - ошибка. Если фактические параметры указаны, верно, заносим их в ТЛП.
Вызываем процедуру предварительного просмотра макроса, которая заносит адреса макрометок в ТЛП. Если процедура нашла ошибку – выход с ошибкой.
Переменной i (номер текущей строки ТМО) присваиваем значение fi;
Организуем цикл со следующим предусловием: i<li
Вызываем функцию по обработке строки ТМО с номером i. Если функция вернула код ошибки – выход с ошибкой.
Увеличиваем i на единицу.
Алгоритм функции обработки строки ТМО.
По номеру текущей обрабатываемой строки (i), извлекаем строку из ТМО.
Если в поле МКОП имя макроса – ошибка.
Если директива macro – вызывается функция обработки вложенного макроопределения. Выход из функции.
Если директива AIF:
Поиск операнда (макрометки) в ТЛП.
Если поиск неудачен – ошибка.
Если поиск удачен, запоминаем адрес макрометки (номер строки в ТМО).
Если условие истинно, то переменной i присваиваем значение операнда, уменьшенное на единицу. Выход из функции.
Директива AGO:
Поиск операнда в ТЛП.
Если поиск неудачен – ошибка.
Если нашли, то переменной i присваиваем значение операнда, уменьшенное на единицу. Выход из функции.
Директива INC. Увеличиваем значение операнда на единицу. Выход из функции.
Директива DEC. Уменьшаем значение операнда на единицу. Выход из функции.
Если поле МКОП содержит команду Ассемблера:
Проверяем строку на наличие параметров макроса. Если нашли заменяем соответствующим значением параметра.
Проверяем строку на наличие уникальных меток. Если нашли, поиск в ТЛП:
Если поиск удачен, добавляем к имени метки уже присвоенный уникальный индекс;
Если поиск неудачен, добавляем имя метки в ТЛП, присваиваем ей уникальный индекс, и добавляем к имени метки в строке ее, только что полученный, уникальный индекс.
Вывод строки в выходной файл. Выход из функции.
Поле МКОП содержит неизвестную команду – ошибка.