Операционная система UNIX. Руководство программиста


Действия


После того, как lex распознает цепочку, сопоставляемую с регулярным выражением, заданным в начале правила, он ищет в правой части правила действие, которое надо выполнить. Среди возможных видов действий - запись типа обнаруженной лексемы и значения, которое принимает лексема (если таковые имеются); замена одной лексемы на другую; подсчет числа вхождений лексем или типов лексем. Все, что Вы хотите проделать, нужно записать в виде фрагментов программ на языке C. Действие может состоять из произвольного числа операторов. Можно напечатать сообщение с найденным текстом или сообщение, как-то трансформирующее этот текст. Так, чтобы распознать выражение Amelia Earhart и сообщить об этом, можно специфицировать правило:

"Amelia Earhart" printf("нашли Amelia");

Чтобы заменить в тексте длинные медицинские термины их эквивалентными обозначениями, следует воспользоваться правилом

Electroencephalogram printf("EEG");

Если требуется подсчитать число строк в тексте, нужно распознавать признаки конца строк и увеличивать на единицу счетчик строк. lex использует стандартные для языка C управляющие последовательности символов, подобные \n для символа перевода строки. Для подсчета числа строк можно использовать правило

\n lineno++;

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

lex сохраняет каждую сопоставленную цепочку в массиве символов yytext[]. Вы можете распечатать содержимое этого массива или манипулировать им, как угодно. Иногда Ваше действие может состоять из двух или большего числа C-операторов и Вы должны (или решили из соображений стиля и ясности) написать их на нескольких строках. Чтобы информировать lex о том, что действие относится к одному правилу, надо просто заключить C-операторы в скобки. Например, чтобы подсчитать общее число всех цепочек цифр во входном тексте, печатать текущее общее число таких цепочек и выводить каждую из них, как только она обнаружена, можно воспользоваться такой записью:

\+?[0-9]+ { digstrgcount++; printf("%d",digstrngcount); yytext [yyleng] = (char) 0; printf("%s",yytext); }

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




- Начало -  - Назад -  - Вперед -



Книжный магазин