Разработка конвертора на языке Си для перевода программ на языке Паскаль в текст программы на языке Си

Создание программы для перевода кодов с языка Pascal на язык Си. Обработка программ операторами case, assign, rewrite и write. Способы объявления файла, комментария, переменных, логических и арифметических выражений. Виды синтаксических анализаторов.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 03.07.2011
Размер файла 461,0 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Министерство образования и науки Российской Федерации

Федеральное агентство по образованию

Государственное образовательное учреждение высшего

профессионального образования

"Северо-Кавказский Государственный Технический Университет"

КУРСОВОЙ ПРОЕКТ

ПО ДИСЦИПЛИНЕ "Программирование на языке высокого уровня"

НА ТЕМУ: "Разработка конвертора на языке Си для перевода программ на языке Паскаль в текст программы на языке Си"

Выполнил студент II курса

специальности 230102.65

"Автоматизированные системы

обработки информации и

управления"

Е.П.Гладкий

Ставрополь

2011

Аннотация

В данном курсовом проекте описана программа, написанная на языке Visual C++.

Необходимо составить программу, которая переводит код программы на языке Pascal в код программы на языке Си. Программа перерабатывает исходный код на языке Pascal, переводит в язык Си и записывает в новый файл.

Разработанная программа позволяет пользователю переводить программы с несколькими операторами: case, assign, rewrite, write, объявление файла, комментарии, объявление переменных, оператора присваивания, а так же логическое и арифметическое выражения тип данных real и integer.

Оглавление

Аннотация

Введение

1. Техническое задание

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

3. Внешняя спецификация программы

4. Описание алгоритма

5. Структура программы

6. Листинг кода

7. Результаты тестирования программы

Заключение

Список литературы

Введение

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

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

1. Техническое задание

Программа предназначена для трансляции кода на языке Pascal в код на языке программирования C.

Программа переводит текст программы, сохраненный в файле filename1 с расширением .PAS. Путь на входной файл filename1 и путь на выходной файл filename2 с расширением .с вводятся с клавиатуры. В коде входного файла нужно использовать операторы: case, assign, rewrite,write, file, комментарии, Begin, end и тип данных: real на язык C, после чего результат программы записывается в выходной файл.

В случае ошибочной обработки оператора, программа добавляет код в выходной файл filename2 <ошибка!>. Программа не прерывается, если найден ошибочный оператор.

Для создания программы использовался Visual Studio 2010, создание тестовой программы используем среду Turbo Pascal 7.0.

Программа создается на языке C в программном пакете Visual Studio 2010 Express Edition, на операционной системе Windows XP SP3.

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

Исходный код находится в файле filename1.pas с кодом на языке Pascal:

filename1 имя входного файла, содержащего исходный текст программы на языке Pascal, в котором используются операторы case, assign, rewrite,write, file, комментарии, Begin, end и тип данных: real

После работы программы программа создает файл filename2.c, а так же счетчики операторов до транслирования и после, а также количество ошибочных операторов:

filename2 имя выходного файла, содержащий конвертированный текст программы на язык C;

koper1 количество операторов в исходной программе;

koper2 количество операторов в конвертированной программе;

ker количество ошибочных операторов в полученной программе;

Для более удобного понимания целей нашей программы составим таблицу 1, в которой сравним синтаксис по операторам на языке C и на языке Pascal по нашему варианту.

Таблица 1 - Синтаксис операторов на языке C и на языке Pascal

Синтаксис оператора на языке Pascal

Синтаксис оператора на языке C

1.Оператор присваивания

v1:=ae1;

v1=ae1;

2. Оператор case:

case k of

1: Begin

End;

2:Begin

End;

