Скачиваний:
27
Добавлен:
02.05.2014
Размер:
200.7 Кб
Скачать

Министерство образования РФ

Уфимский Государственный Авиационный Технический Университет

Кафедра ТК

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

“ Построение простейшего дерева вывода”

Выполнил: ст.гр УТС-411

Файзуллин Р.Р.

Проверил: доцент кафедры ТК

Карамзина А.Г.

Уфа 2007

Цель работы: изучение основных понятий теории грамматик простого и операторного предшествования, ознакомление с алгоритмами синтаксического анализа (разбора) для некоторых классов КС-грамматик, получение практических навыков создания простейшего синтаксического анализатора для заданной грамматики операторного предшествования.

Задание: Для выполнения лабораторной работы требуется написать программу, которая выполняет лексический анализ входного текста в соответствии с заданием, порождает таблицу лексем и выполняет синтаксический разбор текста по заданной грамматике с построением дерева разбора. Текст на входном языке задается в виде символьного (текстового) файла. Допускается исходить из условия, что текст содержат не более одного предложения входного языка. Программа должна выдавать сообщения о наличие во входном тексте ошибок.

Исходная грамматика приведена ниже. Терминальные символы выделены жирным шрифтом. Вместо символа a должны подставляться лексемы.

S ® a := F;

F ® F or T | F xor T | T

T ® T and E | E E ® (F) | not (F) | a

варианта

варианта грамматики

Допустимые лексемы входного языка

2

2

Идентификаторы, константы true и false

Таблица 1. Множество крайне левых и крайне правых символов.

Символы U

L(U)

R(U)

S

a

;

F

F,T,E,(,not,a

T,E,),a

T

T,E,(,not,a

E,),a

E

(,not,a

),a

Таблица 2. Множество крайне левых и крайне правых терминальных символов.

Символы U

L(U)

R(U)

S

a

;

F

or,xor,and,(,not,a

or,xor,and,),a

T

and,(,not,a

and,),a

E

(,not,a

),a

Таблица 3. Матрица операторного предшествования.

Символы

a

or

xor

not

and

:=

;

(

)

конец

a

>

>

>

=

>

>

or

<

>

>

<

<

>

<

>

xor

<

>

>

<

<

>

<

>

not

=

and

<

>

>

<

<

>

<

>

:=

<

<

<

<

<

=

<

;

>

(

<

<

<

<

<

<

=

)

>

>

>

>

>

начало

<

Листинг программы:

unit Unit2;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ComCtrls, StdCtrls, Grids;

type

TAutoState = ( AUTO_H, AUTO_ZZ, AUTO_OO, AUTO_Q, AUTO_R, AUTO_E, AUTO_Q1, AUTO_S, AUTO_A, AUTO_A1, AUTO_A2, AUTO_I, AUTO_N, AUTO_N1, AUTO_N2, AUTO_O, AUTO_O1, AUTO_X, AUTO_X1, AUTO_X2, AUTO_F, AUTO_F1, AUTO_F2, AUTO_F3, AUTO_F4, AUTO_T, AUTO_T1, AUTO_T2, AUTO_T3 );

TForm1 = class(TForm)

OpenDialog1: TOpenDialog;

PageControl1: TPageControl;

TabSheet1: TTabSheet;

Edit1: TEdit;

Button1: TButton;

Button2: TButton;

Memo1: TMemo;

TabSheet2: TTabSheet;

StringGrid1: TStringGrid;

Button3: TButton;

Memo2: TMemo;

Label1: TLabel;

Label2: TLabel;

Edit2: TEdit;

TabSheet3: TTabSheet;

Label3: TLabel;

Memo3: TMemo;

TreeView1: TTreeView;

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure Button3Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

Var str:string;

begin

str:=Edit1.Text;

if Edit1.Text<>'' then Memo1.Lines.LoadFromFile(str)

else ShowMessage('Поле ввода файла пустое!');

end;

procedure TForm1.Button2Click(Sender: TObject);

begin

if OpenDialog1.Execute then Memo1.Lines.LoadFromFile(OpenDialog1.FileName) ;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

Memo1.Text:='';

Memo2.Text:='';

Memo3.Text:='';

StringGrid1.Cells[0,0]:='¹ ï/ï';

StringGrid1.Cells[1,0]:='Значение';

StringGrid1.Cells[2,0]:='Лексема';

