Реферат: Структура и реализация макроязыков
DEFINE(cos)
определяя таким образом новое макроопределение с именем cos, к которому впоследствии можно обращаться следующим образом:
cos(х)
и макропроцессор сгенерирует соответствующую последовательность вызова функции.
РЕАЛИЗАЦИЯ
Таким образом, нами был описан вариант реализации макроязыка. Рассмотрим метод реализации макроязыка. В качестве примера возьмем классический язык макроассемблера.
ПОСТАНОВКА ЗАДАЧИ
Любой процессор макрокоманд должен решать следующие четыре основные задачи:
Распознавать макроопределения. Процессор макрокоманд должен распознавать макроопределения, выделяемые соответствующими псевдокомандами. В языке макроассемблера этими псевдооператорами являются псевдокоманды MACRO и MEND. Эта задача может быть усложнена тем, что внутри макроопределений могут встречаться также другие макроопределения. Когда макроопределения вложены, как было продемонстрировано выше, макропроцессор должен правильно распознавать вложения и сопоставить начало и конец макроса. Весь вложенный текст, включая и другие макроопределения определяет отдельную макрокоманду.
Запоминать макроопределения. Процессор должен запомнить определения макрокоманд, которые будут впоследствии использоваться для расширения макровызовов
Распознавать вызовы. Необходимо также и распознавать макровызовы, представленные в виде мнемонического кода операции. Это предполагает, что имена макрокоманд обрабатываются на тех же самых основаниях, как и один из кодов операции.
Выполнять расширение макрокоманд и подстановку фактических параметров. Вместо формальных параметров макроопределения макропроцессор должен подставить соответствующие операнды макрокоманды. Этот текст, в свою очередь может содержать как макрокоманды так и макроопределения.
Таким образом, макропроцессор должен распознавать и обрабатывать макроопределения и макрокоманды.
Что же касается формальных параметров, то тут нужно принять несколько решений. Необходимо определить - могут ли они встречаться в качестве кода операции, каков синтаксис допустимых параметров. В разных реализациях макроязыков могут встречаться разные варианты методы реализации подобных ситуаций, поэтому можно только дать некоторые разумные варианты, покрывающие большую часть возможных реализаций. Формальные параметры могут встречаться в макроопределении где угодно, в том числе и в команде и в коде операции. Мы хотим, чтобы была обеспечена возможность конкатенации формальных параметров макроопределения с фиксированными символьными строками. В таком случае встает вопрос о некоем разделительном символе, обеспечивающем конкатенацию формальных параметров и заданных пользователем символьных последовательностей.
Например, если из один из параметров должен быть соединен с другим (macro[x,y] = xy), то возможен синтаксис x&y, что означает конкатенацию формального параметра x с формальным параметром y. Этот случай не вызывает больших трудностей. Гораздо сложней обрабатывается случай, когда речь идет о подстановке параметра внутри символьной строки. В таком случае возможным выходом будет конкатенация по умолчанию двух последовательно друг за другом идущих символьных строк, а также преобразование формального параметра, заключенного в скобки к символьной строке. Таким образом, если мы хотим, чтобы в макросе фигурировала строка вида “blablabla[x]xxxxx”, где [x] должно заменяться формальным параметром вполне возможно заменить строку такого вида строкой типа “blablabla”(x)”xxxxx”.
Надо заметить, что множество замечательных идей по реализации подобных макроязыков реализовано в языке REXX, поддерживаемом на системном уровне операционной системой OS/2 компании IBM.
Также для выполнения функций условных переходов должны вычисляться некоторые арифметические выражения (возьмем в пример хотя бы обыкновенных счетчик). Таким образом часто оказывается полезной возможность использования псевдо-переменных времени компиляции внутри макросов.
ДВУПРОСМОТРОВЫЙ АЛГОРИТМ
Начнем с некоторых упрощающих предположений. Будем считать, что наш макропроцессор функционально независим от основного компилятора и его текст будет передаваться этому компилятору. Сначала не разрешим макровызовы и макроопределения внутри макроопределений.
Макропроцессор, как и язык ассемблера, просматривает и обрабатывает строки текста. Но в языке все строки связаны адресацией - одна строка может ссылаться на другую при помощи адреса или имени, которое должно быть “известно” ассемблеру. Более того, адрес присваеваемый каждой отдельной строке зависит от содержимого, количества и адресов предшествующих строк. Если рассматривать макроопределение, как единый объект, то можно сказать, что строки нашего макроопределения не так сильно взаимосвязаны. Макроопределения не могут ссылаться на объекты вовне этого макроопределения. Предположим, что в теле макроопределения есть строка INCR X, причем перед этой командой параметр Х получил значение 10. Макропроцессор не производит синтаксический анализ, а производит простую текстовую подстановку вместо “Х” подставляется “10”.
Наш алгоритм будет выполнять 2 систематических просмотра входного текста. В первый проход будут детерминированы все макроопределения, во второй проход будут открыты все ссылки на макросы. Так же, как и язык ассемблера не может выполнить ссылку на символ до того момента, как он встретит этот символ, язык макрокоманд не может выполнить расширение до тех пор, пока не встретит соответствующее макроопределение. Во время первого просмотра проверяется каждый код операции, макроопределения запоминаются в таблице макроопределений, а копия исходного текста без макроопределений запоминается во внешней памяти, для использования ее при втором проходе. Помимо таблицы макроопределений во время первого прохода будет также таблица имен, во второй проход она будет использоваться для выделения макроопераций и расширения их до текста соответствующего макроопределения.
ДАННЫЕ ДЛЯ ПЕРВОГО ПРОСМОТРА
1. ВХТ - Входной текст
2. ВЫХ1 - Выходная копия текста для использования во второй проход.
3. МДТ - таблица макроопределений, в которой хранятся тела макроопределений
4. МНТ - таблица имен, необходимая для хранения имен макрокоманд, определенных в МНТ
5. МДТС - счетчик для таблицы МДТ
6. МНТС - счетчик для таблицы МНТ
7. АЛА - массив списка параметров для подстановки индексных маркеров вместо формальных параметров, перед запоминанием определения.
ДАННЫЕ ДЛЯ ВТОРОГО ПРОСМОТРА