Парадигмы программирования

Языки макрообработки текстов


Изучается устройство ряда макропроцессоров, используемых при обеспечении гибкости кода программ. Кроме достаточно известных GPM и Trac, ассемблерной макротехники и препроцессоров систем программирования [[4],[28]], рассматриваются макропроцессоры нестандартных языков программирования, применявшиеся при факторизации текстов программ, разрабатываемых одновременно на разные архитектуры.

Макропроцессоры - мощный инструмент повышения емкости действий, образующих процессы информационной обработки. Главное предназначение макросов в системах программирования - достижение гибкости и переносимости текстов программ, применяемых в разных условиях. Многие трудности такого применения макротехники связаны с проблемой контроля типов данных на уровне текста программы. Исследования систем переписывания термов и разметки текстов пока не дали практичных решений в этой области. Современные информационные системы как правило содержат макропроцессоры как инструмент настройки на различные стандарты подготовки и обработки данных.

Начнем с классификации макропреобразований по мощности допустимых воздействий на обрабатываемые данные, предложенной в 1973 году А.А. Берсом:

  • чисто текстовая подстановка, обеспечивающая подготовку текстов по шаблонам и формулярам;
  • условная подстановка, допускающая при формировании текста использование статических параметров;
  • вычисляемые макропреобразования - вычисляются значения некоторых формул, возможно с использованием средств основного языка программирования.

Любой класс макропреобразований может использовать локальные или глобальные переменные, вложенность областей действия определений, рекурсию. Макропроцессор может быть встроен в компилятор, быть автономным инструментом системы программирования, таким как текстовый редактор, оптимизатор или отладчик, или существовать самостоятельно как универсальный инструмент общего назначения.

Обычно макроопределения формируются с учетом границ строк, макровызовы могут выполняться за одни просмотр или до исчерпания при итеративном анализе текста.
Возможно управление глубиной макроподстановки. Популярно синтаксическое подобие макросов выражениям базового языка, хотя это может вызывать путаницу в понимании реальных механизмов при порождении кода программы.

Для автономных макропроцессоров характерны специальные механизмы регулярного конструирования различимых текстов:

  • управляющие символы;
  • счетчики;
  • генераторы уникальных значений;
  • блоки активности (разметка);
  • встроенные функции;
  • управление вводом-выводом.


Макротехника обладает родством с методами конструирования регулярных выражений, техникой сопоставления данных с образцом (Snobol, Prolog), системами переписывания и современными языками разметки (xml, TeX и др.).

Макросом называют средство замены строки на другую, полученную из исходной по заранее заданным правилам. Такую замену осуществляет макропроцесор, управляемый системой макросов. Макропроцессор перерабатывает текст, содержащий вызовы макроса и новые макроопределения, пополняющие систему макросов. Различают общие и локальные макросы, воздействующие на всю текущую программу или на часть ее текста. Системы макросов могут организовываться в библиотеки.

Общеизвестно, что макрос легче применять, чем определять. Внешняя простота введения макросов сопряжена с вероятностью трудно обнаруживаемых ошибок периода исполнения программы, индуцированных случайным сходством с подпрограммами на основном языке программирования:

  • макрос меняет текст программы,
  • подпрограмма меняет данные программы и логику процесса исполнения программы.


Достаточно распространено определение макросов для нужд одной единственной программы, образующих с ней единое целое.

Большинство макропроцессоров допускают переменные макропериода - глобальные и локальные макропеременные.

Макротехника используется при автоматизации формирования различимых имен, например, различимые меток или имен переменных в программе.

Встречается интересное применение вложенности макровызовов и макроопределений, включая рекурсию.

ряд = | <сч = 0> -> [ 0 ] | | | [ ( | сч | + 1] | | | ряд [ сч - 1 ] | | | [ ) ] |______________________



ряд (6) = (6+ (5+ (4+ (3+ (2+ (1+0))))))

Пример 5.1.

Макротехника результативна не только на текстах, но и на геометрических фигурах, графах и кодах. Например, макросами можно описать всем известное пентамино, оптимизацию и кодогенерацию программ.

Техника строковой обработки обычно поддерживается операциями вычисления длины строки, выделения подстроки и конкатенации строк.

При поддержке динамически возникающих макроопределений традиционно обеспечивают самодостаточность, т.е. возможность развития макропроцессора своими средствами. Обычные требования:

  • Подстановка аргументов
  • Использование библиотек
  • Допущение переменных и структур данных
  • Присвоение значений переменных
  • Ветвления и переходы
  • Циклы, иерархия и рекурсия
  • Динамика обработки и создания новых макросов


