Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
spo_otchet_chumak.doc
Скачиваний:
6
Добавлен:
01.04.2025
Размер:
206.85 Кб
Скачать

Лабораторная работа №9 Синтаксический анализ для оператора присваивания

1) Цель работы: создать программу, которая осуществляет синтаксический анализ оператора присваимвания:

2) Исходный текст программы:

program analyzer;

var buf,sl:string;

t:char;

ub,z,tag,n,i,count:integer;

f:text;

tab_k,tab_i,tab_r,tab_l:array [1..256] of string;

fail, bofl:boolean;

procedure err(a:integer);

begin

case a of

0: writeln('error: неверное число скобок');

1: writeln('error: ожидались символы ''*'',''/'',''+'',''-'',''('' или ''#'' [',ub-length(sl),']');

2: writeln('error: ожидался идентификатор или число [',ub-1,']');

3: writeln('error: неожиданный символ [',ub-1,']');

4: writeln('error: ожидался оператор присваивания [',ub-length(sl),']');

5: writeln('error: нельзя присваивать не в начале строки');

6: writeln('error:ожидалось логическое выражение [',ub-length(sl),']');

7: writeln('error: ожидалось ''do'' [',ub-length(sl),']');

end;

fail:=true;

close(f);

halt;

end;

procedure scan(var t:char; var n:integer);

procedure next_ub;

begin

if (ub<length(buf)) then

begin

ub:=ub+1;

//bofl:=false;

end

else

begin

readln(f,buf);

ub:=1;

//bofl:=true;

end;

if (buf[ub]='(') then count:=count+1 else if (buf[ub]=')') then count:=count-1;

end;

function ks(var c:char):boolean;

var i:integer;

begin

ks:=false;

if (c='k') then

begin

for i:=1 to 10 do

if (sl=tab_k[i]) then

begin

ks:=true;

tag:=i;

end;

end;

if (c='i') then

begin

for i:=1 to z do

if (sl=tab_i[i]) then

begin

ks:=true;

tag:=i;

end;

if (tag<>i) then tag:=z;

end;

if (c='r') then

begin

for i:=1 to 20 do

if (sl=tab_r[i]) then

begin

ks:=true;

tag:=i;

end;

end;

if (c='l') then

begin

for i:=1 to 5 do

if (sl=tab_l[i]) then

begin

ks:=true;

tag:=i;

end;

end;

//if not ((ub-length(sl))=1) then bofl:=false;

end;

var x,c:char;

state:integer;

f0:text;

begin

sl:='';

state:=0;

repeat

case state of

0: begin

x:=buf[ub];

if (((x>='a')and(x<='z'))or((x>='A')and(x<='Z'))) then

begin

sl:=sl+x;

next_ub;

state:=1;

end

else if ((x>='0')and(x<='9')) then

begin

sl:=sl+x;

next_ub;

state:=10;

end

else

begin

sl:=sl+x;

next_ub;

state:=5;

end;

end;

1: begin

x:=buf[ub];

if ((((x>='a')and(x<='z'))or((x>='A')and(x<='Z'))or((x>='0')and(x<='9')))and(ub<>1)) then begin sl:=sl+x; next_ub; end

else

begin

c:='k';

if ks(c) then state:=2

else

begin

c:='l';

if ks(c) then state:=7

else

begin

c:='i';

if ks(c) then state:=6 else state:=3;

end;

end;

end;

end;

10: begin

x:=buf[ub];

if ((x>='0')and(x<='9')) then begin sl:=sl+x; next_ub; end

else

begin

t:='c';

n:=0;

state:=4;

end;

end;

2: begin

t:='k';

n:=tag;

state:=4;

end;

3: begin

t:='i';

n:=tag;

tab_i[z]:=sl;

z:=z+1;

state:=4;

end;

5: begin

c:='r';

if ks(c) then

begin

t:='r';

n:=tag;

state:=4;

end

else err(3);

end;

6: begin

t:='i';

n:=tag;

state:=4;

end;

7: begin

t:='l';

n:=tag;

state:=4;

end;

end;

until (state=4);

end;

procedure scan1(var t:char; var n:integer);

var x,c:char;

state,ib:integer;

f0:text;

procedure next_ib;

begin

if (ib<length(buf)) then

begin

ib:=ib+1;

//bofl:=false;

end

else

if not(eof(f)) then begin

readln(f,buf);

ib:=1;

//bofl:=true;

end;

end;

function ks(var c:char):boolean;

var i:integer;

begin

ks:=false;

if (c='k') then

begin

for i:=1 to 10 do

if (sl=tab_k[i]) then

begin

ks:=true;

tag:=i;

end;

end;

if (c='i') then

begin

for i:=1 to z do

if (sl=tab_i[i]) then

begin

ks:=true;

tag:=i;

end;

if (tag<>i) then tag:=z;

end;

if (c='r') then

begin

for i:=1 to 20 do

if (sl=tab_r[i]) then

begin

