Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lex.docx
Скачиваний:
12
Добавлен:
20.03.2016
Размер:
133.64 Кб
Скачать

6. Функция reject

Обычно lex разделяет входной поток, не осуществляя

поиск всех возможных соответствий каждому выражению. Это

означает, что каждый символ рассматривается один и только

один раз. Предположим, что мы хотим подсчитать все вхождения

цепочек she и he во входном тексте. Для этого мы могли бы

записать следующие правила:

she s++;

he h++;

. |

\n ;

Так как she включает в себя he, анализатор не распознает те

вхождения he, которые включены в she, так как, прочитав один

раз she, эти символы он не вернет во входной поток.

Иногда желательно переопределить этот выбор. Действие

функции REJECT означает "выбрать следующую альтернативу".

Это приводит к тому, что каким бы ни было правило, после

него необходимо выполнить второй выбор. Соответственно изме-

нится и положение указателя во входном потоке:

29

she { s++; REJECT; }

he { h++; REJECT; }

. |

\n ;

Здесь после выполнения одного правила символы возвращаются

назад во входной поток, и выполняется другое правило.

Функция REJECT полезна в том случае, когда она применя-

ется для определения всех вхождений какого-либо объекта,

причем вхождения могут перекрываться или включать друг

друга. Предположим, необходимо получить из одного потока

таблицу всех двухбуквенных сочетаний, которые обычно перек-

рываются, например, слово the содержит как th, так и he.

Допустим, имеется двумерный массив digram, тогда:

%%

[a-z][a-z] {

digram[yytext[0]][yytext[1]]++;

REJECT;

}

\n ;

Здесь REJECT используется для выделения буквенных пар, начи-

нающихся на каждой букве, а не на каждой следующей.

7. Функции yyless и yymore

В обычной ситуации содержимое yytext обновляется всякий

раз, когда на входе появляется следующая строка. Напомним,

что в yytext всегда находятся символы распознанной последо-

вательности. Иногда возникает необходимость добавить к теку-

щему содержимому yytext следующую распознанную цепочку сим-

волов. Для этой цели используется функция yymore. Формат

вызова этой функции:

yymore()

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

все символы распознанной последовательности в yytext, а

только необходимое их число. Для этой цели используется

функция yyless. Формат ее вызова:

yyless(n)

где n указывает, что в данный момент необходимы только n

символов строки в yytext. Остальные найденные символы будут

возвращены во входной поток.

Пример использования фунцкии yymore:

30

.

.

.

\"[^"]* {

if( yytext[yyleng - 1] == '\\'){

yymore();

}else{

/*

* здесь должна быть часть

* программы, обрабатывающая

* закрывающую кавычку.

*/

}

}

.

.

.

В этом примере распознаются строки симвoлов, взятые в двой-

ные кавычки, причем символ двойная кавычка внутри этой

строки может изображаться с предшествующей косой чертой.

Анализатор должен распознавать кавычку, ограничивающую

строку, и кавычку, являющуюся частью строки, когда она изоб-

ражена как \".

Допустим, на вход поступает строка "абв\"где". Сначала

будет распознана цепочка "абв\ и, так как последним символом

в этой цепочке будет символ "\", выполнится вызов yymore().

В результате к цепочке "абв\ будет добавлено "где, и в

yytext мы получим: "абв\"где, что и требовалось.

Пример использования фунции yyless:

.

.

.

=-[A-ZА-Яa-zа-я] {

printf("Oператор (=-) двусмысленный.\n");

yyless(yyleng - 2);

/*

* здесь необходимо указать

* действия для случая "=-"

*/

}

.

.

.

В этом примере разрешается двусмысленность выражения "=-

31

буква" в языке Си. Это выражение можно рассматривать как

"=- буква" (равносильно "-=" )

или

"= -буква"

Предположим, что желательно эту ситуацию рассматривать как

"= -буква" и выводить пердупреждение. Указанное в примере

правило распознает эту ситуацию и выводит предупреждение.

Затем, в результате вызова "yyless(yyleng - 2);" два сим-

вола "-буква" будут возвращены во входной поток, а знак "="

останется в yytext для обработки, как в нормальной ситуации.

Таким образом, при продолжении чтения входного потока уже

будет обрабатываться цепочка "-буква", что и требовалось.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]