Синтаксический анализатор логического выражения



 

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






 

Алгоритм построения процедур:

Для построения процедур просматривается правая часть правила для каждого нетерминала.

4. Если встречается нетерминальный символ, то вызывается процедура для этого символа. Если она завершается без ошибки, то в исходном тексте фраза для этого терма закрыта, и все семантические действия тоже выполнены.

5. Если встречается терминальный символ, он сравнивается с очередным символом входной строки. Если они совпадают, этот символ просто закрывается. Если не совпадают, то это синтаксическая ошибка и трансляция прекращается.

6. Если встречается метасимвол:

6.1. Если встречается {, то организуется цикл while, в который помещается все, что заключено в {}. Условием входа в цикл является то, что очередной символ не принадлежит множеству Follow для этого нетерминала.

6.2. Если встречается альтернатива, то организуется оператор if, или несколько вложенных операторов if для ветвления на столько путей, сколько альтернатив.

 

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

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

program rs1;

type leksema1=record

Tok:char;

atr:integer;

end;

var st:string; p:integer;

flagr:boolean;

Chislo,Bykva,r1: set of char;

file1,Ident,Numbers,Razdel1,Razdel2,Key,Lit,Comment:text;

leksema:leksema1;

 

procedure Err(a:integer);

begin

if a=1 then writeln('Ожидается конец файла');

if a=2 then writeln('Неверный символ');

if a=3 then writeln('Ожидается закрывающая скобка');

close (file1);

close (Numbers);

close (Ident);

close (Lit);

close (Razdel1);

close (Razdel2);

close (Comment);

close (Key);

Halt;

end;

 

procedure T; forward;

procedure L;

begin

if p=1 then Scan(st[p],leksema);

T;

if st[p]=' ' then

begin

p:=p+1;

Scan (st[p],leksema);

end;

while not((st[p]='#') or (st[p]=')')) do

begin

if (leksema.Tok='K') and (leksema.Atr=11) then begin

p:=p+1;

Scan(st[p],leksema);

T;

end

else begin if (Leksema.tok<>'K') and (leksema.Atr<>11) then

begin Err(2); flagr:=false; end

end;

end;

end;

 

procedure F; forward;

procedure T;

begin

F;

if st[p]=' ' then

begin

p:=p+1;

Scan (st[p],leksema);

end;

while not((st[p]='#') or (st[p]=')')) do

begin

if (leksema.Tok='K') and ((leksema.Atr=10) or (leksema.Atr=11)) then begin

Scan(st[p],leksema);

F;

end

else begin if (Leksema.tok<>'K') or (leksema.Atr<>10) then

begin Err(2); flagr:=false; end

end;

end;

end;

 

procedure E; forward;

procedure F;

begin

if st[p]=' ' then

begin

p:=p+1;

Scan (st[p],leksema);

end;

if (leksema.Tok='I') or (leksema.Tok='C') then begin

p:=p+1;

Scan(st[p],leksema);

end;

if leksema.Tok='R' then

if (leksema.Atr=19) or (leksema.Atr=20) or (leksema.Atr=21) then

begin

p:=p+1;

Scan(st[p],leksema);

E;

end;

if Leksema.Tok='D' then

if (leksema.Atr=2) or (leksema.Atr=3) or (leksema.Atr=4) then

begin

p:=p+1;

Scan(st[p],leksema);

E;

end;

if (leksema.Tok='R') and (leksema.Atr=11) then begin

p:=p+1;

Scan(st[p],leksema);

L;

if (leksema.Tok='R') and (leksema.Atr=12) then begin

p:=p+1;

Scan(st[p],leksema);

end

else begin Err(3); flagr:=false; end;

end;

end;

 

procedure E;

begin

F;

if st[p]=' ' then

begin

p:=p+1;

Scan (st[p],leksema);

end;

while not((st[p]='#') or (st[p]=')')) do

begin

if (leksema.Tok='I') and (leksema.Tok='C') then begin

p:=p+1;

Scan(st[p],leksema);

F;

end

else begin if (Leksema.tok='K')then L;

end;

end;

end;

 

begin

Chislo:=['0'..'9'];

Bykva:=['a'..'z', 'A'..'Z'];

r1:=[',','.',';',':','[',']','/','+','-','*','(',')','"','{','}','&','^','\','=','<','>'];

assign (file1,'file1_1.txt');

assign (Numbers,'Numbers1.txt');

assign (Ident,'Ident.txt');

assign (Lit,'Lit.txt');

assign (Razdel1,'Razdel1.txt');

assign (Razdel2,'Razdel2.txt');

assign (Comment,'Comment.txt');

assign (Key,'Key.txt');

reset (file1);

rewrite (Numbers);

rewrite (Ident);

rewrite (Lit);

reset (Razdel1);

reset (Razdel2);

rewrite (Comment);

reset (Key);

flagr:=true;

read (file1,st);

p:=1;

L;

if flagr=true then

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

close (file1);

close (Numbers);

close (Ident);

close (Lit);

close (Razdel1);

close (Razdel2);

close (Comment);

close (Key);

end.

3) Результаты:

Исходный файл:

(c<=5) or (b<9)#

Результат:

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

 

Исходный файл:

(c{5) or (b<9)#

Результат:

Неверный символ

 

Исходный файл:

(c<>5) or (b<9#

Результат:

Ожидается закрывающая скобка

 

Исходный файл:

(c<>5) or (b<9)

Результат:

Ожидается конец файла

 


Лабораторная работа №9


Дата добавления: 2018-04-05; просмотров: 401; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!