lex (813547), страница 14
Текст из файла (страница 14)
Одним из наиболее популярныхприложений в данной проблематике является лексический анализ комментариев в исходныхтекстах программ на различных алгоритмических языках высокого уровня.Лексическая обработка комментариев может производиться с различными целями. Например,исключение комментариев из исходного кода программы, выделение комментирующего текста,оценка степени "комментированности" программы. Ниже приводится пример файласпецификации лексем для лексического анализатора, который измеряет общую длинукомментирующего текста без учета пробелов, табуляций и переводов строк в исходном кодепрограммы на языке Pascal:%Start ISCOMOPENCOM"(*"CLOSECOM"*)"%{#include <stdio.h>extern int comcount;int comcount = 0;%}%%{OPENCOM}BEGIN ISCOM;<ISCOM>[^*\t \n]+comcount += yyleng;<ISCOM>\*/[^)]comcount++;{CLOSECOM}BEGIN 0;.|\n;%%int yywrap() {printf("(* %d *)\n", comcount);return(1);} /* yywrap */В языке программирования Pascal комментарии ограничивают символьные пары (* и *),которые идентифицируют, соответственно, начало и конец комментария.
Для их обозначения вфайле спецификации лексем введены регулярные определения OPENCOM и CLOSECOM,которые заданы в секции описаний. Кроме того, в секции описаний директивой %Startдекларируется метка предусловия ISCOM, которая обозначает состояние лексическогоанализатора при разборе входного текста внутри комментария, а также введен блок описанийдля подключения заголовочного файла <stdio.h> из системы программирования C иопределения внешней целочисленной переменной comcount, инициализированной нулевымзначением.Перечисленные инструкции секции описаний имеют вспомогательный характер и введены дляиспользования в секции правил, где лексический анализ комментариев осуществляется последующей схеме: найти открывающий ограничитель комментария, отобразить текст внутрикомментария, найти закрывающий ограничитель комментария.
В соответствии с этой схемойпервое правило с регулярным определением OPENCOM необходимо, чтобы обнаружитьоткрывающий ограничитель комментария и установить метку предусловия ISCOM операторомBEGIN. После этого становятся активны два следующих правила с предусловием ISCOM,действия которых соответствующим образом увеличивают значение счетчика комментариев,заданного внешней переменной comcount. При этом одно из указанных правил обеспечиваетобработку любой последовательности символов без пробелов, табуляций и перевода строки досимвола '*', который может быть началом закрывающего ограничителя комментария.
Другоеправило позволяет учитывать символы '*' внутри комментария. Обработку комментариязавершает правило с регулярным определением CLOSECOM, которое сбрасывает меткупредусловия ISCOM оператором BEGIN с нулевым аргументом. Последнее альтернативноеправило с пустым действием позволяет игнорировать все символы вне комментариев, а такжеразделители внутри них.Файл спецификации лексем завершает секция подпрограмм, которая в данном случаеиспользуется для перегрузки стандартной функции yywrap, которая автоматически вызываетсяв конце лексического анализа входного потока.
Перегрузка выполняется с целью обеспечитьотображение через поток стандартного вывода результирующего значения суммарной длиныкомментариев, которое сохраняет внешняя переменная comcount. Для этого используетсябиблиотечная функция printf системы программирования C. Аналогично стандартномуварианту перегруженная функция yywrap возвращает код 1, чтобы идентифицироватькорректное завершение процедуры лексического анализа.Рассмотренный файл спецификации лексем может быть подготовлен текстовым редактором исохранен, например, под именем compas.l в любом доступном каталоге файловой системы.Построение файла исходного кода лексического анализатора, например, под именем compas.cобеспечивает следующая командная строка вызова генератора LEX:$ lex –t compas.l > compas.cИсполняемый модуль лексического анализатора, например, в файле compas образуется поисходномутекступриследующемобращенииккомпилирующейсистемеязыкапрограммирования C:$ cc –o compas compas.c -llСледует отметить, что в данном случае для компоновки стандартного объектного кодаосновной функции main необходимо подключить библиотеку объектных модулей libl.a (илиразделяемый объект libl.so) генератора LEX, что указано последним аргументом (-ll) этойкомандной строки.Полученный исполняемый файл compas ориентирован на обработку стандартного ввода,поэтому его непосредственный вызов мало полезен, так как обычно требуется лексическийанализ комментариев в программе, исходный текст которой сосредоточен в файле.
Требуемуюлексическую обработку комментариев, например, в файле foo.pas обеспечивает следующийконвейер команд:$ cat foo.pas | compasПосле завершения лексического анализа файла foo.pas общая длина его комментариев будетотображена в потоке стандартного вывода соответствующим целым числом, котороеобрамляют ограничители комментариев языка программирования Pascal.В заключение следует отметить, что к классу рассмотренного примера относятся, в частности,следующие лексические задачи: поиск тегов языка HTML или текста между одноименнымитегами, обработка текста в кавычках или апострофах, распознавание IP-адресов или доменныхимен сети Internet, которые могут быть решены аналогичным образом.РЕКОМЕНДУЕМАЯ ЛИТЕРАТУРА1. С. БаурнОперационная система UNIX.
– М.: Мир, 1986.2. В.П. Тихомиров, М.И. ДавидовОперационная система ДЕМОС:Инструментальные средства программирования. – М.: Финансы и статистика, 1988.3. Б.В. Керниган, Р. ПайкUNIX – универсальная среда программирования. – М.: Финансы и статистика, 1992.4. Д.С. Амстронг, мл.Секреты UNIX. – М.: Диалектика, 2000.5. А. Ахо, Р. Сети, Д. УльманКомпиляторы:Принципы, технологии, инструменты.
– М.: Вильямс, 2001.6. Д. ФридлРегулярные выражения. – СПб.: Питер, 2001.7. Р. ХантерОсновные концепции компиляторов. – М.: Вильямс, 2002.8. Д. Хопкрофт, Р. Мотвани, Д. УльманВведение в теорию автоматов, языков и вычислений. – М.: Вильямс, 2002.СОДЕРЖАНИЕВВЕДЕНИЕ ……………………………………………………………………………………..РЕГУЛЯРНОЕ ВЫРАЖЕНИЕ ……………………………………………………………….Общая характеристика регулярных выражений ……………………………………Элементы регулярных выражений ……………………………………………………Конкатенация литералов ……………………………………………………………….Экранирование метасимволов ………………………………………………………....Коды символов и литеральные константы …………………………………………..Якорные метасимволы ………………………………………………………………….Выбор альтернатив ………………………………………………………………………Классы символов …………………………………………………………………………Квантификаторы …………………………………………………………………………Обработка контекста …………………………………………………………………….Группировка и ограничение регулярных фрагментов ……………………………..Структурный анализ регулярных выражений ………………………………………Конечные автоматы регулярных выражений ……………………………………….СПЕЦИФИКАЦИЯ ЛЕКСЕМ ……………………………………………………………….Структура файла спецификации лексем ……………………………………………..Секция описаний …………………………………………………………………………Спецификация правил …………………………………………………………………..Элементарные действия правил ……………………………………………………….Блоки действий …………………………………………………………………………..Встроенные переменные действий …………………………………………………….Стандартные функции действий ………………………………………………………Операторы действий …………………………………………………………………….Неоднозначные правила ………………………………………………………………...Функциональная реализация правил …………………………………………………Секция подпрограмм …………………………………………………………………….Обработка спецификации лексем ……………………………………………………...Пример разработки лексического анализатора ………………………………………РЕКОМЕНДУЕМАЯ ЛИТЕРАТУРА ………………………………………………………....