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

4. Структура файла lex.Yy.C

lex строит программу - лексический анализатор на языке

Си, которая размещается в файле со стандартным именем

lex.yy.c. Эта программа содержит две основных функции и нес-

колько вспомогательных. Основные - это:

функция yylex()

Она содержит разделы действий всех правил, которые

определены пользователем;

функция yylook()

Она реализует детерминированный конечный автомат, кото-

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

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

программы.

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

мами ввода-вывода. К ним относятся:

input()

читает и возвращает символ из входного потока символов;

unput(c)

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

ного чтения;

output(c)

выводит в выходной поток символ c.

Эти функции определены как макроподстановки следующим

образом:

input -

fprintf( fout, "%s%d%s0,

"#define input() (((yytchar=yysptr>yysbuf

ctable['0],

"?(yylineno++,yytchar):yytchar)==EOF?0:yyt

unput -

26

#define unput(c){

yytchar = (c);

if( yytchar == '\n' ) yylineno--;

*yysptr++ = yytchar;

}

output -

#define output(c) putc(c,yyout)

Эти функции можно изменить, указав им те же имена и

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

При сборке программы лексического анализа редактор

связи ld по флагу -ll подключает головную функцию main, если

она не определена. Ниже приведен текст этой функции из биб-

лиотеки /usr/lib/libl.a

# include "stdio.h"

main(){

yylex();

exit(0);

}

5. Функция yywrap()

Функция yywrap используется для определения конца

файла, из которого лексический анализатор читает поток сим-

волов. Если yywrap возвращает 1, лексический анализатор

прекращает работу. Однако, иногда имеется необходимость

начать ввод данных из другого источника и продолжить работу.

В этом случае пользователь должен написать свою подпрограмму

yywrap, которая организует новый входной поток и возвращает

0, что служит сигналом к продолжению работы анализатора. По

умолчанию yywrap всегда возвращает 1 при завершении входного

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

В Lex-программе невозможно записать правило, которое

будет обнаруживать конец файла. Единственный способ это сде-

лать - использовать фунцию yywrap. Эта функция также удобна,

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

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

зователя новый вариант функции yywrap. Пример:

27

%START AA BB CC

/*

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

* который распознает наличие

* включений файлов в Си-программе,

* условных компиляций,

* макроопределений,

* меток и головной функции main.

* Анализатор ничего не выводит, пока

* осуществляется чтение входного

* потока, а по его завершении

* выводит статистику.

*/

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

ЦИФРА [0-9]

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

int a1,a2,a3,b1,b2,c;

%%

{a1 = a2 = a3 = b1 = b2 = c = 0;}

^# BEGIN AA;

^[ \t]*main BEGIN BB;

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

\t ;

\n BEGIN 0;

<AA>define { a1++; }

<AA>include { a2++; }

<AA>ifdef { a3++; }

<BB>[^\,]*","[^\,]*")" { b1++; }

<BB>[^\,]*")" { b2++; }

<CC>":"/[ \t] { c++; }

%%

yywrap(){

if( b1 == 0 && b2 == 0 )

printf("В программе\

отсутствует функция main.\n");

if( b1 >= 1 && b2 >= 1 ){

printf("Многократное\

определение функции main.\n");

} else {

if(b1 == 1 )

printf("Функция main\

28

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

if( b2 == 1 )

printf("Функция main\

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

}

printf("Включений файлов: %d.\n",a2);

printf("Условных компиляций: %d.\n",a3);

printf("Определений: %d.\n",a1);

printf("Меток: %d.\n",c);

return(1);

}

Оператор return(1) в функции yywrap указывает, что лек-

сический анализатор должен завершить работу. Если необходимо

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

файла, нужно указать return(0), предварительно осуществив

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

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

если yywrap не возвращает 1, то это приводит к бесконечному

циклу.

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