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

2.5. Операторы выбора

Операторы:

/ | ? $ ^

управляют процессом выбора символов.

Оператор /:

ab/cd

"ab" учитывается только тогда, когда за ним следует

"cd".

Опeратор |:

ab|cd

или "ab", или "cd".

Опeратор ?:

x? означает необязательный символ "x".

_?[A-Za-z]*

означает, что перед цепочкой любого количества латинс-

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

10

-?[0-9]+

выделит любое целое число с необязательным минусом впе-

реди.

Оператор $:

x$ означает выбрать символ "x", если он является последним

в строке. Стоит перед символом "\n"!

abc$ означает выбрать цепочку "abc", если она завершает

строку.

Оператор ^:

^x означает выбрать символ "x", если он является первым

символом строки;

^abc означает выбрать цепочку символов "abc", если она начи-

нает строку.

[^A-Z]*

означает все символы, кроме прописных латинских букв.

Когда символ ^ стоит перед выражением или внутри [], он

выполняет операцию дополнение. Внутри квадратных скобок

символ ^ должен обязательно стоять первым у открывающей

скобки!

2.6. Оператор {}

Оператор {} имеет два различных применения:

x{n,m} здесь n и m натуральные, m > n. Означает от n до m

вхождений x, например, x{2,7} - от 2 до 7 вхождений

x.

{имя} вместо {имя} в данное место выражения будет подстав-

лено определение имени из области определений Lex-

программы.

Пример:

БУКВА [A-ZА-Яa-zа-я_]

ЦИФРА [0-9]

ИДЕНТИФИКАТОР {БУКВА}({БУКВА}|{ЦИФРА})*

%%

{ИДЕНТИФИКАТОР} printf("\n%s",yytext);

lex построит лексический анализатор, который будет опреде-

лять и выводить все "слова" из входного файла. Под словом в

данном случае подразумевается идентификатор Си-программы. В

этом примере {ИДЕНТИФИКАТОР} будет заменен на

{БУКВА}({БУКВА}|{ЦИФРА})*, затем на [A-ZА-Яa-zа-я_]([A-ZА-

Яa-zа-я_]|[0-9])*.

11

yytext - это внешний массив символов программы

lex.yy.c, которую строит lex. yytext формируется в процессе

чтения входного файла и содержит текст, для которого уста-

новлено соответствие какому-либо выражению. Этот массив дос-

тупен пользовательским разделам Lex-программы.

Оператор printf выводит каждый идентификатор на новой

строке.

Правило ".|\n ;" используется для того, чтобы

пропустить (не выводить) все цепочки символов, которые не

соответствуют регулярному выражению {ИДЕНТИФИКАТОР}.

2.7. Оператор <&lt;>&gt;. Служебные слова START и BEGIN

Раздел правил Lex-программы может содержать активные и

неактивные правила. Активные правила выполняются всегда.

Неактивные выполняются только в тех случаях, когда выполня-

ется некоторое начальное условие.

Начальные условия Lex-программы помещаются в раздел

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

щими условиями. Оператор START позволяет указать список

начальных условий Lex-программы, а оператор BEGIN позволяет

активировать правила, помеченные начальными условиями.

Активные правила имеют следующий синтаксис:

РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ ДЕЙСТВИЕ

Неактивные правила имеют следующий синтаксис:

<&lt;МЕТКА_УСЛОВИЯ>&gt;РЕГ_ВЫРАЖЕНИЕ ДЕЙСТВИЕ

ВАЖНО: любое правило должно начинаться с первой позиции

строки, пробелы и табуляции недопустимы - они используются

как разделители между регулярным выражением и действием в

правиле!

Рассмотрим пример:

12

%START COMMENT

КОММ_НАЧАЛО "/*"

КОММ_КОНЕЦ "*/"

%%

{КОММ_НАЧАЛО} { ECHO;

BEGIN COMMENT;};

[\t\n]* ;

<COMMENT>[^*]* ECHO;

<COMMENT>[^/] ECHO;

<COMMENT>{КОММ_КОНЕЦ} {

ECHO;

printf("0);

BEGIN 0;};

lex построит лексический анализатор, который выделяет ком-

ментарии в Си-программе и записывает их в стандартный файл

вывода. Программа начинается с ключевого слова START, кото-

рое указано после символа %. Ключевое слово START можно

указать и так: Start, или S, или s . За ключевым словом

START указана метка начального условия COMMENT.

Оператор "<COMMENT>x" означает - x, если анализатор

находится в начальном условии COMMENT.

Oператор "BEGIN COMMENT;" переводит анализатор в

начальное условие COMMENT (смотрите первое правило раздела

правил этой Lex-программы). После этого анализатор уже нахо-

дится в новом состоянии и теперь разбор входного потока сим-

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

ются оператором "<COMMENT>". Например, правило

<COMMENT>[^*]* ECHO;

выполняется только тогда, когда во входном потоке символов

будет обнаружено начало комментариев ("/*"). В этом случае

анализатор записывает в стандартный файл вывода любое число

(в том числе и ноль) символов, отличных от символа "*". Опе-

ратор "BEGIN 0;" переводит анализатор в исходное состояние.

Lex-программа может содержать несколько помеченных

начальных условий. Например, если Lex-программа начинается

строкой

%START AA BB CC DD

то это означает, что она управляет четырьмя начальными сос-

тояниями анализатора. В каждое из этих начальных состояний

анализатор можно перевести, используя оператор BEGIN.

13

Каждое правило, перед которым указан оператор типа

"<&lt;МЕТКА>&gt;", мы будем называть помеченным правилом. Метка фор-

мируется так же, как и метка в Си.

Количество помеченных правил не ограничивается. Кроме

того, разрешается одно правило помечать несколькими метками,

например:

<&lt;МЕТКА1,МЕТКА2,МЕТКА3>&gt;x ДЕЙСТВИЕ

Запятая - обязательный разделитель списка меток!

Рассмотрим пример с несколькими начальными условиями:

%START AA BB CC

БУКВА [A-ZА-Яa-zа-я_]

ЦИФРА [0-9]

ИДЕНТИФИКАТОР {БУКВА}({БУКВА}|{ЦИФРА})*

%%

^# BEGIN AA;

^[ \t]*main BEGIN BB;

^[ \t]*{ИДЕНТИФИКАТОР} BEGIN CC;

\t ;

\n BEGIN 0;

<AA>define printf("Определение.\n");

<AA>include printf("Включение.\n");

<AA>ifdef {

printf("Условная компиляция.\n"); }

<BB>[^\,]*","[^\,]*")" {

printf("main с аргументамии.\n"); }

<BB>[^\,]*")" {

printf("main без аргументов.\n"); }

<CC>":"/[ \t] printf("Метка.\n");

Программа содержит активные и неактивные правила. Все неак-

тивные правила помечены, перед ними указана метка начального

условия. Lex-программа управляет тремя начальными условиями,

в соответствии с которыми активируются помеченные правила.

В результате работы lex мы получим лексический анализа-

тор, который будет распознавать в Си-программе строки преп-

роцессора Си-компилятора, выделять функцию main, распозна-

вая, с аргументами она или без них, распознавать метки.

Лексический анализатор не выводит ничего, кроме сообщений о

выделенных лексемах.

14

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