Скачиваний:
56
Добавлен:
08.01.2014
Размер:
2.6 Mб
Скачать

13.12. Генератор лексических анализаторовlex

Упражнение 13.66. Составьте вариант программы подсчета служебных слов языка Си, не учитывающий появление этих слов, заключенных в кавычки.

%{

uses lexlib;

const

_AND=1;

_ASM=2;

_ARRAY=3;

_BEGIN=4;

_CASE=5;

_CONST=6;

_CONSTRUCTOR=7;

_DESTRUCTOR=8;

_DIV=9;

_DO=10;

_DOWNTO=11;

_ELSE=12;

_END=13;

_EXPORTS=14;

_FILE=15;

_FOR=16;

_FUNCTION=17;

_GOTO=18;

_IF=19;

_IMPLEMENTATION=20;

_IN=21;

_INHERITED=22;

_INLINE=23;

_INTERFACE=24;

_LABEL=25;

_LIBRARY=26;

_MOD=27;

_NIL=28;

_NOT=29;

_OBJECT=30;

_OF=31;

_OR=32;

_PACKED=33;

_PROCEDURE=34;

_PROGRAM=35;

_RECORD=36;

_REPEAT=37;

_SET=38;

_SHL=39;

_SHR=40;

_STRING=41;

_THEN=42;

_TO=43;

_TYPE=44;

_UNIT=45;

_UNTIL=46;

_USES=47;

_VAR=48;

_WHILE=49;

_WITH=50;

_XOR=51;

_STR=52;

_IDENT=53;

%}

letter [a-zA-Z]

digit [0-9]

%%

'[^']*' begin yydone:=true; yyretval:=_STR; end;

\"[^\"]\" begin yydone:=true; yyretval:=_STR; end;

"end." begin yydone:=true; yyretval:=_END; end;

and begin yydone:=true; yyretval:=_AND; end;

asm begin yydone:=true; yyretval:=_ASM; end;

array begin yydone:=true; yyretval:=_ARRAY; end;

begin begin yydone:=true; yyretval:=_BEGIN; end;

case begin yydone:=true; yyretval:=_CASE; end;

const begin yydone:=true; yyretval:=_CONST; end;

constructor begin yydone:=true; yyretval:=_CONSTRUCTOR; end;

destructor begin yydone:=true; yyretval:=_DESTRUCTOR; end;

div begin yydone:=true; yyretval:=_DIV; end;

do begin yydone:=true; yyretval:=_DO; end;

downto begin yydone:=true; yyretval:=_DOWNTO; end;

else begin yydone:=true; yyretval:=_ELSE; end;

end begin yydone:=true; yyretval:=_END; end;

exports begin yydone:=true; yyretval:=_EXPORTS; end;

file begin yydone:=true; yyretval:=_FILE; end;

for begin yydone:=true; yyretval:=_FOR; end;

function begin yydone:=true; yyretval:=_FUNCTION; end;

goto begin yydone:=true; yyretval:=_GOTO; end;

if begin yydone:=true; yyretval:=_IF; end;

implementation begin yydone:=true; yyretval:=_IMPLEMENTATION; end;

in begin yydone:=true; yyretval:=_IN; end;

inherited begin yydone:=true; yyretval:=_INHERITED; end;

inline begin yydone:=true; yyretval:=_INLINE; end;

interface begin yydone:=true; yyretval:=_INTERFACE; end;

label begin yydone:=true; yyretval:=_LABEL; end;

library begin yydone:=true; yyretval:=_LIBRARY; end;

mod begin yydone:=true; yyretval:=_MOD; end;

nil begin yydone:=true; yyretval:=_NIL; end;

not begin yydone:=true; yyretval:=_NOT; end;

object begin yydone:=true; yyretval:=_OBJECT; end;

of begin yydone:=true; yyretval:=_OF; end;

or begin yydone:=true; yyretval:=_OR; end;

packed begin yydone:=true; yyretval:=_PACKED; end;

procedure begin yydone:=true; yyretval:=_PROCEDURE; end;

[pP][rR][oO][gG][rR][aA][mM] begin yydone:=true; yyretval:=_PROGRAM; end;

record begin yydone:=true; yyretval:=_RECORD; end;

repeat begin yydone:=true; yyretval:=_REPEAT; end;

set begin yydone:=true; yyretval:=_SET; end;

shl begin yydone:=true; yyretval:=_SHL; end;

shr begin yydone:=true; yyretval:=_SHR; end;

string begin yydone:=true; yyretval:=_STRING; end;

then begin yydone:=true; yyretval:=_THEN; end;

to begin yydone:=true; yyretval:=_TO; end;

type begin yydone:=true; yyretval:=_TYPE; end;

unit begin yydone:=true; yyretval:=_UNIT; end;

