Искусство программирования для Unix - Реймонд Эрик Стивен
Шрифт:
Интервал:
Закладка:
8.2.8. Учебный пример: awk
Мини-язык awk является инструментальным средством Unix старой школы, прежде широко используемым в shell-сценариях. Как и т4, утилита awk предназначена для написания небольших, но выразительных программ для преобразования текстового ввода в текстовый вывод. Версии утилиты поставляются со всеми Unix-системами. Некоторые из них реализованы с открытым исходным кодом. Команда info gawk в командной строке Unix весьма вероятно позволит получить справочную документацию по программе.
Программы, написанные на awk, состоят из пар шаблон/действие. Каждый шаблон представляет собой регулярное выражение", эта концепция подробно описывается в главе 9. После запуска ада£-программа последовательно анализирует все строки во входном файле. Каждая строка по порядку сравнивается с парой шаблон/действие. Если шаблон соответствует строке, то осуществляется связанное с шаблоном действие.
Каждое действие кодируется на языке, подобном подмножеству языка С, с переменными, условными операторами, циклами и онтологией типов, включая целые числа, строки и (в отличие от С) словари".
Язык действий awk является языком Тьюринга и позволяет считывать и записывать файлы. В некоторых версиях он также позволяет открывать и использовать сетевые сокеты. Однако awk главным образом используется как генератор отчетов, особенно для интерпретации и предварительной обработки табличных данных. Он редко используется автономно, но часто встраивается в сценарии. В главе 9, в учебном примере по созданию HTML-документа имеется пример аю&-программы.
Учебный пример awk приведен в этой книге, чтобы подчеркнуть, что данный язык не является моделью для подражания. Фактически с 1990 года awk почти совершенно вышел из употребления. На смену ему пришли языки сценариев новой школы, особенно Perl, который явно предназначался для того, чтобы полностью вытеснить awk. Причины достойны внимания, поскольку они поучительны для разработчиков мини-языков.
Язык awk первоначально разрабатывался как небольшой, выразительный язык специального назначения для создания отчетов. К сожалению, его соотношение сложность-мощность оказалось неудачным. Язык действий некомпактен, а шаблон-но-управляемая структура, внутри которой он содержится, не позволяет применять его широко. Данный язык унаследовал худшие черты обоих миров. Кроме того, языки сценариев новой школы могут решать все задачи, решаемые awk. Эквивалентные программы, написанные на этих языках, обычно также, если не лучше, читабельны.
Язык awk вышел из употребления также вследствие того, что более современные оболочки обладают средствами вычислений с плавающей точкой, ассоциативными массивами, поддержкой регулярных выражений и средствами обработки подстрок, поэтому эквивалентные небольшим awk-сценариям программы могут быть реализованы без издержек создания процесса.
Дэвид Корн.
В течение нескольких лет после выхода языка Perl в 1987 году, awk оставался конкурентоспособным просто потому, что имел меньшую и более быструю реализацию. Однако по мере того как стоимость вычислительных циклов и памяти падала, экономические причины для привлекательности языка специального назначения, который сравнительно экономно использовал оба ресурса, теряли свою силу. Программисты для реализации аге^-подобных функций все более отдавали предпочтение Perl или (позднее) языку Python, вместо того, чтобы удерживать в памяти два различных языка сценария". К 2000 году awk стал для большинства Unix-хакеров старой школы немногим больше, чем воспоминание, но не самое дорогое.
Снижение цен изменило компромиссы проектирования мини-языков. Ограничение возможностей конструкции ради компактности, возможно, до сих пор является хорошей идеей, но такое же ограничения в целях экономии аппаратных ресурсов — идея неудачная. Со временем аппаратные ресурсы становятся дешевле, а простран-, ство в памяти программистов дороже. Современные мини-языки могут быть универсальными и некомпактными, или специализированными и очень компактными, но специализированные и некомпактные просто не выдержат конкуренции.
8.2.9. Учебный пример: PostScript
PostScript — мини-язык, специализацией которого является описание форматированного текста и графики для графических устройств. Данный язык был импортирован в Unix. Он основывался на разработке легендарного центра "Xerox Palo Alto Research Center", созданной во время появления первых лазерных принтеров. В течение нескольких лет после выхода первой коммерческой версии в 1984 году, PostScript оставался доступным только как частный продукт Adobe, Inc. и главным образом ассоциировался с компьютерами Apple. PostScript был клонирован на условиях лицензионного соглашения, очень близкого к лицензиям на открытые исходные коды, и с тех пор стал стандартом де-факто для управления принтерами в операционной системе Unix. Версия с полностью открытым исходным кодом поставляется с большинством современных Unix-систем65. Также доступно подробное техническое введение в PostScript66.
PostScript обладает некоторым функциональным сходством с разметкой troff. Оба языка предназначены для управления принтерами и другими графическими устройствами, и оба обычно генерируются программами или пакетами макрокоманд, а не вручную. Однако тогда как запросы troff являются быстро созданным набором кодов для управления форматом, PostScript был спроектирован снизу вверх как язык и является гораздо более выразительным и мощным. Главное из того, что делает PostScript, — это алгоритмические описания изображений, имеющие гораздо меньшие размеры, чем представленные ими растровые изображения, и поэтому требующие меньше пространства для хранения и меньшей полосы пропускания при передаче.
PostScript является явным языком Тьюринга, поддерживающим условные операции, циклы, рекурсию и именованные процедуры. Онтология типов включает в себя целые и действительные числа, строки и массивы (каждый элемент массива может иметь любой тип), но не имеет эквивалента структур. Технически PostScript является языком, работающим со стеками. Аргументы примитивных процедур (операторов) PostScript обычно извлекаются из магазинного стека аргументов, а результат (или результаты) возвращаются обратно в стек.
Существует около 40 базовых операторов (при том, что общее их приблизительное количество — 400). Большую часть работы выполняет оператор show, который отображает строку на странице. Другие операторы устанавливают текущий шрифт, изменяют цвет, рисуют линии, дуги или кривые Безье, окрашивают закрытые области, устанавливают области отсечения, а также выполняют другие операции. Подразумевается, что интерпретатор PostScript транслирует данные команды в растровые изображения для передачи на экран или печатный носитель.
Остальные PostScript-операторы реализуют арифметические операции, управляющие структуры и процедуры. Они позволяют выражать повторяющиеся или стереотипные изображения (такие как текст, составленный из повторяющихся графических форм знаков) в виде программ, объединяющих изображения. Часть эффективности PostScript связана с тем фактом, что PostScript-программы для печати текста или простой векторной графики являются гораздо менее громоздкими, чем растровые изображения, в которые преобразовывается текст или векторы. Кроме того, PostScript-программы независимы от разрешающей способности устройств и быстрее передаются по сетевому кабелю или последовательной линии.
Исторически PostScript-интерпретация на основе стеков имеет сходство с языком FORTH, который первоначально предназначался для управления приводами телескопов в реальном времени и имел кратковременную популярность в 80-х годах прошлого века. Языки обработки стеков отличаются превосходной поддержкой чрезвычайно плотного, экономичного кода и печально известны тем, что их трудно читать. Для PostScript характерны обе эти особенности.