end;

procedure TForm1.Button3Click(Sender: TObject);

Const N1=10;

N2=7;

N3=10;

N4=5;

Label M1,M2;

var

CepofV:array [1..100]of integer;

p,stek,d:TStringList;

ind,dl,i,j,i1,i2,i4,j2,fl,fl2,zn,n,m,k,vetv,u:integer;

st,str,stroka,o1,o2,o3,o4,o5,o6,pr:string;

sost:TAutoState;

MyTreeNode:TTreeNode;

nodeTree: TTreeNode;

const

matrix: array [1..N3,1..N3] of char =(

(' ','>','>',' ','>','=','>',' ','>',' '),

('<','>','>','<','<',' ','>','<','>',' '),

('<','>','>','<','<',' ','>','<','>',' '),

(' ',' ',' ',' ',' ',' ',' ','=',' ',' '),

('<','>','>','<','>',' ','>','<','>',' '),

('<','<','<','<','<',' ','=','<',' ',' '),

(' ',' ',' ',' ',' ',' ',' ',' ',' ','>'),

('<','<','<','<','<',' ',' ','<','=',' '),

(' ','>','>',' ','>',' ','>',' ','>',' '),

('<',' ',' ',' ',' ',' ',' ',' ',' ',' '));

prav_1:array [1..N2,1..2] of string= (

('1','a:=E;'),

('2','EorE'),

('3','ExorE'),

('4','EandE'),

('5','(E)'),

('6','not(E)'),

('7','a'));

term:array [1..N1,1..2] of string =(

('1','a'),

('2','or'),

('3','xor'),

('4','not'),

('5','and'),

('6',':='),

('7',';'),

('8','('),

('9',')'),

('10','@'));

{ prav_2:array [1..N2,1..N4] of string=(

('1','a',':=','E',';'),

('2','E','or','E',''),

('3','E','xor','E',''),

('4','E','and','E',''),

('5','(','E',')',''),

('6','not','(','E',')'),

('7','a','','','')); }

notterm:array [1..7] of char=

('E','E','E','E','E','E','E');

Canon:array [1..7,1..4] of string= (

('a',':=','E',';'),

('E','or','E',''),

('E','xor','E',''),

('E','and','E',''),

('(','E',')',''),

('not','(','E',')'),

('a','','',''));

begin

u:=1;

p:=TStringList.Create;

p.Sorted:=False;

stek:=TStringList.Create;

stek.Sorted:=False;

d:=TStringList.Create;

d.Sorted:=False;

for i:=0 to 2 do

for i1:=1 to 999 do

StringGrid1.Cells[i,i1]:='';

i1:=Memo1.Lines.Count;

if i1=0 then begin ShowMessage('Ошибка! Файл пуст!'); exit;end;

ind:=1;

for i:=1 to i1 do

begin

str:='';

stroka:=Memo1.Lines[i-1];

stroka:=stroka+' ';

dl:=Length(stroka);

sost:=AUTO_H;

fl:=0;

zn:=0;

for j:=1 to dl do

begin

st:=stroka[j];

case sost of

AUTO_H:

case stroka[j] of

';': begin sost:=AUTO_R;str:=str+st; end;

'(': begin sost:=AUTO_OO;str:=str+st; end;

')': begin sost:=AUTO_ZZ;str:=str+st; end;

':': begin sost:=AUTO_Q;str:=str+st; end;

'a': begin sost:=AUTO_A;str:=str+st; end;

'n': begin sost:=AUTO_N;str:=str+st; end;

'o': begin sost:=AUTO_O;str:=str+st; end;

'x': begin sost:=AUTO_X;str:=str+st; end;

't': begin sost:=AUTO_T;str:=str+st; end;

'f': begin sost:=AUTO_F;str:=str+st; end;

'b'..'e','g'..'m','p'..'s','u'..'w','y','z': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;str:=''; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_R:

case stroka[j] of

' ': begin sost:=AUTO_H;fl:=1;zn:=1; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_OO:

case stroka[j] of

' ': begin sost:=AUTO_H;fl:=1;zn:=2; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_ZZ:

case stroka[j] of

' ': begin sost:=AUTO_H;fl:=1;zn:=3; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_Q:

case stroka[j] of

'=': begin sost:=AUTO_Q1;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_Q1:

case stroka[j] of