until begin yydone:=true; yyretval:=_UNTIL; end;

uses begin yydone:=true; yyretval:=_USES; end;

var begin yydone:=true; yyretval:=_VAR; end;

while begin yydone:=true; yyretval:=_WHILE; end;

with begin yydone:=true; yyretval:=_WITH; end;

xor begin yydone:=true; yyretval:=_XOR; end;

{letter}({letter}|{digit})* begin yydone:=true; yyretval:=_IDENT; end;

\n ;

. ;

%%

function yywrap:integer;

begin

yywrap:=1;

end;

const

words:array[_AND.._XOR] of string=(

'AND',

'ASM',

'ARRAY',

'BEGIN',

'CASE',

'CONST',

'CONSTRUCTOR',

'DESTRUCTOR',

'DIV',

'DO',

'DOWNTO',

'ELSE',

'END',

'EXPORTS',

'FILE',

'FOR',

'FUNCTION',

'GOTO',

'IF',

'IMPLEMENTATION',

'IN',

'INHERITED',

'INLINE',

'INTERFACE',

'LABEL',

'LIBRARY',

'MOD',

'NIL',

'NOT',

'OBJECT',

'OF',

'OR',

'PACKED',

'PROCEDURE',

'PROGRAM',

'RECORD',

'REPEAT',

'SET',

'SHL',

'SHR',

'STRING',

'THEN',

'TO',

'TYPE',

'UNIT',

'UNTIL',

'USES',

'VAR',

'WHILE',

'WITH',

'XOR' );

var

kwcount:array [1..51] of integer;

token,i:integer;

begin

if paramcount<>1 then

begin

writeln('Используйте: ', paramstr(0), ' файл');

exit;

end;

assign(yyinput,paramstr(1));

{$I-}

reset(yyinput);

if ioresult<>0 then

begin

writeln('Ошибка открытия для чтения ', paramstr(1));

exit;

end;

for i:=_AND to _XOR do

kwcount[i]:=0;

token:=yylex;

while not eof(yyinput) do

begin

if token in [_AND.._XOR] then

inc(kwcount[token]);

token:=yylex;

end;

if token in [_AND.._XOR] then

inc(kwcount[token]);

for i:=_AND to _XOR do

if kwcount[i]<>0 then

writeln('Слово ', words[i], ' встречается ', kwcount[i], ' раз');

close(yyinput);

end.

Упражнение 13.67. Составьте программу удаления из программы на языке Си всех комментариев. Обратите внимание на особые случаи со строками в кавычках и символьными константами; так строка char s[] = "/*"; не является началом комментария! Комментарии записывайте в отдельный файл.

%{

uses lexlib;

const

STROKA=1;

COMMENT=2;

ANY=3;

ENTER=4;

%}

%%

'[^']*' begin yyretval:=STROKA; yydone:=true; end;

\"[^"]*\" begin yyretval:=STROKA; yydone:=true; end;

"end." begin yyretval:=STROKA; yydone:=true; end;

\n begin yyretval:=ENTER; yydone:=true; end;

. begin yyretval:=ANY; yydone:=true; end;

"{"[^"}"]*"}" begin yyretval:=COMMENT;yydone:=true; end;

"/*""/"*([^*/]|[^*]"/"|"*"[^/])*"*"*"*/" begin

yyretval:=COMMENT;yydone:=true;

end;

"(*""("*([^*)]|[^*]")"|"*"[^)])*"*"*"*)" begin

yyretval:=COMMENT;yydone:=true;

end;

"//"[^\n]*\n begin yyretval:=COMMENT;yydone:=true; end;

%%

(*

function yywrap:boolean;

begin

writeln('end?');

yywrap:=true;

end;

*)

var

token:integer;

fresult,fcomment:text;

begin

if paramcount<>3 then

begin

writeln('Используйте: ', paramstr(0), ' исходный_файл результирующий_файл извлеченные_комментарии');

exit;

end;

assign(yyinput,paramstr(1));

{$I-}

reset(yyinput);

if ioresult<>0 then

begin

writeln('Ошибка открытия для чтения ', paramstr(1));

exit;

end;

assign(fresult,paramstr(2));

rewrite(fresult);

if ioresult<>0 then

begin

writeln('Ошибка создания ', paramstr(2));

exit;

end;

assign(fcomment,paramstr(3));

rewrite(fcomment);

if ioresult<>0 then

begin

writeln('Ошибка создания ', paramstr(3));

exit;

end;

token:=yylex;

while not eof(yyinput) do

begin

if token=COMMENT then

writeln(fcomment,yytext)

else

write(fresult,yytext);

token:=yylex;

end;

write(fresult,yytext);

close(yyinput);

close(fcomment);

close(fresult);

end.

Соседние файлы в папке Полищук, Семериков. Системное программирование в UNIX средствами Free Pascal