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

3.2.2. Порядок действия активных правил

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

неактивные правила, размещенные в любом порядке в разделе

правил. В процессе работы лексического анализатора список

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

тора BEGIN. В процессе распознавания символов входного

потока может оказаться так, что одна цепочка символов будет

удовлетворять нескольким правилам и, следовательно, возни-

кает проблема: действие какого правила должно выполняться?

Для разрешения этого противоречия можно использовать

квантование (разбиение) регулярных выражений этих правил

Lex-программы на такие новые регулярные выражения, которые

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

Однако, когда это не сделано, lex использует определенный

детерминированный механизм разрешения такого противоречия:

- выбирается действие того правила, которое распознает

наиболее длинную последовательность символов из вход-

ного потока;

21

- если несколько правил распознают последовательности

символов одной длины, то выполняется действие того

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

правил Lex-программы.

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

.

.

.

[Мм][Аа][Йй] ECHO;

[А-Яа-я]+ ECHO;

.

.

.

Слово "Май" распознают оба правила, однако, выполнится пер-

вое из них, так как и первое, и второе правило распознали

лексему одинакового размера (3 символа). Если во входном

потоке будет, допустим, слово "майский", то первые 3 символа

удовлетворяют первому правилу, а все 7 символов удовлетво-

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

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

ность символов.

3.3. Раздел программ пользователя

Все, что размещено за вторым набором %%, относится к

разделу программ пользователя. Содержимое этого раздела

копируется в выходной файл lex.yy.c без каких-либо измене-

ний. В файле lex.yy.c строки этого раздела рассматриваются

как функции в смысле Си. Эти функции могут вызываться в

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

чения аргументов.

3.4. Комментарии Lex-программы

Комментарии можно указывать во всех разделах Lex-

программы. Формат комментариев должен соответствовать фор-

мату комментариев host-языка. Однако, в каждом разделе Lex-

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

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

ции строки. В разделе правил комментарии можно указывать

только внутри блоков, принадлежащих действиям. В разделе

программ пользователя комментарии указываются как и в host-

языке.

3.5. Примеры Lex-программ

Пример1.

22

%Start KOMMENT

/*

* Программа записывает в

* стандартный файл вывода

* комментарии Си-программы.

* Обратите внимание на то, что

* здесь строки комментариев указаны

* не с первой позиции строки!

*/

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

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

%%

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

BEGIN KOMMENT;}

[0* ;

<KOMMENT>[^*]* ECHO;

<KOMMENT>[^/] ECHO;

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

ECHO;

printf("0);

/*

* Здесь приведен пример

* использования комментариев в

* разделе правил Lex-программы.

* Обратите внимание на то, что

* комментрий указан внутри блока,

* определяющего действие правила.

*/

BEGIN 0;}

%%

/*

* Здесь приведен пример комментариев

* в разделе программ пользователя.

*/

Пример 2.

23

%Start IC1 IC2 Normal

/*

* Отладочный фрагмент

* Lex-программы, которая строит

* лексический анализатор для

* компилятора языка Паскаль.

* Действие return(...)

* возвращает тип лексемы в

* в вызывающую анализатор

* программу.

* Обратите внимание на то, что в

* этой Lex-программе отсутствуют

* активные правила. Это сделано

* в связи с тем, что нет

* необходимости иметь правила,

* которые всегда активны.

* Все цепочки символов входного

* потока, не распознанные в

* правилах, копируются в выходной

* поток символов.

*/

LETTER [A-ZА-Яa-zа-я_]

DIGIT [0-9]

IDENT {LETTER}({LETTER}|{DIGIT})*

INT {DIGIT}+

FIXED {INT}?.{INT}

WHISP [ 0*

%%

BEGIN Normal;

<Normal>"{" BEGIN IC1;

<IC1>[^}] ;

<IC1>"}" BEGIN Normal;

<Normal>"(*" BEGIN IC2;

<IC2>[^*]|[^)] ;

<IC2>&gt;"*)" BEGIN Normal;

<Normal>'([^']|'')*' return( строка );

<Normal>"<>" return( не_равно );

<Normal>"=" return( равно );

<Normal>"<" return( меньше );

<Normal>">" return( больше );

<Normal>">=" return(больше_или_равно);

<Normal>"<=" return(меньше_или_равно);

<Normal>".." return( точка_точка );

<Normal>"+" return( плюс );

<Normal>"-" return( минус );

<Normal>":=" return( присвоить );

<Normal>"*" return( умножить );

<Normal>"/" return( разделить );

<Normal>mod return( t_mod );

24

<Normal>div return( t_div );

<Normal>and return( t_and );

<Normal>or return( t_or );

<Normal>not return( t_not );

<Normal>"(" return( lpar );

<Normal>")" return( rpar );

<Normal>"[" return( lbracket );

<Normal>"]" return( rbracket );

<Normal>"," return( comma );

<Normal>":" return( colon );

<Normal>"^" return( circumflex );

<Normal>";" return( semicolon );

<Normal>write return( Write );

<Normal>writeln return( Writeln );

<Normal>label return( t_label );

<Normal>program return( );

<Normal>const x( "константы" ) ;

<Normal>type x( "типы" ) ;

<Normal>var x( "перем" ) ;

<Normal>procedure x( "процедура" ) ;

<Normal>function x( "функция" ) ;

<Normal>begin x( "начало" ) ;

<Normal>end{WHISP}. x( "конец прогр" ) ;

<Normal>end x( "конец" ) ;

<Normal>array x( "массив" ) ;

<Normal>of x( "из" ) ;

<Normal>record x( "запись" ) ;

<Normal>case x( "выбор" ) ;

<Normal>in x( "в" ) ;

<Normal>file x( "файл" ) ;

<Normal>for x( "для" ) ;

<Normal>to x( "к" ) ;

<Normal>downto x( "вниз к" ) ;

<Normal>do x( "выполн" ) ;

<Normal>while x( "пока" ) ;

<Normal>repeat x( "повт" ) ;

<Normal>until x( "до" ) ;

<Normal>set x( "множество" ) ;

<Normal>with x( "с" );

<Normal>nil x( "nil" ) ;

<Normal>if x( "если" ) ;

<Normal>then x( "то" ) ;

<Normal>else x( "иначе" ) ;

<Normal>{FIXED} x( "float" ) ;

<Normal>{INT} x( "ц.б.з" ) ;

<Normal>{IDENT} x( "идент" ) ;

<Normal>[ 0] ;

%%

x( s )

char *s ;

{

25

printf("%-15.15s 177> %s <1770,

s, yytext ) ;

}

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