' ': begin sost:=AUTO_H;fl:=1;zn:=4; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_A:

case stroka[j] of

'a'..'m','o'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'n': begin sost:=AUTO_A1;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_A1:

case stroka[j] of

'a'..'c','e'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'd': begin sost:=AUTO_A2;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_A2:

case stroka[j] of

'a'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=6; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_N:

case stroka[j] of

'a'..'n','p'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'o': begin sost:=AUTO_N1;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_N1:

case stroka[j] of

'a'..'s','u'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

't': begin sost:=AUTO_N2;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_N2:

case stroka[j] of

'a'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=7; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_X:

case stroka[j] of

'a'..'n','p'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'o': begin sost:=AUTO_X1;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_X1:

case stroka[j] of

'a'..'q','s'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'r': begin sost:=AUTO_X2;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_X2:

case stroka[j] of

'a'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=9; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_O:

case stroka[j] of

'a'..'q','s'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'r': begin sost:=AUTO_O1;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_O1:

case stroka[j] of

'a'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=8; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_T:

case stroka[j] of

'a'..'q','s'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'r': begin sost:=AUTO_T1;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_T1:

case stroka[j] of

'a'..'t','v'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'u': begin sost:=AUTO_T2;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_T2:

case stroka[j] of

'a'..'d','f'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'e': begin sost:=AUTO_T3;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_T3:

case stroka[j] of

'a'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=10; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_F:

case stroka[j] of

'b'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'a': begin sost:=AUTO_F1;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_F1:

case stroka[j] of

'a'..'k','m'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'l': begin sost:=AUTO_F2;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_F2:

case stroka[j] of

'a'..'r','t'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

's': begin sost:=AUTO_F3;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_F3:

case stroka[j] of

'a'..'d','f'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

'e': begin sost:=AUTO_F4;str:=str+st; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_F4:

case stroka[j] of

'a'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=11; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_I:

case stroka[j] of

'a'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;

' ': begin sost:=AUTO_H;fl:=1;zn:=5; end;

else begin sost:=AUTO_E;str:=str+st; end;

end;

AUTO_E: begin

if stroka[j]<>' 'then

begin

sost:=AUTO_E;

str:=str+st;

end

else

begin

sost:=AUTO_H;

Memo2.Lines.Append(str);

str:='';

end;

end;

end;

if fl=1 then

begin

StringGrid1.Cells[0,ind]:=IntToStr(ind);

StringGrid1.Cells[1,ind]:=str;

case zn of

1: Begin StringGrid1.Cells[2,ind]:='Разделяюший знак'; p.Add(';'); end;

2: Begin StringGrid1.Cells[2,ind]:='Круглые открывающиеся скобки'; p.Add('('); end;

3: Begin StringGrid1.Cells[2,ind]:='Круглые закрывающиеся скобки'; p.Add(')'); end;

4: Begin StringGrid1.Cells[2,ind]:='Знак присваивания'; p.Add(':='); end;

5: Begin StringGrid1.Cells[2,ind]:='Идентификатор'; p.Add('a'); end;

6: Begin StringGrid1.Cells[2,ind]:='Оператор сравнения "and"'; p.Add('and'); end;

7: Begin StringGrid1.Cells[2,ind]:='Оператор сравнения "not"'; p.Add('not'); end;

8: Begin StringGrid1.Cells[2,ind]:='Оператор сравнения "or"'; p.Add('or'); end;

9: Begin StringGrid1.Cells[2,ind]:='Оператор сравнения "xor"'; p.Add('xor'); end;

10: Begin StringGrid1.Cells[2,ind]:='Логическая константа "true"'; p.Add('a'); end;

11: Begin StringGrid1.Cells[2,ind]:='Логическая константа "false"'; p.Add('a'); end;

end;

str:='';

ind:=ind+1;

fl:=0;

end;

end;

end;

Edit2.Text:=IntToStr(ind-1);

fl:=p.Count;

if fl=0 then begin ShowMessage('Ошибка! Таблица лексем пустая!!'); exit;end;

p.Add('@');

stek.Add('@');

stek.Add(p.Strings[0]);

p.Delete(0);

ind:=p.Count-1;

o1:=p.Strings[0];

fl:=stek.Count-1;

o2:=stek.Strings[fl];

repeat

Begin

o1:=p.Strings[0];

