Лабораторная работа №2 / Отчет 2-2
.docУфимский Государственный Авиационный Технический Университет
Кафедра ТК
Отчет по лабораторной работе №2
Проектирование лексического анализатора
по курсу «Системное программное обеспечение»
Выполнил:
студент группы Т28-420
Принял: к.т.н.,
ст. преподаватель
Карамзина А.Г.
Уфа-2005
Цель работы: изучение основных понятий теории регулярных грамматик, ознакомление с назначением и принципами работы лексических анализаторов (сканеров), получение практических навыков построения сканера на примере заданного простейшего входного языка.
Задание: написать программу, которая выполняет лексический анализ входного текста в соответствии с заданием и порождает таблицу лексем с указанием их типов и значений. Текст на входном языке задается в виде символьного (текстового) файла.
Входной язык содержит логические выражения, разделенные символом ;(точка с запятой). Логические выражения состоят из идентификаторов, констант true и false, знака присваивания (:=), знаков операций or, xor, and, not и круглых скобок.
Описание КС - грамматики входного языка
G( {a,d,f,n,l,s,e,t,r,u,x,#,’:’,’=’, ‘;’, ‘(‘, ‘)’}, {A,H,I,J,N,B,K,O,P,Y,C,Q,D,R,Z,F,T,U,L,X,M,G,V,W, i, S}, P,S)
P:
A→ t H→Ar I→Hu J→Ie N→( | ) B→f K→Ba O→Kl P→Os Y→Pe C→ o Q→Cr |
D→x R→Do Z→Rr F→a T→Fn U→Td L→: X→L= M→; G→n V→Go W→Vt |
S→A#| H#| I#| J#| N#| B#| K#| O#|P#|Y#|C#|Q#|D#|R#|Z#|F#|T#|U#|L#|X#|M#|G#|V#|W#|i#
i→ii*|h*|AA*|HH*|II*|JJ*|BB*|KK*|OO*|PI*|CA*|DD*|RA*|FF*|TT*|GF*|VV*|PJ*|YJ*|QJ*|ZJ*|
UJ*|WJ*
i* - множество всех символов
h*- множество всех символов, крoме терминальных символов и 0..9
J*- множество всех символов, кроме #
A*- множество всех символов, кроме #, r
H*- множество всех символов, кроме #,u
I*- множество всех символов, кроме #,e
B*- множество всех символов, кроме #, a
K*- множество всех символов, кроме #, l
O*- множество всех символов, кроме #, s
D*- множество всех символов, кроме #, o
F*- множество всех символов, кроме #, n
T*- множество всех символов, кроме #, d
V*- множество всех символов, кроме #, t
Листинг программы:
Файл unit.cpp:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <stdio.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
sgrTable->Rows[0]->Add("Лексема");
sgrTable->Rows[0]->Add("Тип лексемы");
sgrTable->Rows[0]->Add("Цепочка ");
}
//---------------------------------------------------------------------------
String TForm1::Conclude(char X)
{
if(X=='M') return("Круглая скобка");
if(X=='N') return("Разделительный символ");
if(X=='J' || X=='Y') return("Логическая константа");
if(X=='Q' || X=='Z' || X=='U' || X=='W') return("Знак операции");
if(X=='X') return("Знак присваивания");
else return("Идентификатор");
}
String TForm1::Analiz(char *wInput)
{
int i = 0;
String Way= "h";
char State = 'h';
do {
switch (State) {
case 'h':
switch (wInput[i]) {
case 't' : State = 'A'; break;
case 'f' : State = 'B'; break;
case 'o' : State = 'C'; break;
case 'x' : State = 'D'; break;
case 'a' : State = 'F'; break;
case 'n' : State = 'G'; break;
case ':' : State = 'L'; break;
case '(' : State = 'M'; break;
case ')' : State = 'M'; break;
case ';' : State = 'N'; break;
case '0' : State = 'e'; break;
case '1' : State = 'e'; break;
case '2' : State = 'e'; break;
case '3' : State = 'e'; break;
case '4' : State = 'e'; break;
case '5' : State = 'e'; break;
case '6' : State = 'e'; break;
case '7' : State = 'e'; break;
case '8' : State = 'e'; break;
case '9' : State = 'e'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'A':
switch (wInput[i]) {
case 'r' : State = 'H'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'H':
switch (wInput[i]) {
case 'u' : State = 'I'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'I':
switch (wInput[i]) {
case 'e' : State = 'J'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'J':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'B':
switch (wInput[i]) {
case 'a' : State = 'K'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'K':
switch (wInput[i]) {
case 'l' : State = 'O'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'O':
switch (wInput[i]) {
case 's' : State = 'P'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'P':
switch (wInput[i]) {
case 'e' : State = 'Y'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'Y':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'C':
switch (wInput[i]) {
case 'r' : State = 'Q'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'Q':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'D':
switch (wInput[i]) {
case 'o' : State = 'R'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'R':
switch (wInput[i]) {
case 'r' : State = 'Z'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'Z':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'F':
switch (wInput[i]) {
case 'n' : State = 'T'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'T':
switch (wInput[i]) {
case 'd' : State = 'U'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'U':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'G':
switch (wInput[i]) {
case 'o' : State = 'V'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'V':
switch (wInput[i]) {
case 't' : State = 'W'; break;
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'W':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'L':
switch (wInput[i]) {
case '=' : State = 'X'; break;
default : State = 'e'; break;
}; Way=Way + State; break;
case 'X':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'e'; break;
}; Way=Way + State; break;
case 'M':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'e'; break;
}; Way=Way + State; break;
case 'N':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'e'; break;
}; Way=Way + State; break;
case 'i':
switch (wInput[i]) {
case '\0' : State = 'S'; break;
default : State = 'i'; break;
}; Way=Way + State; break;
case 'e': break;
}
}while (wInput[i++]!='\0');
return Way;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
FILE *input;
char *temp;
String Way;
int i=1;
temp = new char[20];
if(OpenDialog1->Execute())
{
input = fopen(OpenDialog1->FileName.c_str(),"r");
while (!feof(input))
{
fscanf(input,"%s",temp);
Way = Analiz(temp);
if( Way[strlen(Way.c_str())]!='e' )
{
sgrTable->Rows[i]->Add(temp);
sgrTable->Rows[i]->Add(Conclude(Way[strlen(Way.c_str())-1]));
sgrTable->Rows[i]->Add(Way);
i++;
}
}
sgrTable->RowCount = i;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
Файл input.txt:
( X := true ) and ( Y := false ) ;
( X xor Y ) or ( Y not X ) ;
z := 10 ;
l := 20 ;
Результаты работы:
Вывод: В результате проделанной работы были изучены основные понятия теории регулярных грамматик, назначения и принципы работы лексических анализаторов (сканеров). Были получены практические навыки построения сканера на примере заданного простейшего входного языка.