Рефераты
 

Разработка сканера

Разработка сканера

24

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

Тульский государственный университет

Кафедра АТМ

Курсовая работа

по курсу

«Теория вычислительных процессов»

Тула - 2003

Содержание:

Введение……………………………………………………………………3

1.Постановка задачи….……………………………………………………4

1.1. Задание…………………………………………..……………………..4

2.1. Глобальные переменные и необходимые подпрограммы…….….…4

3.1. Диаграмма состояний………………………………..………………..5

2.Текст программы………………………………………………………...7

3. Инструкция пользователю……………………………………………..14

4. Тестовый пример……………………………………………………….14

Вывод………………………………………………………………............14

Список использованных источников……………………………………15

Введение:

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

1. Постановка задачи:

1.1. Задание:

В данной контрольно-курсовой работе необходимо выполнить лексический анализ текста программы на некотором условном языке программирования. Таким образом требуется разработать сканер, который считывает литеры первоначальной, исходной программы и строит слова, или иначе символы, исходной программы (идентификаторы, служебные слова, одно- или двулитерные разделители).

Символами в языке, для которого необходимо разработать сканер являются:

1.Служебные слова: Цикл …;

Пока … Делать;

Продолжить;

Вещественный;

Двойной.

2.Операторы: +, -, *, /, (, ), =, <>, <, >.

3.Идентификаторы: ( рус.буква | _ ), ( рус.буква | _ | цифра )*.

4.Логические операции: И, ИЛИ, НЕ.