fl:=stek.Count-1;

repeat

if stek.Strings[fl]<>'E' then o2:=stek.Strings[fl]

else fl:=fl-1;

until(o2<>'E');

j:=1;i1:=0;

repeat

if term[j][2]=o1 then i1:=StrToInt(term[j][1])

else j:=j+1;

if i1>N1 then begin ShowMessage('Ошибка!');exit;end;

until(i1<>0);

j:=1;i2:=0;

repeat

if term[j][2]=o2 then i2:=StrToInt(term[j][1])

else j:=j+1;

if i2>N1 then begin ShowMessage('Ошибка!');exit;end;

until(i2<>0);

o3:=matrix[i2][i1];

if (o3='=')or(o3='<') then

begin stek.Add(o1);p.Delete(0); end

else

if o3='>' then

begin

if fl=stek.Count-1 then

begin

dl:=1;

i:=1;

pr:=o2;

M1:

o4:=stek.Strings[fl-i];

if o4<>'E' then begin

j:=1;i4:=0;

repeat

if term[j][2]=o4 then i4:=StrToInt(term[j][1])

else j:=j+1;

if i4>N1 then begin ShowMessage('Ошибка!');exit;end;

until(i4<>0);

o5:=matrix[i4][i2];

if o5='='then

begin

dl:=dl+1;pr:=o4+pr;i:=i+1;i2:=i4;

goto M1;

end

else begin goto M2; end;

end

else

begin

if stek.Strings[fl-i-1]<>'E' then

begin

j:=1;i4:=0;

repeat

if term[j][2]=stek.Strings[fl-i-1] then i4:=StrToInt(term[j][1])

else j:=j+1;

if i4>N1 then begin ShowMessage('Ошибка!');exit;end;

until(i4<>0);

o5:=matrix[i4][i2];

if o5='='then

begin

dl:=dl+1;pr:=o4+pr; i:=i+1;goto M1;

end

else begin goto M2; end;

end;

end;

end

else

begin

dl:=1;

i:=1;

pr:=o2;

o4:=stek.Strings[fl-i];

o6:=stek.Strings[fl+i];

if (o4='E')and(o6='E') then begin pr:='E'+o2+'E';dl:=3;end

else begin ShowMessage('Ошибка входной цепочки ('+o2+')!');exit; end;

end;

M2:

for j:=1 to dl do stek.Delete(stek.Count-1);

j:=1;zn:=0;

repeat

if prav_1[j][2]=pr then zn:=StrToInt(prav_1[j][1])

else j:=j+1;

if zn>N2 then begin ShowMessage('Ошибка!');exit;end;

until(zn<>0);

stek.Add('E');

d.Add(IntToStr(zn));

CepofV[u]:=zn;

u:=u+1;

end

else begin ShowMessage('Ошибка во входной цепочке!');exit; end;

fl:=stek.Count-1;

o1:=p.Strings[0];

o2:=stek.Strings[fl-1];

end;

until (o1='@')and(o2='@');

p.Clear;

str:='';

i4:=d.Count-1;

for i:=0 to i4 do str:=str+d.Strings[i]+' ';

memo3.Text:=str;

TreeView1.Items.Clear;

n:=d.Count;

with TreeView1 do

begin

Items.Add(Nil,'E');

vetv:=0;

j:=0;

for k:=n downto 1 do begin

m:=Items.Count;

if k<n then

for i:=m-1 downto 0 do if (Items[i].Text=notterm[CepofV[k]])and(Items[i].HasChildren=False) then begin vetv:=i;break; end;

for i:=1 to 4 do

if Canon[CepofV[k],i]<>'' then Items.AddChild(Items[vetv],Canon[CepofV[k],i]);

{vetv:=vetv+1;}

end;

FullExpand

end;

p.Destroy;

stek.Destroy;

d.Destroy;

end;

end.

Результаты работы:

Рис.1. Содержимое исходного файла.

Рис.2. Содержимое таблицы лексем.

Рис.3. Дерево вывода.

Вывод: в ходе работы были изучены основные понятия теории грамматик простого и операторного предшествования, ознакомление с алгоритмами синтаксического анализа (разбора) для некоторых классов КС-грамматик, а также была разработана программа, которая считывает данные с файла, создаёт таблицу лексем и выдаёт дерево решений.

Соседние файлы в папке лаба3