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

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

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

Кафедра ТК

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

“ Проектирование лексического анализатора ”

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

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

Ситдикова О.

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

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

Уфа 2007

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

Вариант 2: входной язык содержит логические выражения, разделенные символом ; (точка с запятой). Логические выражения состоят из идентификаторов, констант true и false, знака присваивания (:=), знаков операций or, xor, and, not и круглых скобок.

КС-грамматика входного языка в форме Бэкуса-Наура:

^-знак пробела

G({0..9, a..z, ;, (, ), :, =,^}, {R,ZZ,OO,Q,Q1,I,A,A1,A2,N,N1,N2,X,X1,X2,O,O1,T,T1,T2,T3,F,F1,F2,F3,F4},P,S)

P:

H®H^

R®H;

ZZ®H)

OO®H(

Q®H:

Q1®Q=

I®Hb..He|Hg..Hm|Hp..Hs|Hu..Hw|Hy|Hz|Aa..Am|Ao..Az|A0..A9|A1a..A1c|A1e..A1z|A10..A19|A2a..A2z|A20..A29|Na..Nn|Np..Nz|N0..N9|N1a..N1s|N1u..N1z|N10..N19|N2a.. N2z|N20..N29|Xa..Xn|Xp..Xz|X0..X9|X1a..X1q|X1s..X1z|X10..X19|X2a…X2z|X20..X29| Oa..Oq|Os..Oz|O0..O9|O1a..O1z|O10..O19|Ta..Tq|Ts..Tz|T0..T9|T1a..T1t|T1v..T1z|T10..T19|T2a..T2d|T2f..T2z|T20..T29|T3a..T3z|T30..T39|Fb..Fz|F0..F9|F1a..F1k|F1m..F1z|F10..F19|F2a..F2r|F2t..F2z|F20..F29|F3a..F3d|F3f..F3z|F30..F39|F4a..F4z|F40..F49|Ia..Iz||I0..I9

A®Ha

A1®An

A2®A1d

N®Hn

N1®No

N2®N1t

X®Hx

X1®Xo

X2®X1r

O®Ho

O1®Or

T®Ht

T1®Tr

T2®T1u

T3®T2e

F®Hf

F1®Fa

F2®F1l

F3®F2s

F4®F3e

S®R^|ZZ^|OO^|Q1^|A2^|N2^|X2^|O1^|T3^|I^|F4^

Фрагмент графа переходов КА для разделяющего знака, знака пробела, круглых открывающихся и закрывающихся скобок, знака присваивания, представлен на рис.1.

Рис.1. Фрагмент графа переходов КА разделяющего знака, скобок и знака присваивания.

Фрагмент графа переходов КА для идентификатора, операторов сравнения “xor”, “not”, “and”, “or” представлен на рис.2.

Рис.2. Фрагмент графа переходов КА идентификатора и операторов сравнения “xor”, “not”, “and”, “or”.

Фрагмент графа переходов КА для идентификатора и логических констант "false" и "true" представлен на рис.3.

Рис.3. Фрагмент графа переходов КА идентификатора и логических констант "false" и "true".

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

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;

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:='';

StringGrid1.Cells[0,0]:='№ п/п';

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

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

end;

procedure TForm1.Button3Click(Sender: TObject);

var

ind,pos,dl,i,j,i1,fl,zn:integer;

st,str,stroka:string;

sost:TAutoState;

begin

for i:=0 to 2 do

for i1:=1 to 999 do

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

i1:=Memo1.Lines.Count;

ind:=1;

pos:=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: StringGrid1.Cells[2,ind]:='Разделяюший знак';

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

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

4: StringGrid1.Cells[2,ind]:='Знак присваивания';

5: StringGrid1.Cells[2,ind]:='Идентификатор';

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

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

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

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

10: StringGrid1.Cells[2,ind]:='Логическая константа "true"';

11: StringGrid1.Cells[2,ind]:='Логическая константа "false"';

end;

str:='';

ind:=ind+1;

fl:=0;

end;

end;

end;

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

end; end.

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

Рис.4. Модуль лексического анализатора (содержимое исходного файла).

Рис.5. Модуль лексического анализатора (таблица лексем).

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