5.Комментарий: {*…*}, {{ -до конца строки.

1.2. Глобальные переменные и необходимые подпрограммы:

Для работы сканера требуются следующие переменные и подпрограммы:

1. char c, где c - глобальная переменная, значением которой всегда будет сканируемая литера исходной программы.

2. int Class, где Class содержит целое число, которое характеризует класс литеры, находящейся в с. Будем считать, что если Class = 1 то это цифра, Class = 2 - буква, Class = 3 - литера `{`, Class = 4 - оператор, Class = 5 - недопустимое выражение.

3. char s[20] - массив который будет содержать цепочку литер, составляющих символ.

4. void Getchar(char, int&) - функция, задача которой состоит в том, чтобы выбрать следующую литеру исходной программы и поместить ее в с, а класс литера в Class.

5. int LookUp(char* ) - функция которая осуществляет поиск символа, набранного в s, по таблице служебных слов и логических операций. Если символ является служебным словом, то LookUp возвратит 1, если символ это логическая операция то LookUp вернет 2, в противном случае функция вернет 3.

1.3. Диаграмма состояний:

Метка D используется вместо любой из меток 0, 1, 2, … , 9, т. е. D представляет класс цифр. Это делается для упрощения диаграммы. Аналогично метка L представляет класс буквы А, Б, … , Я, а, б, … , я, а DELIM представляет класс разделителей (операторов). Литера { обрабатывается особым образом.

Некоторые дуги не помечены. Эти дуги будут выбраны, если сканируемая литера не совпадает ни с одной из литер, которыми помечены другие дуги.

Добавим семантику в диаграмму состояний. Введем команду Gc, сокращенно обозначив таки образом функцию void Getchar(char, int&). Под первой дугой, ведущей к состоянию S, записана команда init, которая указывает на необходимость выполнения подготовительных действий и начальных установок, а именно проверка содержимого с, и если там пробел, то повторно вызывается void Getchar(char, int&) до тех пор, пока в с не окажется литера, отличная от пробела если команда init определит конец файла то программа будет завершена. Команда ADD означает, что литера с добавляется к строке s. В состоянии Print int печатается определенное программой целое число, в Print sl - служебное слово, в Print log - логическая операция, в Print id - идентификатор, в Print com - комментарий, в Print еrror - недопустимое выражение. Из любого состояния Print дуги ведут в состояние S до тех пор, пока init не определит конец файла.

Рисунок 1. Диаграмма состояний с семантическими процедурами.

2. Текст программы:

#include <fstream.h>

#include <stdlib.h>

#include <process.h>

#include <stdio.h>

#include <conio.h>

#include <ctype.h>

#include <string.h>

int Prov_itn(); //Проверка на ввод целого положительного числа

int LookUp (char*); //Поиск символа по таблице служебных слов

void Getchar(char,int&);//Определяет класс литеры

void main()

{

char s[20],f_in[10]="in.txt",f_out[10],c,k,a;

int Class,Quit=0,Q=0,x,i,n,j=0;

char _ []="-----------------------",

_cel[]=".Целое :",

_op []=".Оператор :",

_kom[]=".Комментарий :",

_id []=".Идентификатор :",

_sl []=".Служебное слово :",

_log[]=".Логическая операция :",

_err[]=".Недопустимое выражение:",

__ []="-----------------------";

clrscr();

fstream inFile,outFile;

cout<<"\t----------------------¬\n";

cout<<"\t¦ 1.Ввод с клавиатуры.¦\n";

cout<<"\t¦ 2.Ввод с файла. ¦\n";

cout<<"\tL----------------------\n";

do

cout<<"\t Ваш выбор:";

n=Prov_itn();

if(n<1 while(1);

if(n==1)

{

inFile.open(f_in,ios::trunc |ios::in | ios::out);

cout<<"\nВводите текст (в конце текста введите !):\n";

for(;(a=getchar())!='!';)

inFile<<a;

inFile.close();

inFile.open(f_in,ios::in | ios::out);

cout<<"\nВведите имя файла вывода: ";

cin >>f_out;

outFile.open(f_out,ios::trunc |ios::in | ios::out);

if(!outFile)

{

cout<<"Ошибка окрытия файла: "<<f_out;

}

}

if(n==2)

{

cout<<"Введите имя файла ввода: ";

cin >>f_in;

inFile.open(f_in,ios::in | ios::out );

if(!inFile)

{

cout<<"\nОшибка открытия файла: "<<f_in;

}

if(inFile.peek()!=EOF)

{

cout<<"Содержимое файла:\n\n";

while(inFile.peek()!=EOF)

{

inFile.get(c);

cout<<c;

}

}

else

{

cout<<"Файл пуст!";

getch();

exit(0);

}

inFile.close();

inFile.open(f_in,ios::in | ios::out );

cout<<"\n\nВведите имя файла вывода: ";

cin >>f_out;

outFile.open(f_out,ios::trunc |ios::in | ios::out);

if(!outFile)

{

cout<<"\nОшибка окрытия файла: "<<f_out;

}

}

//Проверка содержимого файла

if(inFile.peek()!=EOF)

{

Quit=1;

inFile.get(c);

Getchar(c,Class);

outFile<<_<<"\n";

}

else

Quit=0;

while(Quit==1)

{

j++;

while(c==' '||c=='\n')

{

if(inFile.peek()==EOF)

{

Quit=0;

break;

}

inFile.get(c);

Getchar(c,Class);

}

switch(Class)

{

case 1: //Считываемый символ цифра

{

i=0;

do

{

s[i]=c;

i++;

if(inFile.peek()==EOF)

{

Quit=0;

break;

}

inFile.get(c);

Getchar(c,Class);

}while(Class==1);

s[i]='\0';

outFile<<j<<_cel<<s<<"\n";

}

break;

case 2: //Считываемый символ буква

{

i=0;

do

{

s[i]=c;

i++;

if(inFile.peek()==EOF)

{

Quit=0;

break;

}

inFile.get(c);

Getchar(c,Class);

}while(Class<=2);

s[i]='\0';

x=LookUp(s);

if(x==1)

outFile<<j<<_sl<<s<<"\n";

if(x==2)

outFile<<j<<_log<<s<<"\n";

if(x==3)

outFile<<j<<_id<<s<<"\n";

}

break;

case 3: //Считываемый символ начало комментария {

{

i=0;

s[i]=c;

i++;

if(inFile.peek()==EOF)

{

Quit=0;

outFile<<j<<_err<<s<<"\n";

break;

}

inFile.get(c);

Q=0;

if(c=='*')

{

s[i]=c;

i++;

do

{

if(inFile.peek()==EOF)

{

Quit=0;

break;

}

inFile.get(c);

if(c=='*')

{

if(inFile.peek()==EOF)

{

Quit=0;

break;

}

inFile.get(k);

if(k!='}') continue;

s[i]=c;

i++;

s[i]=c=k;

i++;

Q=1;

if(inFile.peek()==EOF)

{

Quit=0;

break;

}

inFile.get(c);

}

}while(Q!=1);

s[i]='\0';

Getchar(c,Class);

outFile<<j<<_kom<<s<<"\n";

}

else

{

if(c=='{')

{

s[i]=c;

i++;

do

{

if(inFile.peek()==EOF)

{

Quit=0;

break;

}

inFile.get(c);

}while(c!='\n');

inFile.get(c);

s[i]='\0';

Getchar(c,Class);

outFile<<j<<_kom<<s<<"\n";

}

else

{ Getchar(c,Class);

outFile<<j<<_err<<s<<"\n";

}

}

}break;

case 4: //Считываемый символ оператор

{

i=0;

s[i]=c;

if(s[i]=='<' && inFile.peek()!=EOF)

{

inFile.get(c);

Getchar(c,Class);

if(c=='>')

{

i++;

s[i]=c;

if(inFile.peek()!=EOF)

{ inFile.get(c);

Getchar(c,Class);

}

else

Quit=0;

}}

else

{

if(inFile.peek()!=EOF)

{ inFile.get(c);

Getchar(c,Class);

}

else

Quit=0;

}

i++;

s[i]='\0';

outFile<<j<<_op<<s<<"\n";

}break;

case 5:

{

i=0;

do

{

s[i]=c;

i++;

if(inFile.peek()!=EOF)

{ inFile.get(c);

Getchar(c,Class);

}

else

{

Quit=0;break;

}

}while(Class==5);

s[i]='\0';

outFile<<j<<_err<<s<<"\n";

}break;

}

if(Quit==0)

outFile<<__<<"\n";

}

cout<<"Содержимое файла:\n\n";

outFile.close();

outFile.open(f_out,ios::in | ios::out );

{

while(outFile.peek()!=EOF)

{

outFile.get(c);

cout<<c;

}

}

inFile.close();

outFile.close();

getch();

}

//Определяет класс литеры

void Getchar(char cc,int& Class1)

{

int i;

char ca[]={'+','-','*','/','(',')','=','<>','<','>'};

char cb[]={'А','Б','В','Г','Д','Е','Ж','З','И','Й','К',

'Л','М','Н','О','П','Р','С','Т','У','Ф','Х',

'Ц','Ч', 'Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я','а',

'б','в','г','д','е','ж','з','и','й','к','л',

'м','н','о','п','р','с','т','у','ф','х','ц',

'ч','ш','щ','ъ','ы','ь','э','ю','я','_'};

char cd[]={'1','2','3','4','5','6','7','8','9','0'};

for(i=0;i<10;i++)

if(cc==cd[i])

{

Class1=1;

return;

}

if(cc=='{')

{

Class1=3;

return;

}

for(i=0;i<10;i++)

if(cc==ca[i])

{

Class1=4;

return;

}

for(i=0;i<65;i++)

if(cc==cb[i])

{

Class1=2;

return;

}

if(cc==' ' || cc=='\n')

Class1=10;

else Class1=5;

}

//Поиск символа по таблице служебных слов

int LookUp(char* s)

{

int i;

char *log[]={"И","ИЛИ","НЕ"};

char *sl []={"Цикл","Пока","Делать","Продолжить","Вещественный","Двойной"};

for(i=0;i<6;i++)

{

if(strcmp(s,sl[i])==0)

return 1;

}

for(i=0;i<3;i++)

{

if(strcmp(s,log[i])==0)

return 2;

}

return 3;

}

//Проверка на ввод целого положительного числа

int Prov_itn()

{

char k1[5],k2[5];

int nn;

cin>>k1;

nn=atoi(k1);

itoa(nn,k2,10);

if (strlen(k1)!=strlen(k2))

return 0;

return nn;

}

3. Инструкция пользователю:

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

4. Тестовый пример:

+---------------------+

¦ 1.Ввод с клавиатуры.¦

¦ 2.Ввод с файла. ¦

+---------------------+

Ваш выбор:2

Введите имя файла ввода: in.txt

Содержимое файла:

Пока {*(ldfjvkdfvfjkb*}

Вещественный<> +=

Введите имя файла вывода: put.txt

Содержимое файла:

-----------------------

1.Служебное слово :Пока

2.Комментарий :{**}

3.Служебное слово :Вещественный

4.Оператор :<>

5.Оператор :+

6.Оператор :=

-----------------------

Вывод:

В настоящей работе была показана работа сканера, при которой выполняется полный лексический анализ исходной программы.

Список использованных источников:

1. Грис Д. Конструирование компиляторов для цифровых вычислительных машин. М.: Мир, 1975;

2. Хантер Р. Проектирование и конструирование компиляторов. М.: Финансы и статистика, 1984.

3. Касьянов В.Н., Поттосин И.В. Методы построения трансляторов. Новосибирск: Наука, 1986.


© 2010 BANKS OF РЕФЕРАТ