switch(k){

case 1:

{

break;

case 2:

{

break;

3. Оператор assign, rewrite, write

assign(fl,'c:tuc\tuc.txt');

rewrite(fl);

write(fl,'bla');

fl = fopen("c:tuc\tuc.txt","w");

fcreate(fl);

fprintf(fl,"bla");

4.Операторные скобки

Begin…End

{…}

5.Объявление файла

fl:file of integer;

FILE *fl;

6.Комментарии:

{…}

/*…*/

Арифметическое выражение Ае3

Логическое выражение Le2:

3. Внешняя спецификация программы

Исходный текст программы, написанный на языке Pascal, filename1.pas вводится после запроса программы:

Имя входного файла:<Имя входного файла>

После работы программы, ввести имя файла:filename2, в который записывается код после трансляции:

Имя выходного файла:<Имя выходного файла>

После работы программы, выводится на экран количество операторов исходных, успешно обработанных и которые оказались ошибочные(koper1, koper2, ker).

Количество операторов в исходной программе:<число>

Количество в полученной программе:<число>

Количество ошибочных операторов в полученной программе:<число>

Результат хранится в файле:<имя выходного файла>

Если путь к указанному файлу filename1 не верен написать:

Ошибка открытия файла!

4. Описание алгоритма

Первая фаза транслирования исходного кода, это лексический анализ. Работа лексического анализатора состоит в том, чтобы сгруппировать определенные терминальные символы в единые синтаксические объекты, называемые лексемами. Какие объекты считать лексемами зависит от определения языка программирования, в нашей программе это массив ключевых слов.

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

Цепочка лексем образует вход синтаксического анализатора, исследующего только первые компоненты лексем - их типы.

Синтаксический анализ, или разбор - это процесс, в котором исследуется цепочка лексем и устанавливается, удовлетворяет ли она структурными условиями, явно сформулированным в определении синтаксиса языка.

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

Выходом анализатора служит дерево, которое представляет синтаксическую структуру, присущую исходной программе.(Рисунок 1)

Рисунок 1 - Дерево синтаксической структуры.

На рисунке 1 используются только те функции которые позволяет транслировать наша программа, а именно: комментарии (Comment_is_find, Comment_is_finish), case (Process_case), write, rewrite, assign (Process_begin, Process_write, Process_rewrite, Process_assign), обработка переменной (Process_Var, Process_Vardescr), проверка на наличие ошибочных операторов (Errore_Program).

5. Структура программы

Назначение подпрограмм:

errore_program - Подпрограмма обработки ошибок, включает в себя функции определения места ошибки, а так же выделение полной ошибочной конструкции. Заносит данные о количестве ошибок в специальную переменную.

comment_is_find - Проверяет строку на наличие комментария, и обрабатывает его если это так.

ReadingWord - Подпрограмма анализа текста на наличие токенов. Определяет тип токена и делает его проверку. Возвращает позицию начала, количество символов в токене, а так же его тип. Заодно пропускает пробелы.

process_begin - Подпрограмма обработки блока Begin…End, запускается после того как во входном файле встречено слово begin и заменяет их на {…}

Process_Var - Подпрограмма обработки блока переменных - var. Проверяет конструкции на их тип: обычные переменные или метка. После чего передает поток управления в ту или иную функцию.

Comment_is_finish - Подпрограмма обработки окончания комментария.

ReadingWordS - Подпрограмма посимвольно просматривает файл и определяет к чему можно отнести данный символ.

process_rewrite - Подпрограмма обработки ключевого слова rewrite.

process_assign - Подпрограмма обработки ключевого слова assign.

process_write - Подпрограмма обработки ключевого слова write

Описание констант, переменных и функций программы.

Константы

Array_Key_Word - константа, которая равна количеству слов в массиве. В нашей программе оно равно 16. Это такие слова как: "begin", "end", "var", "real", "boolean", "false", "true", "type, "and", "or", "case", "assign", "rewrite"ю

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

Функции и процедуры

void IncDt() - функция увеличение отступа.

void DecDt() - функция уменьшения отступа.

void copychar() - копирует слово из входного файла в выходной без изменений.

int fae() - вспомогательная подфункция обработки арифметического выражения.

int ae() - функция обработки арифметического выражения.

Функция возвращает один из следующих кодов

// идентификаторы возможных типов слов

Word_errore 0 // Идентификатор ошибочного оператора

Word_space 1 // Идентификатор символа пробела

Word_string 2 // Идентификатор строки

Word_numb 3 // Идентификатор числа

Word_char 4 // Любые символы разделители, такие как \n \t и тд

Таблица идентификаций:

Ключевое слово

Номер

KeyS_begin

1

KeyS_end

2

KeyS_var

3

KeyS_real

4

KeyS_boolean

5

KeyS_false

6

KeyS_true

7

KeyS_array

8

KeyS_type

9

KeyS_and

10

KeyS_or

11

KeyS_case

12

KeyS_assign

13

KeyS_read

14

KeyS_write

15

KeyS_rewrite

16

6. Листинг кода

// Gladky.cpp: определяет точку входа для консольного приложения.

//

#include <stdafx.h>

#include <conio.h>

#include <stdio.h>

#include <string.h>

#include <locale.h>

FILE *filename1, *filename2;

const int allbuf = 10000;//весь исходный текст представляется одной большой символьной строкой, а не массивом символов, это максимальная длина

const int Array_Key_Word = 18;

char * KWs[Array_Key_Word] =

{

"begin", "end", "var", "real",

"boolean", "false", "true", "array",

"while", "do", "type", "and",

"or", "case", "assign", "read",

"write", "rewrite"

};// это массив ключевых слов, которые обрабатываются данной программой

//ключевый слова

//каждому ключевому слову присвоен номер, это будет дальше испоьзоваться в проге

#define KeyS_begin 1

#define KeyS_end 2

#define KeyS_var 3

#define KeyS_real 4

#define KeyS_boolean 5

#define KeyS_false 6

#define KeyS_true 7

#define KeyS_array 8

#define KeyS_while 9

#define KeyS_do 10

#define KeyS_type 11

#define KeyS_and 12

#define KeyS_or 13

#define KeyS_case 14

#define KeyS_assign 15

#define KeyS_read 16

#define KeyS_write 17

#define KeyS_rewrite 18

//типы

//тоже присвоены номера

#define t_Int 1 //целый

#define t_Real 2 //дробный

#define t_Bool 3 //логический

#define t_Array 4 //массив

#define t_File 5

const int cuservars = 6;

int uvars;

//тип "слова"

#define Word_errore 0 //ошибка

#define Word_space 1 //пробелы

#define Word_string 2 //строка

#define Word_numb 3 //число

#define Word_char 4 //символ (разделитель, ...)

//собственно это наши входные и выходные большие строки, в эти большие

//строки записываются также символы конца строки '\n', что и используется в дальнейшем для формирования выходного теста построчно

char instr[allbuf],

outstr[allbuf];

int inlen,outlen,inpos;//текущие позиции (строки входные, выходные, позиция в строке входной)

int koper1,koper2,ker;//эти переменные считают количество операторов во входном, выходном файле и кол-во ошибок

int wlen; //длина "слова"

int wtype; //тип "слова"

int wnumf; //0 - целое число, 1 - дробное

int dt; //размер отступа (от начала строки)

typedef struct var{ //элемент списка переменных

char s[64]; //идент-р переменной

int tp; //тип переменной

var * next;

};

typedef struct types{ //элемент списка типов

char s[64]; //идент-р переменной

int tid;

types * next;

};

var *vars, *lvars; //списки переменных

//(глобальных и локальных)

types * typeslist;

// прототипы функций

int fle();

// Дальнейшие функции описывают работу с динамической памятью,

// В которой создается список с переменными, их типами и названием

// Используя этот список, затем идет построение раздела объявления переменных

// в c++

//добавить переменную в список

// где gl - тип переменной, глобальная или локальная.

int addvar(int gl){

var *np, *p;

if (gl) p = vars; else p = lvars;

// int memcmp(const void *buf1, const void *buf2, size_t count);

// Функция memcmp() сравнивает первые count символов массивов, адресуемых параметрами buf1 и buf2.

// buf1 меньше buf2 = меньше нуля

// buf1 равен buf2 = 0

// buf1 больше buf2 = больше нуля

while (p) {

if (strlen(p->s)==wlen&&

!memcmp(p->s,&instr[inpos],wlen)) return 0;

p = p->next;

}

np = new var;

// void *memcpy(void *to, const void *from, size_t count);

// Функция memcpy() копирует count символов из массива,

// адресуемого параметром from, в массив, адресуемый параметром to.

// Если заданные массивы перекрываются, поведение функции memcopy() не определено.

memcpy(np->s,&instr[inpos],wlen);

// после имени переменной мы записываем 0 (метка

// что бы потом читать имя переменной до этого символа)

np->s[wlen]=0;

// тип переменной задаем как -1 (метка, что бы потом переопределить)

np->tp = -1;

// Если глобальная переменная, то добавляем этот элемент в начало

// (т.е. получается стек из переменных) списка глобальных переменных

// иначе в начало списка локальных

if (gl) {

np->next = vars;

vars = np;

} else {

np->next = lvars;

lvars = np;

}

return 1;

}

int addnewtype()

{

types *head=typeslist, *ntype;

while (head) {

if (strlen(head->s)==wlen&&

!memcmp(head->s,&instr[inpos],wlen)) return 0;

head = head->next;

}

ntype = new types;

memcpy(ntype->s,&instr[inpos],wlen);

ntype->s[wlen]=0;

ntype->tid = uvars;

uvars++;

ntype->next = typeslist;

typeslist = ntype;

return 1;

}

//установка типа переменной

// если gl - идентификатор глобальности = 1, то это глобальная переменная

// иначе локальная

// есть четыре типа переменных (описаны выше)

// конструкцию while можно расшифровать так:

// пока указатель на структуру p существует выполнять:

// если тип переменной -1 то присвоить ей заданный тип

// и далее шаг вперед

void settype(int gl, int type){

var *p;

if (gl) p = vars; else p = lvars;

while (p) {

if (p->tp==-1) p->tp = type;

p = p->next;

}

}

// получение типа переменной

// при этом тип уже должен был заранее задан

int vartype(){

var * p;

// обработка локальных переменных

p = lvars;

while (p) {

if (strlen(p->s)==wlen&& // если слово во входном тексте равно названию переменной (в списке),

!memcmp(p->s,&instr[inpos],wlen)) return p->tp; // то вернуть тип переменной

p = p->next;

}

// обработка глобальных переменных

p = vars;

while (p) {

if (strlen(p->s)==wlen&&

!memcmp(p->s,&instr[inpos],wlen)) return p->tp;

p = p->next;

}

return 0;

}

char* usertype()

{

types * p;

// обработка локальных переменных

p = typeslist;

while (p) {

if (strlen(p->s)==wlen&& // если слово во входном тексте равно названию переменной (в списке),

!memcmp(p->s,&instr[inpos],wlen)) return p->s; // то вернуть тип переменной

p = p->next;

}

return "0";

}

// освобождение списка переменных

// просто удаление обоих списков

// как для локальных переменных, так и для глобальных

void freevars(int gl){

var *p, *pp;

p = lvars;

while (p) {

pp = p;

p = p->next;

delete pp;

}

lvars = NULL;

if (gl) {

p = vars;

while (p) {

pp = p;

p = p->next;

delete pp;

}

vars = NULL;

}

}

// Одна из главных функций получение слова, здесь посимвольно анализируется текст

// Вкратце описание выглядит так

// прога анализирует текст посимвольно и каждый раз определяет тип символа

// (число, буква, пробел ит.д.),

// когда удается ясно определить значение этого символа (цифра, переменная и т.д.)

// или последовательности символов( перемнная, ключевое слово и т.д.)

// выполнение функции прерывается она возвращает тип этого слова

//Функция возвращает один из следующих кодов

////тип "слова"

// Word_errore 0 //ошибка

// Word_space 1 //пробелы

// Word_string 2 //строка

// w_numb 3 //число

// Word_char 4 //символ (разделитель, ...)

// чтение слова

int ReadingWord()

{

int st = 0;

char c; // символ который сравнивается

wlen = 0;// длина анализуруемого слова

while (wlen+inpos<inlen ){

c = instr[inpos+wlen];

switch (st){ // получение символа и дальнейший выбор направления обработки

case 0:

if (c==' ' || c=='\t' || c=='\n') st = 1;

else

if ((c>='A' && c<='Z')||(c>='a' && c<='z')) st = 2;

else

if (c>='0' && c<='9') st = 3;

else

if (

c=='.' || c<=',' || c >=':' || c<=';' ||

c=='+' || c<='-' || c>='*' || c<='/' ||

c=='\''

)

{ wlen = 1; return wtype = Word_char; }//возвращает, что это символ

else { wlen = 0; return wtype = Word_errore; }

break;

case 1:

if (c==' ' || c=='\t' || c=='\n') wlen++;

else return wtype = Word_space; ///возвращает, что это символ пробел

break;

case 2:

if (

(c>='A' && c<='Z') ||

(c>='a' && c<='z') ||

(c>='0' && c<='9') ||

c=='_'

) wlen++;

else return wtype = Word_string;

break;

case 3:

if (c>='0' && c<='9') wlen++; else

if (c=='.'&& instr[inpos+wlen+1]!='.') { // говорит, что есть точка в числе, т.е оно дробное

wlen++;

st = 5;

}

else{

wnumf = 0;

return wtype = w_numb;//возвращает, что это число

}

break;

case 5:

if (c>='0' && c<='9') wlen++; else {

wnumf = 1;

return wtype = w_numb;//возвращает, что это число (дробную часть)

}

}

}

wlen = 0;

return 0;

}

//запись строки в выходной буфер

void put_str(char * s){

int l = strlen(s);

memcpy(&outstr[outlen],s,l);

outlen += l;

}

int scmp(char * m, char * s, int n){

int l = strlen(s);

if (n>l) l = n;

/*int memicmp (buf1, buf2, cnt);

char *buf1; первый буфер

char *buf2; второй буфер

unsigned cnt; количество символов

Функция memicmp лексикографически сравнивает первые cnt

байтов из buf1 и buf2 вне зависимости от типа регистра, т.е. бук-

вы верхнего и нижнего регистров считаются эквивалентными. Функция

memicmp возвращает значение, указывающее соотношение buf1 и buf2,

а именно:

Величина Значение

меньше 0 buf1 меньше, чем buf2

0 buf1 идентично buf2

больше 0 buf1 больше, чем buf2*/

return memicmp(m,s,l);

}

//запись символа в выходной буфер

void put_char(char c){

outstr[outlen] = c;

outlen++;

}

void copychar(){

memcpy(&outstr[outlen],&instr[inpos],wlen);

inpos += wlen;

outlen += wlen;

}

int wequ(char * s){

return (!scmp(&instr[inpos],s,wlen));

}

//пропускает пробелы

void wskip(){

inpos += wlen;

}

void wstr(char * s){

// char *strncpy (char *dst, const char *src, size_t len);

// dst -- указатель на буфер назначения.

// src -- указатель на исходную строку.

// len -- максимальное количество копируемых символов (см. раздел Безопасность ниже).

// Функция копирует из строки src в буфер dst не более чем len символов

// (включая нулевой символ), не гарантируя завершения строки

// нулевым символом (если длина строки src больше или равна len).

// Если длина строки src меньше len, то буфер добивается до len нулями.

// Функция возвращает значение dst.

strncpy(s,&instr[inpos],wlen);

}

//получение слов, и если тип слова пробелы, запускает процедуру, пропускающую пробелы

int ReadingWordS(){

ReadingWord();

if (wtype==Word_space) {

wskip();

ReadingWord();

}

return wtype;

}

//увеличение отступа

void IncDt()

{

dt += 2;

}

//уменьшение отступа

void DecDt()

{

dt -= 2;

}

//вывод отступа

void put_dt()

{

for (int i=0; i<dt; i++) put_char(' ');

}

//вывод отступа

void put_dt11()

{

char s[10];

for (int i=0; i<dt; i++) {

sprintf(s,"%d",i/2);

put_str(s);

}

}

//открытие файла

int RecText(char * s1)

{

if ((filename1 = fopen(s1, "rt")) == NULL){

return 0;

}

fseek(filename1, 0, SEEK_END);

inlen = ftell(filename1);

fseek(filename1, 0, SEEK_SET);

if (inlen>allbuf) inlen = allbuf;

inlen = Process_read(instr,1,inlen,filename1);

instr[inlen] = 0;

inpos = 0;

outlen = 0;

return 1;

}

//вывод обработанного текста

int PutText(char * s2)

{

if ((filename2 = fopen(s2, "wt")) == NULL){

return 0;

}

Process_write(outstr,outlen,1,filename2);

return 1;

}

//вывод ошибочного оператора

void errore_program()

{

put_char('\n');

put_str("< Ошибка! > \n");

int k;

while (1){

ReadingWordS();

if (instr[inpos]== ';' || inpos>= inlen) {

copychar();

break;

};

copychar();

}

ker++; // увеличение счетчика ошибок

}

int flabel(int gl);

//проверка на комментарий

int Comment_is_find(){

return (instr[inpos]=='{' ||

instr[inpos]=='(' ||instr[inpos+1]=='*');

}

//проверка на закрытие комментария

void Comment_is_finish(){

if (instr[inpos]=='{'){

outstr[outlen] = '/';

outstr[outlen+1] = '*';

inpos++;

outlen += 2;

while (instr[inpos]!='}' && inpos<inlen) {

if (inpos>=inlen) return;

outstr[outlen] = instr[inpos];

inpos++;

outlen++;

}

outstr[outlen] = '*';

outstr[outlen+1] = '/';

inpos++;

outlen += 2;

}

else{

outstr[outlen] = '/';

outstr[outlen+1] = '*';

inpos += 2;

outlen += 2;

while (!(instr[inpos]=='*' && instr[inpos+1]==')')

&& inpos<inlen) {

if (inpos>=inlen) return;

outstr[outlen] = instr[inpos];

inpos++;

outlen++;

}

outstr[outlen] = '*';

outstr[outlen+1] = '/';

inpos += 2;

outlen += 2;

}

put_char('\n');

}

// здесь идет проверка на ключевое слово,

// сравниваются полученное нами слово со словом из списка

// и если да, то возвращается номер слова в списке

// проверка на ключевое слово

int fkW(){

for (int i=0; i<Array_Key_Word; i++){// просмотр всего массива Array_Key_Word

if (!scmp(&instr[inpos],KWs[i],wlen))

return i+1;

}

return 0;

}

// вот это обработка переменных после слова var,

// здесь идут обращения к тем четырем функциям работающим со списком перемнных

// обработка описания переменных: x1,..,xn: тип;

int fIntRealBoolAr(int svar, int gl){

char s[256];

int label;

int sp = 0;

ReadingWordS();

while (1){

if (wtype!=Word_string||fkW()|| gl>0&&vartype() ) return 0;

addvar(gl);

if (svar) {

s[sp] = '&';

s[sp+1] = ' ';

sp += 2;

}

memcpy(&s[sp],&instr[inpos],wlen);

inpos += wlen;

sp += wlen;

ReadingWordS();

if (instr[inpos]==','){

s[sp]=',';

inpos++;

sp++;

} else break;

ReadingWordS();

} // while(1)

if (instr[inpos]==':'){ //тип переменных

inpos++;

ReadingWordS();

if (wtype!=Word_string) return 0;

if (!scmp(&instr[inpos],"boolean",wlen)){

settype(gl,t_Bool);

put_str("int ");

wskip();

memcpy(&outstr[outlen],&s[0],sp);

outlen += sp;

}

else

if (!scmp(&instr[inpos],"real",wlen)){

settype(gl,t_Real);

put_str("float ");

wskip();

memcpy(&outstr[outlen],&s[0],sp);

outlen += sp;

}

else

if (!scmp(&instr[inpos],"integer",wlen)){

settype(gl,t_Int);

put_str("int ");

wskip();

memcpy(&outstr[outlen],&s[0],sp);

outlen += sp;

}

else

if (!scmp(&instr[inpos],usertype(),wlen)){

put_str(usertype());

put_str(" ");

wskip();

memcpy(&outstr[outlen],&s[0],sp);

outlen += sp;

}

else

if (!scmp(&instr[inpos],"array",wlen)){

wskip();

settype(gl,t_Array);

ReadingWordS();

if (instr[inpos]!='[') return 0;

s[sp]='[';

inpos++;

sp++;

while (1) {

ReadingWordS();

if (instr[inpos]!='1') return 0;

wskip();

ReadingWordS();

if (instr[inpos]!='.'||instr[inpos+1]!='.')

return 0;

inpos += 2;

ReadingWordS();

if (wtype!=w_numb) return 0;

memcpy(&s[sp],&instr[inpos],wlen);

inpos += wlen;

sp += wlen;

ReadingWordS();

if (instr[inpos]==']'){

s[sp]=']';

inpos++;

sp++;

break;

}

if (instr[inpos]==','){

inpos++;

s[sp]=']';

sp++;

s[sp]='[';

sp++;

}

}

ReadingWordS();

if (wtype!=Word_string) return 0;

if (scmp(&instr[inpos],"of",wlen)) return 0;

wskip();

ReadingWordS();

if (wtype!=Word_string) return 0;

if (scmp(&instr[inpos],"real",wlen)) return 0;

wskip();

put_str("float ");

memcpy(&outstr[outlen],&s[0],sp);

outlen += sp;

}

if(wequ("file"))

{

wskip();

ReadingWordS();

if(!wequ("of")) return 0;

wskip();

ReadingWordS();

put_str("FILE *");

memcpy(&outstr[outlen],&s[0],sp);

outlen += sp;

wskip();

settype(gl,t_File);

}

}

else return 0;

return 1;

}

//обработка описания блока переменных

int Process_var(int gl){

inpos += wlen;

ReadingWordS();

do{

koper1++;

if (Comment_is_find()){ //комментарии

Comment_is_finish();

koper2++;

continue;

}

put_dt();

if (!fIntRealBoolAr(0,gl)) errore_program();

else koper2++;

ReadingWordS();

if (instr[inpos]!=';')

return 0;

wskip();

put_str(";\n");

ReadingWordS();

if (wtype!=Word_string || fkW())

return 1;

}while(1);

}

//обработка блока описания переменных

int Process_vardescr(){

inpos += wlen;

int k,svar;

ReadingWordS();

do{

k = fkW();

svar = k==KeyS_var;

if (svar) {

wskip();

ReadingWordS();

}

if (!fIntRealBoolAr(svar,0)) return 0;

ReadingWordS();

if (instr[inpos]!=';') return 1;

wskip();

put_str(", ");

ReadingWordS();

k= fkW();

if (wtype!=Word_string || k&&k!=KeyS_var) return 0;

}while(1);

}

int fbegin(int k);

//обработка case

int Process_case()

{

int beg;

wskip();

put_dt();

put_str("switch");

put_str("(");

ReadingWordS();

copychar();

put_str("){\n");

ReadingWordS();

if (!wequ("of")) return 0;

wskip();

while(1)

{

ReadingWordS();

if (wequ("end")) {

wskip();

inpos++;

DecDt();

put_dt();

put_str("}\n");

break;

}

put_dt();

put_str("case ");

if ((wtype!=Word_string)&&(wtype!=w_numb)&&(wtype!=Word_char)) return 0;

if (instr[inpos]=='\'') {wskip(); put_str("\'");}

ReadingWordS();

copychar();

if (instr[inpos]=='\'') {wskip(); put_str("\'");}

ReadingWordS();

if (instr[inpos]!=':') return 0;

copychar();

ReadingWordS();

beg = 0; // по умолчанию ожидаем case 1: blabla;

if (wequ("begin")) {wskip(); beg = 1;}; // beg - для обработки begin end в кейс.

put_str("\n");

IncDt();

fbegin(3); // 3 - означает обработку case

DecDt();

if (wequ("end")&&beg)

{

put_dt();

put_str("break;\n");

wskip();

if(instr[inpos]==';') inpos++;

} else { put_dt(); put_str("break;\n");}

}

return 1;

}

int Process_rewrite()

{

wskip();

if (instr[inpos]!='(') return 0;

inpos++;

put_dt();

put_str("fcreate(");

ReadingWordS();

if(vartype()!=t_File) return 0;

copychar();

if (instr[inpos]!=')') return 0;

inpos++;

put_str(")");

if (instr[inpos]!=';') return 0;

inpos++;

put_str(";\n");

return 1;

}

int Process_reset()

{

wskip();

if (instr[inpos]!='(') return 0;

inpos++;

ReadingWordS();

wskip();

if (instr[inpos]!=')') return 0;

inpos++;

if (instr[inpos]!=';') return 0;

inpos++;

return 1;

}

int Process_assign()

{

int t;

wskip();

if (instr[inpos]!='(') return 0;

inpos++;

ReadingWordS();

if(t = vartype())

{

if(t==t_File)

{

put_dt();

copychar();

put_str(" = fopen(\"");

if(instr[inpos]!=',') return 0;

inpos+=2;

while (instr[inpos]!= '\'')

{

outstr[outlen] = instr[inpos];

inpos++;

outlen++;

}

inpos++;

put_str("\"");

put_str(",\"w\"");

ReadingWordS();

if (instr[inpos]!=')') return 0;

inpos++;

put_str(")");

if (instr[inpos]!=';') return 0;

inpos++;

put_str(";\n");

return 1;

}

}

return 1;

}

//обработка оператора read

int Process_read(int ln){

char s[256];

int sp;

int t;

wskip();

put_dt();

ReadingWordS();

if (instr[inpos]!='(') return 0;

inpos++;

ReadingWordS();

if(t = vartype())

{

if(t==t_File)

{

put_str("fscanf(");

copychar();

if(instr[inpos]!=',') return 0;

inpos++;

put_str(",");

while (instr[inpos]!= ')')

{

outstr[outlen] = instr[inpos];

inpos++;

outlen++;

}

ReadingWordS();

if (instr[inpos]!=')') return 0;

inpos++;

put_str(")");

if (instr[inpos]!=';') return 0;

inpos++;

put_str(";\n");

return 1;

}

}

put_str("scanf");

put_str("(\"");

sp=0;

while (1) {

ReadingWordS();

if (wtype!=Word_string) return 0;

t = vartype();

if (t==t_Int) put_str("%d");

else if (t==t_Real) put_str("%f");

else return 0;

s[sp] = '&';

sp += wlen;

ReadingWordS();

memcpy(&s[sp],&instr[inpos],wlen);

inpos += wlen;

sp += wlen;

ReadingWordS();

if (instr[inpos]!=',') break;

s[sp] = instr[inpos];

inpos++;

sp++;

}

put_str("\",");

memcpy(&outstr[outlen],s,sp);

outlen += sp;

ReadingWordS();

if (instr[inpos]!=')') return 0;

inpos++;

put_char(')');

ReadingWordS();

if (instr[inpos]!=';') return 0;

inpos++;

if (ln) put_str("; printf(\"\\n\");\n");

else put_str(";\n");

return 1;

}

//обработка оператора write

int Process_write(int ln){

char s[256];

int sp;

int t;

wskip();

put_dt();

ReadingWordS();

if (instr[inpos]!='(') return 0;

inpos++;

/* Обработка файла */

ReadingWordS();

if(t = vartype())

{

if(t==t_File)

{

put_str("fprintf(");

copychar();

if(instr[inpos]!=',') return 0;

inpos+=2;

put_str(",\"");

while (instr[inpos]!= '\'')

{

outstr[outlen] = instr[inpos];

inpos++;

outlen++;

}

inpos++;

put_str("\"");

ReadingWordS();

if (instr[inpos]!=')') return 0;

inpos++;

put_str(")");

if (instr[inpos]!=';') return 0;

inpos++;

put_str(";\n");

return 1;

}

}

put_str("printf");

put_char('(');

ReadingWordS();

if (instr[inpos]!='\'') return 0;

put_char('"');

inpos++;

while (instr[inpos]!= '\'') {

outstr[outlen] = instr[inpos];

inpos++;

outlen++;

}

inpos++;

if (instr[inpos]==')')

{

if (ln) put_str("\\n");

put_char(')');

inpos++;

if (instr[inpos]!=';') return 0;

inpos++;

put_str(";\n");

return 1;

}

if (instr[inpos]!=',') return 0;

inpos++;

sp=0;

while (1) {

ReadingWordS();

if (wtype!=Word_string) return 0;

t = vartype();

if (t==t_Int) put_str("%d");

else if (t==t_Real) put_str("%f");

else return 0;

memcpy(&s[sp],&instr[inpos],wlen);

inpos += wlen;

sp += wlen;

ReadingWordS();

if (instr[inpos]!=',') break;

s[sp] = instr[inpos];

inpos++;

sp++;

}

if (ln) put_str("\\n");

put_char('"');

ReadingWordS();

put_str("\,");

memcpy(&outstr[outlen],s,sp);

outlen += sp;

ReadingWordS();

if (instr[inpos]!=')') return 0;

inpos++;

put_char(')');

ReadingWordS();

if (instr[inpos]!=';') return 0;

inpos++;

put_str(";\n");

return 1;

}

//обработка арифметического выражения

int fae() {

ReadingWordS();

if (instr[inpos]=='+'){

copychar();

}

else

if (instr[inpos]=='-'){

copychar();

}

while (1){

ReadingWordS();

if (wtype==w_numb) copychar(); else

if (wtype==Word_string&&vartype()==t_Int) copychar(); else

if (wtype==Word_string&&vartype()==t_Real) copychar(); else

if (wtype==Word_string&&vartype()==t_Array) {

copychar();

ReadingWordS();

if (instr[inpos]=='['){

copychar();

while (1) {

if (!fae()) return 0;

put_str("-1");

ReadingWordS();

if (instr[inpos]==']'){

copychar();

break;

}

if (instr[inpos]==','){

wskip();

put_str("][");

}

}

}

} else

if (instr[inpos]=='('){

copychar();

if (!fae()) return 0;

ReadingWordS();

if (instr[inpos]!=')') return 0;

inpos++;

put_char(')');

}

else return 0;

ReadingWordS();

char c = instr[inpos];

if (c=='+'||c=='-'||c=='*'||c=='/') copychar();

else return 1;

}

}

//обработка арифметического выражения

int ae(){

char c,c1;

if (!fae()) return 0;

ReadingWordS();

c = instr[inpos];

c1 = instr[inpos+1];

if (c=='<'&&c1=='>') {

inpos += 2;

put_str("!=");

}

else

if (c=='=') {

inpos++;

put_str("==");

}

else

if (c=='>'||c=='<') {

if (c1=='='){

inpos += 2;

}

else copychar();

}

ReadingWordS();

if (!fae()) return 0;

return 1;

}

//обработка логического выражения

int fle() {

int k;

char c,c1;

int arifm, ip,op;

while (1){

ReadingWordS();

k = fkW();

int ip, op;

ip = inpos;

op = outlen;

arifm = 0;

if(instr[inpos]=='+'||

instr[inpos]=='('||

instr[inpos]=='-'||

wtype==Word_string&&!fkW() ||

wtype==w_numb)

arifm = ae();

if (!arifm){

inpos = ip;

outlen = op;

ReadingWordS();

k = fkW();

//------

if (wtype==Word_string&&k==KeyS_true){

wskip();

put_char('1');

}

else

if (wtype==Word_string&&k==KeyS_false) {

wskip();

put_char('0');

}

else

if (wtype==Word_string&&vartype()==t_Bool) copychar(); else

if (instr[inpos]=='('){

copychar();

if (!fle()) return 0;

ReadingWordS();

if (instr[inpos]!=')') return 0;

inpos++;

put_char(')');

}

else return 0;

}

ReadingWordS();

k = fkW();

if (k==KeyS_or) put_str("||"); else

if (k==KeyS_and) put_str("&&");

else return 1;

wskip();

}

}

//проверка на присваивание

int asign(){

int type = vartype();

if (!(type==t_Bool||type==t_Real||type==t_Int)) return 0;

//put_char('\n');

put_dt();

copychar();

ReadingWordS();

if (instr[inpos]!=':'||instr[inpos+1]!='=')

return 0;

put_char('=');

inpos += 2;

if (type==t_Bool) {

if (!fle()) return 0;

}

else

if (!fae()) return 0;

ReadingWordS();

if (instr[inpos]!=';') return 0;

copychar();

put_char('\n');

return 1;

}

//обработка оператора while

int fwhile() {

wskip();

put_dt();

put_str("while (");

if (!fle()) return 0;

ReadingWordS();

if (wtype!=Word_string||fkW()!=KeyS_do) return 0;

wskip();

put_str(")\n");

return 1;

}

//обработка блока операторов

int fbegin(int gl){

int rep_n = 0;

if(gl!=3) wskip();

if (gl==1) put_str("\n\nvoid main()\n");

if ((gl!=2)||(gl!=3)) {

put_dt();

put_str("{\n");

IncDt();

}

int b;

do{

b = 1;

ReadingWordS();

if (Comment_is_find()){

Comment_is_finish();

continue;

}

switch(fkW()){

case KeyS_begin:

koper1++;

if (!fbegin(0)) return 0;

koper2++;

break;

case KeyS_case:

koper1++;

if (!Process_case()) return 0;

break;

case KeyS_read:

koper1++;

if (!Process_read(0)) return 0;

koper2++;

break;

case KeyS_write:

koper1++;

if (!Process_write(0)) return 0;

koper2++;

break;

case KeyS_rewrite:

koper1++;

if (!Process_rewrite()) return 0;

koper2++;

break;

case KeyS_assign:

koper1++;

if (!Process_assign()) return 0;

koper2++;

break;

case KeyS_while:

koper1++;

if (!fwhile()) return 0;

koper2++;

break;

case KeyS_end:

koper1++;

if(gl == 3) return 3;

wskip();

DecDt();

put_dt();

put_str("}\n");

ReadingWordS();

if (gl==1&&instr[inpos]=='.' ||

gl!=1&&instr[inpos]==';'){

wskip();

koper2++;

return 1;

}

else

{

wskip();

return 0;

}

case 0:

if (!asign()) return 0; //присваивание

break;

default:

return 0;

}

} while (b);

return 1;

}

//главная функция преобразования ттекста

//преобразование текста

int Translate()

{

int b;

int k;

koper1 = koper2 = 0;

put_str("#include <stdio.h>\n\n"); //для scanf и printf

do{

b = 1;

ReadingWordS();

k = fkW(); //проверка на ключевое слово

if (k==KeyS_var){ //начало блока переменных

koper1++;

if (!Process_var(1)) {

errore_program();

}

else koper2++; }

else

if (k==KeyS_type){ //блок описания типов

koper1++;

if (!frecord()) {

errore_program();

}

else koper2++;

}

else

if (k==KeyS_begin){ //начало блока операторов

if (!fbegin(1)) {

errore_program();

}

b = 0;

}

else

if (Comment_is_find()) Comment_is_finish(); //комментарии

else {

koper1++;

errore_program();

};

} while (b==1);

if (instr[inpos]!='.') return 0; //точка в конце программы

inpos++;

return 1;

}

void main()

{

setlocale(LC_ALL,"Russian");

char s[128];

printf("Введите имя входного файла: ");

scanf("%s",s);

if (!RecText(s))

{

printf("\nОшибка открытия файла!");

}

vars = NULL;

lvars = NULL;

uvars = cuservars;

Translate();

freevars(1);

printf("\nВведите имя выходного файла:");

scanf("%s",s);

if (!PutText(s))

{

printf("\nОшибка создания файла!");

}

printf("\nКоличество операторов"

" в исходном файле: %d", koper1);

printf("\nКоличество операторов"

" в полученном файле: %d", koper2);

printf("\nКоличество ошибочных операторов"

" которые не были обработаны: %d", ker);

printf("\n\nРезультат хранится в файле: %s",s);

fclose(filename1);

fclose(filename2);

while (!kbhit()) ;

}

7. Результаты тестирования программы

На входе:

var

i,k:integer;

m:real;

fl:file of integer;

begin

assign(fl,'c:tuc\tuc.txt');

rewrite(fl);

write(fl,'bla');

Case k of

1 : Begin

End;

2 : Begin

End;

3 : Begin

writeln('privet!');

readln();

End;

4 : Begin

End;

end;

End.

На выходе:

#include <stdio.h>

int i,k;

float m;

FILE *fl;

void main()

{

fl = fopen("c:tuc\tuc.txt","w");

fcreate(fl);

fprintf(fl,"bla");

switch(k){

case 1:

{

break;

case 2:

{

break;

case 3:

{

break;

case writeln

< Ошибка! >

('privet!');

программа код язык оператор

На рисунке 1 скриншот экрана после работы программы

Рисунок 1 - Результат работы программы

Заключение

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

Список литературы

Основная

Зайцева, Л. В. Алгоритмические языки и пpoгpaммиpoвaниe / Л. В. Зaйцeвa. - М. : МГГУ, 1996.

Фapoнoв, В. В. Пpoгpaммиpoвaниe нa ПЭВМ в сpeдe Туpбo-Пaскaль / В. В. Фapoнoв. - М. : МГТУ, 1999.

Alfred V. Aho Jeffrey D. Ullman The theory of parsing, translation and compiling Prentice-Hall, inc Englewood Clifis, N. J., 1972

Дoпoлнитeльнaя

1. Кpaсoв, A. В. Пpoгpaммиpoвaниe нa Borland C пoд MS Windows / A. В. Кpaсoв. - СПб. : СПбГУТ, 2001.

2. Зaйцeвa, Л. В. Мeтoдичeскиe укaзaния для выпoлнeния куpсoвoгo пpoeктa пo дисциплинe "Aлгopитмичeскиe языки и пpoгpaммиpoвaниe" пo спeц. 2203 / Л. В. Зaйцeвa, В. Г. Ссopин, E. A. Epoхинa, 2005.

Размещено на Allbest.ru


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.