Unix Man (Справочное руководство)


FLEX(1) - часть 10


she s++; he h++; \n | . ;

где два последних правила игнорируют все, кроме he и she. Следует помнить, что точка (.) не подбирает знак новой строки. Так как she включает he, то lex не будет распзнавать экземпляры he внутри she: обработав she, он больше к этому месту не возвращается.

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

she {s++;REJECT;} he {h++;REJECT;} \n | . ;

Эти правила - измененный вариант предыдущих примеров. Но их действие такое же. После подсчета каждого выражения, оно отклоняется. После каждого присваивания будет подсчитываться следующее выражение. В этом примере пользователь мог бы заметить, что she включает he, но не наоборот, и опустить действие REJECT относительно he. В других случаях нельзя указать, какой входной символ будет в обоих классах.

Рассмотрим два правила:

a[bc]+{...;REJECT;} a[cd]+{...;REJECT;}

Если вводится ab, то сопоставляется только первое правило, если ad - только второе. Входная символьная строка accb сопоставляется первому правилу (для четырех символов), и второму - для трех. Наоборот, ввод accd сопоставляется второму правилу для четырех символов, затем первому для трех.

REJECT полезно всегда, когда целью lex является не разделение входного потока, а обнаружение всех экземпляров определенных элементов входных данных. Эти элементы могут перекрываться или содержать в себе друг друга. Допустим, что требуется числовая таблица входных данных; числа перекрываются аналогично тому, как слово "the" содержит th и he. Следует определить двумерный массив digram. Тогда подойдет такой источник:

%% [a-z][a-z] {digram[yytext[0]yytext[1]]++;REJECT;} . ; \n ;

где REJECT необходим для выборки пары букв, начинающейся с любого символа, а не любого одного символа.

Следует помнить, что REJECT не просматривает входные данные повторно. Наоборот, он запоминает результаты предыдущего анализа. Это значит, что если найдено правило с последующим контекстом и исполнялось REJECT, то для изменения символов во входном потоке нельзя использовать input(). Это единственное ограничение, накладываемое на возможности обработки еще не просматривавшегося ввода.

Описание зависимости от левого контекста





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



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