ks:=true;

tag:=i;

end;

end;

if (c='l') then

begin

for i:=1 to 5 do

if (sl=tab_l[i]) then

begin

ks:=true;

tag:=i;

end;

end;

//if not ((ub-length(sl))=1) then bofl:=false;

end;

begin

ib:=ub;

sl:='';

state:=0;

repeat

case state of

0: begin

x:=buf[ib];

if (((x>='a')and(x<='z'))or((x>='A')and(x<='Z'))) then

begin

sl:=sl+x;

next_ib;

state:=1;

end

else if ((x>='0')and(x<='9')) then

begin

sl:=sl+x;

next_ib;

state:=10;

end

else

begin

sl:=sl+x;

next_ib;

state:=5;

end;

end;

1: begin

x:=buf[ib];

if ((((x>='a')and(x<='z'))or((x>='A')and(x<='Z'))or((x>='0')and(x<='9')))and(ib<>1)) then begin sl:=sl+x; next_ib; end

else

begin

c:='k';

if ks(c) then state:=2

else

begin

c:='l';

if ks(c) then state:=7

else

begin

c:='i';

if ks(c) then state:=6 else state:=3;

end;

end;

end;

end;

10: begin

x:=buf[ib];

if ((x>='0')and(x<='9')) then begin sl:=sl+x; next_ib; end

else

begin

t:='c';

n:=0;

state:=4;

end;

end;

2: begin

t:='k';

n:=tag;

state:=4;

end;

3: begin

t:='i';

n:=tag;

tab_i[z]:=sl;

z:=z+1;

state:=4;

end;

5: begin

c:='r';

if ks(c) then

begin

t:='r';

n:=tag;

state:=4;

end

else

begin

writeln('Неожиданный символ [',ib,']');

halt;

end;

end;

6: begin

t:='i';

n:=tag;

state:=4;

end;

7: begin

t:='l';

n:=tag;

state:=4;

end;

end;

until (state=4);

end;

procedure ee; forward;

procedure oppr; forward;

procedure oppr;

begin

if not bofl then err(5);

scan(T,n);

scan(T,n);

if not ((T='r')and(n=9)) then err(4)

else begin

ee;

scan1(T,n);

if not ((T='r')and(n=7)) then err(1);

end;

end;

procedure ff;

begin

scan(T,n);

if (T='i') then

begin

if not ((ub-length(sl))=1) then bofl:=false;

scan1(T,n);

if ((T='r')and(n=8)) then oppr;

end

else if (T='c') then

begin

end

else if (T='k') then

begin

if (n=4) then opw;

end

else if (T='l') then

begin

end

else if ((T='r')and(n=5)) then

begin

ee;

scan(T,n);

if ((T='r')and(n=6)) then begin end

else if ((T='r')and(n=11)) then begin

ee;

scan(T,n);

if not ((T='r') and (n=12)) then err(0); end

else err(0);

end

else err(2);

end;

procedure tt;

begin

ff;

scan1(T,n);

while (not((T='r') and ((n=1) or (n=2) or (n=6) or (n=7) or (n=12)))) do

begin

scan(T,n);

if ((T='r') and (n=3)) then ff else

if ((T='r') and (n=4)) then ff else

if ((T='r') and (n=10)) then ff else

err(1);

scan1(T,n);

end;

end;

procedure ee;

begin

tt;

While (not(((T='r') and (n=7))or((T='r') and (n=6)) or ((T='r')and(n=12)))) do

begin

scan(T,n);

if ((T='r') and (n=1)) then tt else

if ((T='r') and (n=2)) then tt else

err(1);

scan1(T,n);

end;

end;

procedure prepare;

begin

assign(f,'D:\op prisv\tab_r.txt');

reset(f);

i:=1;

repeat

readln(f,tab_r[i]);

i:=i+1;

until eof(f);

close(f);

assign(f,'D:\op prisv\tab_k.txt');

reset(f);

i:=1;

repeat

readln(f,tab_k[i]);

i:=i+1;

until eof(f);

close(f);

assign(f,'D:\op prisv\tab_l.txt');

reset(f);

i:=1;

repeat

readln(f,tab_l[i]);

i:=i+1;

until eof(f);

close(f);

assign(f,'D:\op prisv\text.txt');

reset(f);

readln(f,buf);

ub:=1;

z:=1;

count:=0;

bofl:=true;

if (buf[ub]='(') then count:=count+1 else if (buf[ub]=')') then count:=count-1;

end;

begin

prepare;

ee;

if (buf[ub]='(') then count:=count+1 else if (buf[ub]=')') then count:=count-1;

if (count<>0) then err(0);

writeln(' Строка правильная');

close(f);

assign(f,'D:\op prisv\tab_i.txt');

append(f);

for i:=1 to z-1 do

writeln(f,tab_i[i]);

close(f);

end.

Содержимое файла: (c<=5) or (b<9)#

В результате сканирования исходного текста получим сообщение:

Строка правильная

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