Чтение онлайн

на главную - закладки

Жанры

Искусство программирования для Unix

Реймонд Эрик Стивен

Шрифт:

Утилита lex была написана для автоматизации создания лексических анализаторов (анализаторов лексем) для компиляторов. Впоследствии оказалось, что она имеет удивительно широкий диапазон применения для других видов распознавания образцов, и с тех пор описывается как "швейцарский нож Unix-программирования" [125] .

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

125

Распространенное

более новое описание языка Perl как "швейцарской бензопилы" является производным.

Джон Джарвис (John Jarvis) в Холмделе (Holmdel — лаборатория AT&T) использовал lex для поиска неисправностей в монтажных платах. Он сканировал плату, применял методику кодирования цепей для представления границ областей на плате, а затем использовал Lex для определения образцов, с помощью которых можно было бы находить распространенные ошибки монтажа.

Майк Леск.

Важнее то, что мини-язык lex-спецификации является более высокоуровневым и компактным, чем эквивалентный С-код, написанный вручную. Доступны модули для использования flex (версия с открытым исходным кодом) с Perl (их можно найти в Web с помощью фразы "lex perl"), а также идентично работающая реализация, которая является частью средства PLY в Python.

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

Утилита yacc — генератор синтаксических анализаторов. Она также была написана для автоматизации части работы по написанию компиляторов, yacc принимает на входе грамматическую спецификацию в декларативном мини-языке, подобном BNF (Backus-Naur Form — запись Бэкуса-Наура), с С-кодом, связанным с каждым элементом грамматики. Данная программа генерирует код для функции синтаксического анализа, которая при вызове принимает текст, соответствующий грамматике из входного потока. По мере распознавания каждого грамматического элемента, функция анализатора запускает связанный С-код.

Комбинация утилит lex и yacc весьма эффективна для написания языковых интерпретаторов всех видов. Хотя большинству Unix-программистов никогда не придется выполнять данный вид универсального построения компилятора, для которого задумывались эти инструменты, они чрезвычайно полезны для написания анализаторов синтаксиса конфигурационных файлов и узкоспециальных мини-языков.

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

Если существует возможность реализовать анализатор на языке более высокого уровня, чем С (что и рекомендуется; см. главу 14), то следует рассмотреть такие

эквивалентные средства, как PLY в Python (которое охватывает функции lex и yacc) [126] или Perl-модули PY и Parse::Yapp, либо Java-пакеты CUP [127] , Jack [128] или Yacc/M [129] .

126

PLY можно загрузить со страницы <http://systems.cs.uchicago.edu/ply/>.

127

Пакет CUP

доступен на странице <http://www.cs.princeton.edu/~appel/modern/java/CUP>.

128

Пакет Jack доступен на странице <http://www.javaworld.com/javaworld/jw-12-1996/jw-12-jack.html>.

129

Пакет Yacc/M доступен на странице <http://david.tribble.com/yaccm.html>.

Как и в случае с макропроцессорами, одной из проблем, связанных с генераторами кода и препроцессорами, является то, что ошибки компиляции в сгенерированном коде могут содержать номера строк сгенерированного кода (который редактировать нежелательно), а не номера строк во входных данных генератора (т.е. там, где необходимо внести изменения). В утилитах yacc и lex данная проблема решается такими же конструкциями

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

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

15.3.1.1. Учебный пример: грамматика

fetchmailrc

Канонический демонстрационный пример, который, видимо, приводится в каждом учебном пособии по lex и yacc, представляет собой игрушечную программу интерактивного калькулятора, которая анализирует и вычисляет введенные пользователем арифметические выражения. В данной книге нет этого избитого клише. Заинтересованные читатели могут обратиться к исходному коду реализации bc(1) и dc(1) проекта GNU или к принципиальному примеру "hoc" [130] см. [39].

130

http://cm.bell-labs.com/cm/cs/upe/

Вместо этого грамматика анализатора конфигурационных файлов fetchmail предоставляет хороший учебный пример среднего размера по использованию lex и yacc. Здесь имеется несколько интересных моментов.

lexспецификация в файле

rcfile_l.l
— весьма типичная реализация shell-подобного синтаксиса. Обратите внимание на то, как два дополняющих правила поддерживают строки либо с одинарными, либо с двойными кавычками; данная идея хороша в принципе. Правила для принятия (возможно, со знаком) целых литералов и отклонения комментариев также являются достаточно распространенными.

yacc-спецификация в файле

rcfile_y.y
достаточно длинная, но понятная. Она не осуществляет каких-либо fetchmail– действий, а только устанавливает биты в списке внутренних управляющих блоков. После запуска fetchmail в обычном режиме программа только периодически проходит по данному списку, используя каждую запись для управления сеансом получения почты с удаленного узла.

15.3.2. Учебный пример: Glade

Программа Glade рассматривалась в главе 8 в качестве хорошего примера декларативного мини-языка. Также отмечалось, что в результате работы серверной части Glade генерируется код на одном из нескольких языков.

Glade представляет собой хороший современный пример генератора прикладного кода. Описанные ниже функции, которые отсутствуют в большинстве GUI-построителей (особенно в большинстве коммерческих GUI-построителей), делают Glade. Unix-программой "по духу".

Поделиться:
Популярные книги

Отмороженный 8.0

Гарцевич Евгений Александрович
8. Отмороженный
Фантастика:
постапокалипсис
рпг
аниме
5.00
рейтинг книги
Отмороженный 8.0

Газлайтер. Том 14

Володин Григорий Григорьевич
14. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 14

Ермак. Телохранитель

Валериев Игорь
2. Ермак
Фантастика:
альтернативная история
7.00
рейтинг книги
Ермак. Телохранитель

Матабар IV

Клеванский Кирилл Сергеевич
4. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар IV

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Идеальный мир для Лекаря 19

Сапфир Олег
19. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 19

Дочь моего друга

Тоцка Тала
2. Айдаровы
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Дочь моего друга

Свет Черной Звезды

Звездная Елена
6. Катриона
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Свет Черной Звезды

Кодекс Крови. Книга IV

Борзых М.
4. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга IV

Идеальный мир для Лекаря 22

Сапфир Олег
22. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 22

Попаданка в академии драконов 4

Свадьбина Любовь
4. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.47
рейтинг книги
Попаданка в академии драконов 4

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Лолита

Набоков Владимир Владимирович
Проза:
классическая проза
современная проза
8.05
рейтинг книги
Лолита

Сводный гад

Рам Янка
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Сводный гад