Макропроцессор получает логическое завершение, поддерживая динамически формируемые макроопределения, возможно используя макровызовы в аргументах. Являясь инструментом расширения средств системы программирования, макропроцессор по своей природе должен быть развиваемым. Традиционная при разработке систем программирования общность и минимизация понятий оказывается не лучшим идеалом для разработки информационных систем массового назначения потому, что решение практических задач всегда сопряжено со множеством тривиальных мелочей, связанных с нелогичными особенностями оборудования или привычками пользователей. Макротехника дает сравнительно недорогой метод учета таких мелочей на уровне специализации системных приложений.

На практике макроассемблер выполняет роль расширенной системы команд. Такие команды могут обеспечивать специальные модули для обработки файлов с нестандартной информацией, например, распознавать текст с устаревшими или нестандартными шрифтами.

Отдельного решения требуют вопросы проявления в программах контекстов без макрообработки, таких как строковые константы и комментарии, выпадающие из общего строя языка программирования.

В системах программирования препроцессоры обычно формируют входной текст для компилятора, а макроассемблеры выполняют сборку кода на уровне ассемблера или объектного кода.





В текстовых процессорах - контекстная замена, контекстное редактирование и регулярные преобразования текста.

Техника выполнения макропреобразований достаточно разнообразна. Так, например, язык GPM всю работу с макросами сводит к маровызову вида:

$ mak, a1, a2, ... aN; - вызов макроса1)

Позиции макровызова занумерованы по числу предшествующих запятых, что делает не нужным описание переменных, одновременно с возможностью самоприменения определений.

~0 ~1 ~2 ... ~N - описание не нужно

Кроме того используются скобки, блокирующие подстановки при необходимости.

< S > - блокировка подстановок в S

Достаточно всего одной встроенной функции DEF, выполняющей введение макропределений.

$ DEF, mak, опр;

Пример 5.2. Введение новых макроопределений GPM

$ Def, size, 6; $ size; => 6 x ($size, $size) => x(6,6) size$size => size6

Пример 5.3. Использование макроопределений GPM

$Def, opp, UN~1; $opp, R; => ОШ - нет аргумента

$Def, opp, <UN~1>; $opp, R; => UNR

Пример 5.4. Использование блокировок в макроопределениях GPM

if A=B then C else D

$A, $Def, A , <D>; $def, B, <C>;;

Пример 5.5. Моделирование ветвлений макроопределенем GPM

В этом примере результат условного выражения обеспечен побочным эффектом на глобальной таблице имен.

Совершенно иначе выглядит макротехника в не менее лаконичном языке макропроцессора TRAC. Все сводится к макровызовам функций, встроенных и определяемых.

# (F, s1,s2,...,sN)

Встроенные функции:

ds - опр. строки cl - call ss - выделить сегмент rs - чтение строки

#(DS,ПРИМЕР, собака сидит на ковре) #(ss,ПРИМЕР,собака,ковре) #(cl,ПРИМЕР,кошка,кресле) = кошка сидит на кресле

Пример 5.6. Работа с шаблонами на языке Trac

Два интересных механизма макротехники были реализованы в проекте языка Setl при попытке его эффективной реализации посредством языка Little [[49],[32]].

Для поддержки переноса программы на разные архитектуры предлагался специальная разметка текста с помощью флагов, в зависимости от значения которых блоки строк включались во входной текст для компилятора.


Значения флагов можно было инициировать, наращивать или редуцировать и обнулять.

+ flag - включить строку. .flag - завершение блока, сопровождается увеличением или уменьшением счетчика, одноименного с флагом. - flag - пропустить строку.

Для автоматизации формирования фрагментов текста, обладающих зависимостью от численных характеристик или кратности вхождения в программу использовался специальный механизм специальных макропеременных:

zxN => N + I --- в строке размещается значение счетчика

zyN = N' => N' (zyN := N') --- задание значения спецпеременной

zaN => A(N+i) --- в строке размещается имя "а", сцепленное со значением счетчика

Пример 5.7. Представление зависимости от процесса формирования текста

В общем случае интерпретирующие автоматы для макропроцессоров характеризуются возможностью многократной обработки данных, до тех пор пока не будет получен результат без макровызовов. Соответствующая универсальная функция построения результата макрообработки получается реализационно не очень простой.

Подобные механизмы макрообработки текстов используются препроцессорами в стандартных системах программирования и текстовых процессорах. Иногда встречаются и более специализированные средства, использующие счетчиковые переменные, конструкторы уникальных имен, моделирующие иерархию модулей или параметризующие зависимость вариантов программы от целевых архитектур.

Концептуально макротехника близка продукционному стилю программирования, языкам разметки и системам переписывания текстов, в настоящее время активно развивающимся как языки гипертекстов для разработки сайтов и информационных сервисов.

  1)

  Символ $ набран вместо параграфа

Содержание раздела