Язык XSLT, который используется для описания трансформаций XML-файлов, соответствует верхнему уровню сложности декларативных мини-языков. Он довольно сложен для того, чтобы рассматривать его как мини-язык, однако разделяет некоторые важные характеристики таких языков, которые подробнее рассматриваются ниже при изучении XSLT.
Спектр мини-языков простирается от декларативных (с неявными действиями) к императивным (с явными действиями). Синтаксис файла конфигурации программы fetchmail(1) можно рассматривать либо как очень слабый императивный язык, либо как декларативный язык с неявной управляющей логикой. Языки обработки текстов troff и PostScript являются императивными языками с большим количеством встроенной специальной информации о прикладной области.
Некоторые императивные мини-языки для решения специальных задач граничат с универсальными интерпретаторами. Они достигают данного уровня, когда явно являются языками Тьюринга , т.е. они могут выполнять условные операции и циклы (или рекурсию) [78] Любой язык Тьюринга мог бы теоретически использоваться для универсального программирования и теоретически является в точности таким же мощным, как любой другой язык Тьюринга. На практике некоторые языки Тьюринга были бы слишком сложными для использования за пределами специфической или узкой предметной области.
с функциями, которые предназначены для использования в качестве управляющих структур. В отличие от них, некоторые языки только отчасти являются языками Тьюринга. В них имеются функции, которые можно использовать для реализации управляющих структур как побочный эффект того, для чего они фактически предназначены.
Интерпретаторы bc(1) и dc(1), рассмотренные в главе 7, являются хорошими примерами специализированных императивных мини-языков, которые явно являются языками Тьюринга.
Такие языки, как Emacs Lisp и JavaScript, находятся в области универсальных интерпретаторов. Языки Emacs Lisp и JavaScript предназначены для использования в качестве полных языков программирования, работающих в специализированных средах. Более подробно они описываются ниже при рассмотрении встроенных языков сценариев.
Область интерпретаторов представляет собой область возрастающей неопределенности. Оборотной стороной этого является то, что более универсальный интерпретатор включает в себя меньше предположений о среде, в которой он работает. С возрастающей неопределенностью обычно приходит более развитая онтология типов данных. Shell и Tcl обладают сравнительно простой онтологией, a Perl, Python и Java — более сложной. Данные универсальные языки подробнее рассматриваются в главе 14.
8.2. Применение мини-языков
Разработка программ с помощью мини-языков затрагивает две отдельные проблемы. Одна из них заключается в том, чтобы уметь пользоваться имеющимися в инструментарии мини-языками и понимать, когда их можно применять такими, как они есть. Другая проблема — знать, когда целесообразно разрабатывать для приложения нестандартный мини-язык. Для того чтобы помочь читателю развить оба аспекта конструкторского мышления, почти половина данной главы состоит из учебных примеров.
8.2.1. Учебный пример: sng
В главе 6 рассматривалась утилита sng(1), преобразовывающая PNG-файл в редактируемую полностью текстовую форму. Формат файлов данных SNG заслуживает повторного рассмотрения здесь для контраста, поскольку он не вполне является узкоспециальным мини-языком. Он описывает расположение данных, но не связывает с ними какую-либо предполагаемую последовательность действий.
Однако SNG действительно имеет одну общую важную характеристику с узкоспециальными мини-языками, которую не поддерживают структурированные двоичные форматы данных, подобные PNG, — прозрачность. Структурированные файлы данных позволяют без использования мини-языка взаимодействовать средствам редактирования, преобразования и создания, которые не имеют информации о конструкторских "предположениях" друг друга. В случае SNG добавляется то, что данный формат как узкоспециальный мини-язык, предназначен для простого просмотра и редактирования с помощью универсальных средств.
8.2.2. Учебный пример: регулярные выражения
Одним из видов спецификации, который периодически появляется в инструментах Unix и языках сценариев, является регулярное выражение (regular expression, или regexp для краткости). Здесь регулярные выражения рассматриваются как декларативный мини-язык для описания текстовых шаблонов. Часто регулярные выражения встраиваются в другие мини-языки. Регулярные выражения настолько распространены, что их едва ли можно считать мини-языком, однако они заменяют то, что в противном случае представляло было собой огромные объемы кода, реализующего различные (и несовместимые) возможности поиска.
Читать дальше