Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовые по программированию / v29 / Шиндин А.Ю. - отчет по курсовой работе.doc
Скачиваний:
11
Добавлен:
20.05.2014
Размер:
551.42 Кб
Скачать
    1. Выделение подпрограмм

Подпрограммы детального анализа ключевых слов

Каждая из подпрограмм детального анализа ключевого слова выполняет следующие действия:

  • Выясняет, правильно ли оформлены логическое или арифметическое выражение, если оно предполагается в предложении Паскаля, содержащего соответствующее ключевое слово..

  • Определяет, нет ли в предложении признака продолжения (текст расширения). Если есть, то соответствуещее окончание предложение отрезается и отсылается снова в началобуфераstr_bufдля последующего анализа. Например, в предложении

  1. If a>b then begin c:=d;

  1. текст If a>b будет выделен и обработан, а текст then begin c:=d; будет отправлен в str_buf.

  • Проводит преобразование текста, непосредственно следующего за ключевым словом (кроме текста расширения) в эквивалентный текст на языке С.

  • Выводит полученный текст предложения на С в выходной файл. При выводе в файл выполняется дополнение текста слева необходимым количеством пробелов в соответствии с логикой генерируемого текста (подпрограммы increase_indentиdecrease_indent). Например, предложение

  1. if (a>b) { с =2;d =1;}

  2. выводится в следующем формате:

  3. if (a>b)

  4. {

  5. с =2;

  6. d =1;

  7. }

Подпрограммы анализа выражений

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

  • Подпрограмма анализа логического выражения (Analyze_LE1) вызывается при обработке предложений ПаскаляIfиUntil.

  • Подпрограма анализа арифметического выражения (Analyze_AE2) вызывается при обработке логического выражения, а также при обработке оператора присваивания.

  • Подпрограмма анализа имени идентификатора (Analyze_Identify) вызывается при анализе оператора присваивания, оператораFunction,в секцияхVar, Const, Uses, Label.

Cлужебные подпрограммы

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

  • Подпрограммы Ltrim, Rtrim, Pos, Reverse, GetHead, GetTailиспользуются для анализа и преобразования строк символов.

  • Подпрограмма Output_C_Linesвыводит полученный текст на языке С в файл вывода и увеличивает счетчик выходных строк.

    1. Диаграммы анализа выражений

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

      1. Логическое выражение le1

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

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

/////////////////////////////////////////////////////////////////////////////

// //

// Ковертор из Паскаля в Си А.Шиндин, МИЭМ 2005 //

// Курсовой проект. Обработка исходного текста на Паскале //

// и получение текста на Си по правилам заданного варианта. //

// //

/////////////////////////////////////////////////////////////////////////////

#include <stdio.h>

#include <conio.h>

#include <ctype.h>

#include <string.h>

#include <stdlib.h>

#define buf_len 255 //максимальный размер рабочих строк

#define buf_len_short 32

#define ZNAK *s_cur=='-' || *s_cur=='+'

#define true 0

#define false 1

char str_expr[80];//глобальная переменная строка с выражением Ae2

char *s_cur;//указатель на номер текущей позиции в str_expr

char pas_prog_name[buf_len];//имя исходной программы на языке Pascal

char c_prog_name[buf_len]; //имя получаемой программы на языке C

FILE *file_in, *file_out; //входной файл (*.pas) и выходной файл (*.c)

int count_source_lines=0; //счетчик строк на Pascal'е

int count_out_lines=0; //счетчик законченных предложений на C (translated to C)

int other_oper_flag=0; //см. подпрограму Analyze_Other_Operator

int main_flag=0; //используется для определения контекста исполнения:

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

//внутри подпрограммы или функции

int function_flag=0; // этой переменной присваивается значение 1,

//если встречается кл.слово "function";

int function_end_level=0;

// если установлен function_flag=1 и далее

//встречается кл.слово "begin", то переменная

//"function_end_level" увеличивается на 1;

// если установлен function_flag=1 и встречается

//кл.слово "end", то "function_end_level"

//уменьшается на 1.;

// если function_end_level становится равной 0

//после очередного "end", то флажок

//"function_flag" снова становится равным 0.

//Такой подход позволяет точно установить "begin",

//относящийся к главной программе на Паскале.

//Когда это происходит, переменная

//"function_flag" устанавливается в 2.

int indent=0; //отступ для строки на C (от начала строки).

int indent_delta=2; //прирост отступа (для его уменьшения/увеличения)

char indent_text[buf_len]; //строка символов, используемая для вставки

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

int errors_counter=0; //счетчик ошибок

int anomaly_counter=0; //счетчик аномалий

char anomaly_text[buf_len];//сообщение об аномалии

char str_in[buf_len]; //путь доступа к входному файлу

//на Паскале

char str_out[buf_len]; //путь доступа к выходному файлу

//на C

char str_temp[buf_len]; //для чтения исходных строк

char str_temp_nocomments[buf_len]; //для накопления исходного текста,

//очищенного от комменатриев

char str_buf[buf_len]; //буфер накопления текста на Паскале

char w_str[buf_len]; //рабочая строка для обр-ки буфера

char str_sep[buf_len]=";"; //строка разделителей исходных операторов

char comments_buf[buf_len]; //буфер накопления комменариев

char non_comments_buf[buf_len]; //фрагмент исходного текста, очищенного

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

char anykey[1]=" "; //строка используется для остановки

//программы во время выполнения

//через gets(anykey)

int fid=0; //function id;

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

int pos(char *str1, char *str2);

char* GetHead(char *str1, char *str2);

char* GetTail(char *str1, char *str2);

void Reverse(char *str1, char *str2);

void GetPaths();

void Pas_to_C(char* pas_str, char* c_str);

void ClearOffBlanks(char *str1, char* str2);

void LTrim(char* str1, char* seps, char* str2);

void RTrim(char* str1, char* seps, char* str2);

void Press_Blanks(char *str1, char* str2);

void Analyze_Assignment(char* str1, char* str2);

void Analyze_Repeat(char *str1, char *str2);

void Analyze_If(char *str1, char *str2);

void Analyze_Then(char *str1, char *str2);

void Analyze_Else(char *str1, char *str2);

void Analyze_Until(char *str1, char *str2);

void Analyze_Begin(char *str1, char *str2);

void Analyze_End(char *str1, char *str2);

void Analyze_End_Prog(char *str1, char *str2);

void Analyze_GoTo(char *str1, char *str2);

void Analyze_Function(char *str1, char *str2);

void Analyze_Var(char *str1, char *str2);

void Analyze_Var_Oper(char *str1, char *str2);

void Analyze_Const(char *str1, char *str2);

void Analyze_Const_Oper(char *str1, char *str2);

void Analyze_Uses(char *str1, char *str2);

void Analyze_Uses_Oper(char *str1, char *str2);

void Analyze_Label(char *str1, char *str2);

void Analyze_Label_Oper(char *str1, char *str2);

void Analyze_Other_Operator(char *str1, char *str2);

void Analyze_Program_Start();

void Output_C_lines(char* str);

void Replace(char* str1, char* str2, char* str3, char* str4);

void Reformat_Logical_Expression(char *str1, char *str2);

void Reformat_Other_Operators(char *str1, char *str2);

void increase_indent();

void decrease_indent();

int Analyze_Const(); //функция анализа константы без знака

int Analyze_Identify();//функция анализа идентификатора

int Analyze_Mnog(); //функция анализа множителя

int Analyze_Slag(); //функция анализа слагаемого

int Analyze_Perem(); //функция анализа переменной

int Analyze_Ae2(); //функция анализа арифметического выражения Ae2

int Analyze_Le1(); //функция анализа логического выражения Le1(на входе-Ae2)

int Analyze_Symb_Le1();//функция анализа символа между двумя Ae2

//блок подпрограмм

/*=========================================================================*/

void increase_indent()

//увеличиваем отступ для формируемых строк на С

{

fid=1;

char bl[buf_len]

=" ";

indent = indent+indent_delta;

if (indent <= 0)

{

*indent_text=0;

}

else

{

strncpy(indent_text,bl,indent);

indent_text[indent]='\0';

}

return;

}

/*=========================================================================*/

void decrease_indent()

//уменьшаем отступ для формируемых строк на С

{

fid=2;

char bl[buf_len]

=" ";

indent = indent-indent_delta;

if (indent < 0) indent=0;

if (indent <= 0)

{

*indent_text=0;

}

else

{

strncpy(indent_text,bl,indent);

indent_text[indent]='\0';

}

return;

}

/*=========================================================================*/

void Analyze_Program_Start()

//формирование начала программы на С

{

fid=3;

char c_prog_line[buf_len];//the output prog header line

Output_C_lines("/*Pascal to C converter by A.Shindin MIEM 2005*/");

strcpy(c_prog_line,"#include <stdio.h>");Output_C_lines(c_prog_line);

strcpy(c_prog_line,"#include <conio.h>");Output_C_lines(c_prog_line);

strcpy(c_prog_line,"#include <ctype.h>");Output_C_lines(c_prog_line);

strcpy(c_prog_line,"#include <string.h>");Output_C_lines(c_prog_line);

strcpy(c_prog_line,"#include <stdlib.h>");Output_C_lines(c_prog_line);

strcpy(c_prog_line,"#define buf_len 255");Output_C_lines(c_prog_line);

}

/*=========================================================================*/

void Output_C_lines(char *str)

//подрограмма вывода в результирующий файл строки str

{

//fid=4;

if (strcmp(str,";")==0)

{}

else

{

char out_c_str[buf_len];

strcpy(out_c_str,indent_text);

strcat(out_c_str,str);

fputs(out_c_str,file_out);

fputs("\n",file_out);

count_out_lines++;

}

}//proc

/*=================================================*/

void ClearOffBlanks(char *str1, char* str2)

//подпрограмма выполняет следующие действия:

// 1. Очищает слева строку от "пропусков" (пробелов, знаков tab и т.п.)

// 2. Добавляет пробелы в начале и конце строки, до и после скобок,

// перед точкой с запятой.

// 3. Двойные пробелы заменяет на одиночные.

// Полученная строка записывается в str2.

{

fid=5;

char sw1[buf_len];

char sw2[buf_len];

//добавление пробелов

strcpy(sw1," ");

strcat(sw1,str1);

strcat(sw1," ");

//замена пропусков (табуляторов и концов строк) на пробелы

Replace(sw1,"\t "," ",sw2);strcpy(sw1,sw2);

Replace(sw1," \t"," ",sw2);strcpy(sw1,sw2);

//excluding the line break character

Replace(sw1,"\n"," ",sw2);strcpy(sw1,sw2);

//замена ";" на " ;"

Replace(sw1,";"," ;",sw2);strcpy(sw1,sw2);

//замена скобок на комбинации пробелов и скобок

Replace(sw1,"("," ( ",sw2);strcpy(sw1,sw2);

Replace(sw1,")"," ) ",sw2);strcpy(sw1,sw2);

//замена двойных пробелов на одиночные

while (pos(sw1," ")>=0)

{

Replace(sw1," "," ",sw2);strcpy(sw1,sw2);

}

strcpy(str2,sw1);

return;

}//proc

/*=========================================================================*/

void Analyze_Other_Operator(char *str1, char *str2)

{

//Анализ и преобразование строк с "прочими" ключевыми словами

// Здесь мы анализируем строку на Паскале, в которой не обнаружены

//ключевые слова, входящие в задачу курсовой работы.

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

//(переменная "other_oper_flag")

// Этот флажок может иметь одно из следующих значений:

// 0 мы находимся внутри программы, подпрограммы или функции

// 1 мы находимся в секции uses

// 2 мы находимся в секции const

// 3 мы находимся в секции label

// 4 мы находимся в секции var

fid=6;

switch (other_oper_flag)

{

case 0:

Analyze_Assignment(str1, str2);

break;

case 1:

Analyze_Uses_Oper(str1, str2);

break;

case 2:

Analyze_Const_Oper(str1, str2);

break;

case 3:

Analyze_Label_Oper(str1, str2);

break;

case 4:

Analyze_Var_Oper(str1, str2);

break;

}

}

/*=========================================================================*/

void Analyze_If(char *str1, char *str2)

//анализ и преобразование строки на Паскале, содержащей

//ключевое слово IF

//str1=ключевое слово

//str2=список параметров или конец исходной строки

{

fid=7;

int pos_then;

int log_exp_len;

char logical_expression[buf_len];

char *sw;

char sw1[buf_len];

char sw2[buf_len];

char c_expr[buf_len];

char _tail[buf_len];

char str_buf_work[buf_len];

//обработка исходной строки

strcpy(sw1,str2);

pos_then = pos(strupr(sw1),"THEN");

if (pos_then==-1)

{//THEN не найдено - это ошибка - концевик очищаем

log_exp_len=strlen(sw1);

*_tail=0;

//создаем строку на С с комментарием about wrong expression

//*anomaly_text=0;

//strcat(anomaly_text,"\n{");

//strcat(anomaly_text,"Не обнаружен оператор Then");

//strcat(anomaly_text,"}");

//Output_C_lines(c_expr);

//anomaly_counter++;

}

else

{//THEN найдено - берем концевик после "then"

log_exp_len=pos_then;

*_tail=0;

strcpy(_tail,str2+pos_then);

}

//выделяем логическое выражение в IF

*sw2=0;

strncat(sw2,str2,log_exp_len);

//strncat(sw2,"",1);

//Analyze_Le1() работает с переменной str_expr

//убираем пробелы перед анализм le

strcpy(sw1,sw2);

Replace(sw1," ","",sw2);

strcpy(str_expr,sw2);

//printf("\nstr_expr=<%s>",str_expr);

//анализ Le1

fid=7;

s_cur=str_expr;

if(Analyze_Le1()==true)

{

//printf("\n correct logical expr=<%s>",str_expr);

strcpy(sw2,str_expr);

//преобразуем логическое выражение

Reformat_Logical_Expression(sw2,logical_expression);

//создаем строку на С с логическим выражением

*c_expr=0;

strcat(c_expr,"if ( ");

strcat(c_expr,logical_expression);

strcat(c_expr," ) ");

Output_C_lines(c_expr);

}

else

{

//printf("\n incorrect logical expr=<%s>",str_expr);

*c_expr=0;

strcat(c_expr,str1);

strcat(c_expr," ");

strcat(c_expr,str2);

strcat(c_expr,"/*ERR: Error in logical expression*/");

errors_counter++;

Output_C_lines(c_expr);

}

//возвращаем концевик в начало буфера str_buf

*str_buf_work=0;

strcat(str_buf_work,_tail);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

//gets(anykey);

return;

}//proc

/*=========================================================================*/

void Analyze_Then(char *str1, char *str2)

//анализ и преобразование строки на Паскале, содержащей

//ключевое слово THEN

//str1=ключевое слово

//str2=список параметров или конец исходной строки

{

fid=8;

char str_buf_work[buf_len];

//возвращаем концевик в начало буфера str_buf

*str_buf_work=0;

strcat(str_buf_work,str2);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

return;

}//proc

/*=========================================================================*/

void Analyze_Until(char *str1, char *str2)

//анализ и преобразование строки на Паскале, содержащей

//ключевое слово UNTIL

//str1=ключевое слово

//str2=список параметров или конец исходной строки

{

fid=9;

int pos_then;

int log_exp_len;

char logical_expression[buf_len];

char *sw;

char sw1[buf_len];

char sw2[buf_len];

char c_expr[buf_len];

char _tail[buf_len];

char str_buf_work[buf_len];

fid=9;

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

strcpy(sw1,str2);

//вычеркиваем ";"

Replace(sw1,";","",sw2);strcpy(sw1,sw2);

//убираем пробелы перед анализм le

Replace(sw1," ","",sw2);strcpy(sw1,sw2);

strcpy(str_expr,sw1);

//printf("\nstr_expr=<%s>",str_expr);

//Analyze_Le1() работает с переменной str_expr

//анализ

s_cur=str_expr;

if (Analyze_Le1()==true)

{

strcpy(sw1,str_expr);

//преобразуем логическое выражение

Reformat_Logical_Expression(sw1,logical_expression);

//создаем эквивалентные строки на С

*c_expr=0;

strcat(c_expr,"}");

Output_C_lines(c_expr);

decrease_indent(); //уменьшаем отступ, увеличенный по "repeat"

*c_expr=0;

strcat(c_expr,"while !( "); //until (le) ==> while !(le)

strcat(c_expr,logical_expression);

strcat(c_expr," );");

Output_C_lines(c_expr);

}

else

{

printf("\n incorrect logical expr=<%s>",str_expr);

*c_expr=0;

strcat(c_expr,str1);

strcat(c_expr," ");

strcat(c_expr,str2);

strcat(c_expr,"/*ERR: Error in logical expression*/");

errors_counter++;

Output_C_lines(c_expr);

}

return;

}//proc

/*=========================================================================*/

void Analyze_End(char *str1, char *str2)

//анализ и преобразование строки на Паскале, содержащей

//ключевое слово END

//str1=ключевое слово

//str2=список параметров или конец исходной строки

{

fid=10;

char c_expr[buf_len];

char _tail[buf_len];

char str_buf_work[buf_len];

char sw1[buf_len];

char sw2[buf_len];

//формируем эквивалентный текст на С

// end ==> }

*c_expr=0;

strcat(c_expr,"}");

Output_C_lines(c_expr);

decrease_indent(); //уменьшаем отступ

//очищаем str2 от ;

//Replace(str2,";","",sw2);

//strcpy(str2,sw2);

//если после "end" есть текст, то возвращаем его в начало str_buf

*str_buf_work=0;

strcat(str_buf_work,str2);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

//анализируем, не закончился ли оператор "function"

if (function_flag == 1) //был "function"

{

function_end_level=function_end_level-1; //уменьшаем уровень "end"

if (function_end_level == 0) //если достигли 0, то этот "end"

{ //завершил функцию

function_flag = 0;

}

}

return;

}//proc

/*=========================================================================*/

void Analyze_End_Prog(char *str1, char *str2)

//анализ и преобразование строки на Паскале, содержащей

//ключевое слово END.

//str1=ключевое слово

//str2=список параметров или конец исходной строки

{

fid=11;

char c_expr[buf_len];

char _tail[buf_len];

char str_buf_work[buf_len];

decrease_indent();//уменьшаем отступ

//формируем эквивалентный текст на С

// end. ==> }

*c_expr=0;

strcat(c_expr,"}");

Output_C_lines(c_expr);

return;

}//proc

/*=========================================================================*/

void Analyze_Else(char *str1, char *str2)

//анализ и преобразование строки на Паскале, содержащей

//ключевое слово ELSE

//str1=ключевое слово

//str2=список параметров или конец исходной строки

{

fid=12;

char c_expr[buf_len];

char _tail[buf_len];

char str_buf_work[buf_len];

decrease_indent();//уменьшаем отступ

//формируем эквивалентный текст на С

*c_expr=0;

strcat(c_expr,"else");

Output_C_lines(c_expr);

//возвращаем концевик текста в начало str_buf

*str_buf_work=0;

strcat(str_buf_work,str2);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

//increase_indent();//снова увеличиваем отступ

return;

}//proc

/*=========================================================================*/

void Analyze_Begin(char *str1, char *str2)

//анализ и преобразование строки на Паскале, содержащей

//ключевое слово BEGIN

//str1=ключевое слово

//str2=список параметров или конец исходной строки

{

fid=13;

char c_expr[buf_len];

char _tail[buf_len];

char str_buf_work[buf_len];

char sw1[buf_len];

char sw2[buf_len];

//копируем концевик от "begin" в рабочую строку

strcpy(_tail,str2);

increase_indent(); //увеличиваем отступ

//Проверяем, относится ли "begin" к тексту главной программы на Паскале

if (function_flag == 0)

{//Да, этот "begin" относится к тексту главной программы

indent=0; //сбрасываем отступ

*indent_text=0; //и очищаем строку отступа

//формируем текст на С эквивалентный началу программы

*c_expr=0;

strcat(c_expr,"\n/*MAIN PROGRAM*/\n");//обозначаем место

Output_C_lines(c_expr); //главной программы

*c_expr=0;

strcat(c_expr,"void main()");

Output_C_lines(c_expr);

function_flag = 2;//теперь мы находимся в главной программе

}

other_oper_flag=0;

function_end_level = function_end_level+1;//мы нашли "begin" -

//увеличим уровень "begin-end"

//printf("\nbeg_stmt: <%s> f_flag: <%d> fe_level: <%d>",str2,function_flag,function_end_level);

//формируем начало блока, если это не первый begin внутри function

if ((function_flag == 1) && (function_end_level == 1))

{

//printf("\n first begin in function");

}

else

{

//printf("\n non-first begin in function");

*c_expr=0;

strcat(c_expr,"{");

Output_C_lines(c_expr);

}

//весь концевик после "begin" отправляем в начало str_buf

*str_buf_work=0;

strcat(str_buf_work,_tail);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

return;

}//proc

/*=========================================================================*/

void Reformat_Logical_Expression(char *str1, char *str2)

//анализ и преобразование строки на Паскале, содержащей

//логическое выражение, в эквивалентное выражение на С

//str1=исходное выражение

//str2=выходное выражение

{

fid=14;

char sw1[buf_len];

char sw2[buf_len];

strcpy(sw1,str1);

//преобразуем выражение в канонический вид (проводим замены)

//это необходимо, чтобы отличить обработку "=" от ">=" и т.п.

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

//длинные

Replace(sw1,">=",".GE.",sw2);strcpy(sw1,sw2);

Replace(sw1,"<=",".LE.",sw2);strcpy(sw1,sw2);

Replace(sw1,":=",".ASGN.",sw2);strcpy(sw1,sw2);

//короткие

Replace(sw1,">",".GT.",sw2);strcpy(sw1,sw2);

Replace(sw1,"<",".LT.",sw2);strcpy(sw1,sw2);

Replace(sw1,"=",".EQ.",sw2);strcpy(sw1,sw2);

//теперь преобразуем из канонического вида в вид на С

Replace(sw1,".GE.",">=",sw2);strcpy(sw1,sw2);

Replace(sw1,".LE.","<=",sw2);strcpy(sw1,sw2);

Replace(sw1,".GT.",">",sw2);strcpy(sw1,sw2);

Replace(sw1,".LT.","<",sw2);strcpy(sw1,sw2);

Replace(sw1,".EQ.","==",sw2);strcpy(sw1,sw2);

Replace(sw1,".ASGN."," = ",sw2);strcpy(sw1,sw2);

//проводим дополнительные замены для др. лог.операций

Replace(sw1," and "," && ",sw2);strcpy(sw1,sw2);

Replace(sw1," And "," && ",sw2);strcpy(sw1,sw2);

Replace(sw1," AND "," && ",sw2);strcpy(sw1,sw2);

Replace(sw1," or "," || ",sw2);strcpy(sw1,sw2);

Replace(sw1," Or "," || ",sw2);strcpy(sw1,sw2);

Replace(sw1," OR "," || ",sw2);strcpy(sw1,sw2);

strcpy(str2,sw1);

return;

}//proc

/*=========================================================================*/

void Reformat_Other_Operators(char *str1, char *str2)

//str1=исходное выражение

//str2=выходное выражение

{

fid=30;

char sw1[buf_len];

char sw2[buf_len];

strcpy(sw1,str1);

Replace(sw1,"writeln","printf",sw2);strcpy(sw1,sw2);

Replace(sw1,"readln","scanf",sw2);strcpy(sw1,sw2);

strcpy(str2,sw1);

}

/*=========================================================================*/

void Analyze_Repeat(char *str1, char *str2)

//подрограмма на анализ оператора "Repeat"

//преобразуется в оператор do {

//str1=исходное выражение

//str2=выходное выражение

{

fid=15;

char c_expr[buf_len];

char _tail[buf_len];

char str_buf_work[buf_len];

char sw1[buf_len];

char sw2[buf_len];

//выделение концевика от "repeat"

strcpy(_tail,str2);

//формируем эквивалентный текст на С (repeat ==> do {)

*c_expr=0;

strcpy(c_expr,"do");

Output_C_lines(c_expr);

increase_indent();//увеличиваем отступ (он будет уменьшен в until)

strcpy(c_expr,"{");

Output_C_lines(c_expr);

//возвращаем концевик в начало буфера накпления Паскаля str_buf

*str_buf_work=0;

strcat(str_buf_work,_tail);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

return;

}//proc

/*=========================================================================*/

void Analyze_Function(char *str1, char *str2)

{

fid=16;

//подрограмма на анализ оператора "Function"

//str1=исходное выражение

//str2=выходное выражение

char c_str[buf_len];

char function_name[buf_len];

char function_type[buf_len];

char function_parametres[buf_len];

char function_parametres_temp[buf_len];

char *sw,*sw1,*sw2;//рабочие строки для GetHead и GetTail

char w_str[buf_len];//рабочая строка

char w_str2[buf_len];//рабочая строка

char str_buf_work[buf_len];//рабочая строка

char w_str_par[buf_len];

char convert_str[buf_len];

char p_sep[1]="Й"; //строка используется для разделения групп параметров

int more_par_groups=1; //флажок продолжения анализа групп параметров

int more_parameters=1; //флажок продолжения анализа групп параметров

char parm_group[buf_len]; //для группы параметров

char parm[buf_len]; //для параметров

char parm_type[buf_len]; //для типа параметра

char parm_type_valid[buf_len]; //для допустимых типов параметров

char parm_tstr[buf_len]; //для анализа параметров

char c_parms [buf_len]; //для накопления эквивалентного

//описания параметров на С

int p_zs; //поз.закр.скобки

int p_ptype; //поз.корр.типа параметра

int flag_not_OK=0; //флажок некорректности предложения function

strcpy(parm_type_valid,",INTEGER,STRING,");

//чистим строки для С

*c_str=0;

*c_parms=0;

//очищаем строку от пробелов и формируем рабочую строку

//Replace(str2," ","",w_str);

strcpy(w_str,str2);

//анализируем, есть ли закр. скобка

p_zs=pos(str2,")");

if (p_zs==-1) //это еще не полный вариант оператора function

{

*w_str=0;

strcat(w_str,str1);

strcat(w_str, " ");

strcat(w_str,str2);

Replace(w_str,";",p_sep,w_str2); //заменяем ";" на разделитель

//возвращаем все неоконченное предложение в начало str_buf

*str_buf_work=0;

strcat(str_buf_work,w_str2);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

}

else //теперь обрабатываем весь оператор function с разделителями групп параметров

{

//выделяем имя функции

sw=GetHead(w_str,"(");

strcpy(function_name,sw);

free(sw);

//printf("function name:<%s>\n",function_name);

//анализ имени функции на идентификатор

strcpy(str_expr,function_name);

s_cur=str_expr;

if(Analyze_Identify()==true)

{}

else

{flag_not_OK++;}

//if (flag_not_OK > 0) {printf("func.name");}

//уменьшаем рабочую строку

strcpy(w_str,str2);

sw=GetTail(w_str,")");

strcpy(w_str,sw);

free(sw);

//printf("w_str 1:<%s>\n",w_str);

sw=GetTail(w_str,":");

strcpy(w_str,sw);

free(sw);

//printf("w_str 2:<%s>\n",w_str);

sw=GetHead(w_str,";");

strcpy(w_str,sw);

free(sw);

//printf("w_str 3:<%s>\n",w_str);

Replace(w_str," ","",convert_str);

strcpy(w_str,convert_str);

//printf("w_str 4:<%s>\n",w_str);

//выделяем тип функции

strcpy(function_type,w_str);

//printf("function type 1:<%s>\n",function_type);

//преобразуем тип функции

if(strcmp(function_type,"integer")==0)

{

Replace(function_type,"integer","int",convert_str);

}

if(strcmp(function_type,"string")==0)

{

Replace(function_type,"string","char",convert_str);

}

strcpy(function_type,convert_str);

//printf("function type 2:<%s>\n",function_type);

//параметры

strcpy(w_str,str2);

//выделяем параметры функции

sw1=GetTail(w_str,"(");

strcpy(w_str_par,sw1);

free(sw1);

sw2=GetHead(w_str_par,")");

strcpy(function_parametres,sw2);

free(sw2);

//printf("function par:<%s>\n",function_parametres);

//сохраняем function_parametres

strcpy(function_parametres_temp,function_parametres);

//добавляем в конец function_parametres p_sep для корр.анализа

strcat(function_parametres,p_sep);

//обрабатываем группы параметров

more_par_groups=1;

while(more_par_groups==1)

{

sw1=GetHead(function_parametres,p_sep);

strcpy(parm_group,sw1);

free(sw1);

if (strlen(parm_group)==0) //очередная группа не выделена

{

more_par_groups=0;

}

else //анализируем параметры группы

{

//printf("parm group:<%s>\n",parm_group);

//удаляем описатель "var", если он есть и пробелы

Replace(parm_group,"var","",parm_tstr);strcpy(parm_group,parm_tstr);

Replace(parm_group,"Var","",parm_tstr);strcpy(parm_group,parm_tstr);

Replace(parm_group," ","",parm_tstr);strcpy(parm_group,parm_tstr);

//выделяем тип параметров

sw1=GetTail(parm_group,":");

strcpy(parm_type,sw1);

free(sw1);

//допустим ли этот тип параметра?

strcpy(parm_tstr,",");

strcat(parm_tstr,parm_type);

strcat(parm_tstr,",");

strupr(parm_tstr);

p_ptype=pos(parm_type_valid,parm_tstr);

if (p_ptype==-1) //если это некорр.тип параметра

{

flag_not_OK++;

strcpy(parm_type,"illegal");

//if (flag_not_OK > 0) {printf("parm.type");}

}

//printf("parm type:<%s>\n",parm_type);

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

Replace(parm_group,":",",:",parm_tstr);strcpy(parm_group,parm_tstr);

//обрабатываем параметры

more_parameters=1;

while(more_parameters==1)

{

sw1=GetHead(parm_group,",");

strcpy(parm,sw1);

free(sw1);

//printf("parm:<%s>\n",parm);

if (strlen(parm)==0) //очередной параметр не выделен

{

more_parameters=0;

}

else

{

//анализ имени параметра корректность идентификатор

strcpy(str_expr,parm);

s_cur=str_expr;

if(Analyze_Identify()==true)

{

}

else

{

flag_not_OK++;

//if (flag_not_OK > 0) {printf("parm.name");}

}

//формируем строку для С

if (strcmp(strupr(parm_type),"INTEGER")==0)

{

strcat(c_parms, "int ");

strcat(c_parms, parm);

}

else if (strcmp(strupr(parm_type),"STRING")==0)

{

strcat(c_parms, "char* ");

strcat(c_parms, parm);

}

else

{

strcat(c_parms, "illegal ");

strcat(c_parms, parm);

}

strcat(c_parms, ", ");

//остаток строки parm_group переписываем в parm_group

//для продолжения анализа параметров

sw1=GetTail(parm_group,",");

strcpy(parm_group,sw1);

free(sw1);

}

}

//остаток строки function_parametres переписываем в

//function_parametres для продолжения анализа групп

sw1=GetTail(function_parametres,p_sep);

strcpy(function_parametres,sw1);

free(sw1);

}

}

//убираем из c_parms последнюю запятую

Reverse(c_parms,parm_tstr);

sw1=GetTail(parm_tstr,",");

strcpy(parm_tstr,sw1);

free(sw1);

Reverse(parm_tstr,c_parms);

//анализируем, все ли корректно

if (flag_not_OK > 0)

{

*c_str=0;

strcat(c_str,"\n/*ERR: Incorrect identifier(s) or parameter(s) in the function*/");

errors_counter++;

Output_C_lines(c_str);

}

//делаем эквивалентную строку на C

*c_str=0;

strcat(c_str,function_type);

strcat(c_str," ");

strcat(c_str,function_name);

strcat(c_str," (");

strcat(c_str,c_parms);

strcat(c_str,") ");

//printf("c_str:<%s>\n",c_str);

Output_C_lines(c_str);

*c_str=0;

strcat(c_str," {");

Output_C_lines(c_str);

function_flag=1;

other_oper_flag=0;

}

return;

}//proc

/*=========================================================================*/

void Analyze_GoTo(char *str1, char *str2)

//подрограмма на анализ оператора goto

//str1=исходное выражение

//str2=выходное выражение

{

fid=17;

char sw1[buf_len];

char sw2[buf_len];

char c_str[buf_len];

*c_str=0;

strcat(c_str,str1);

strcat(c_str," ");

strcat(c_str,str2);

strcat(c_str," ");

Output_C_lines(c_str);

return;

}//proc

/*=========================================================================*/

void Analyze_Assignment(char *str1, char *str2)

//подрограмма на анализ оператора присваивания ':=' and others

//str1=исходное выражение

//str2=выходное выражение

{

fid=18;

char sw1[buf_len];

char sw2[buf_len];

char temp_str[buf_len];

char c_str[buf_len];

char *tsw1;

char *swork1;//строки для GetHead и GetTail

char *swork2;

char left_side[buf_len];

char right_side[buf_len];

int flag_ok=0;//признак правильности присваивания

int pasgn; //позиция оператора присваивания

*c_str=0;

*left_side=0;

*right_side=0;

Replace(str1," ","",sw1);

strcpy(str1,sw1);

Replace(str2," ","",sw2);

strcpy(str2,sw2);

*sw1=0;

*sw2=0;

//это оператор присваивания?

pasgn=pos(str1,":=");

if (pasgn>0) //это оператор присваивания

{

//printf("\ncorrect asgn left=<%s> right=<%s>",str1,str2);

//формируем общую строку

strcpy(sw1,str1);

strcat(sw1,str2);

Replace(sw1," ","",sw2);

strcpy(sw1,sw2);

//выделяем левую сторону

swork1=GetHead(sw1,":=");

strcpy(left_side,swork1);

free(swork1);

//выделяем правую сторону

swork2=GetTail(sw1,":=");

strcpy(right_side,swork2);

free(swork2);

swork2=GetHead(right_side,";");

strcpy(right_side,swork2);

free(swork2);

//printf("\nre-asgn left=<%s> right=<%s>",left_side,right_side);

//анализ левой части на идентификатор

strcpy(str_expr,left_side);

s_cur=str_expr;

if(Analyze_Identify()==false)

{

flag_ok=0;

}

else

{

flag_ok++;

}

//анализ правой части присваивания

strcpy(str_expr,right_side);

s_cur=str_expr;

if(Analyze_Ae2()==false)

{

flag_ok=0;

}

else

{

flag_ok++;

}

if(flag_ok==2)//обе части верны

{

strcat(c_str,left_side);

strcat(c_str,":=");

strcat(c_str,right_side);

strcat(c_str,";");

strcpy(sw1,c_str);

Reformat_Logical_Expression(sw1,sw2);

strcpy(c_str,sw2);

Reformat_Other_Operators(c_str,sw1);

strcpy(c_str,sw1);

}

else //одна из частей неверна

{

strcat(c_str,left_side);

strcat(c_str,":=");

strcat(c_str,right_side);

strcat(c_str,";");

strcat(c_str,"/*ERR:Error in assignment*/");

errors_counter++;

}

}

else //это не оператор присваивания

{

//printf("\nincorr asgn left=<%s> right=<%s>",str1,str2);

strcat(c_str,str1);

strcat(c_str,str2);

strcpy(sw1,c_str);

Reformat_Logical_Expression(sw1,sw2);

strcpy(c_str,sw2);

Reformat_Other_Operators(c_str,sw1);

strcpy(c_str,sw1);

}

fid=18;

Output_C_lines(c_str);

//gets(anykey);

return;

}//proc

/*=========================================================================*/

void Analyze_Uses(char *str1, char *str2)

//подпрограмма анализа ключевого слова 'uses'

//str1=исходное выражение

//str2=выходное выражение

{

fid=19;

char *work_str;

char str_buf_work[buf_len];

char c_str[buf_len];

//устанавливаем флажок ожидаемых операций other_oper_flag в 1.

//этот флажок анализируется в функции Analyze_Other_Operator

other_oper_flag=1; //означает: вошли в секцию Uses

//write as comment

*c_str=0;

strcat(c_str, "/*<USES>*/");

Output_C_lines(c_str);

//возвращаем концевик в начало str_buf

*str_buf_work=0;

strcat(str_buf_work,str2);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

return;

}//proc

/*=========================================================================*/

void Analyze_Uses_Oper(char *str1, char *str2)

//!!

//str1=исходное выражение

//str2=выходное выражение

{

fid=20;

char *work_str;

char str_buf_work[buf_len];

char c_str[buf_len];

//writing out as comments

*c_str=0;

strcat(c_str,"/*<uses> ");

strcat(c_str,str1);

strcat(c_str,str2);

strcat(c_str,"*/");

Output_C_lines(c_str);

return;

}

/*=========================================================================*/

void Analyze_Const(char *str1, char *str2)

//подпрограмма анализа ключевого слова 'Const'

//str1=исходное выражение

//str2=выходное выражение

{

fid=21;

char *work_str;

char str_buf_work[buf_len];

char c_str[buf_len];

//устанавливаем флажок ожидаемых операций other_oper_flag в 1.

//этот флажок анализируется в функции Analyze_Other_Operator

other_oper_flag=2; //означает: вошли в секцию Const

//writing comment

*c_str=0;

strcat(c_str, "/*<CONST>*/");

Output_C_lines(c_str);

//возвращаем концевик в начало str_buf

*str_buf_work=0;

strcat(str_buf_work,str2);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

return;

}//proc

/*=========================================================================*/

void Analyze_Const_Oper(char *str1, char *str2)

//!!

//str1=исходное выражение

//str2=выходное выражение

{

fid=22;

char sw1[buf_len];

char sw2[buf_len];

char *sw;

char const_name[buf_len];

char const_val[buf_len];

char tmp[buf_len];

char c_str[buf_len];

*sw1=0;

*sw2=0;

//printf("<str1:%s>\n",str1);

//printf("<str2:%s>\n",str2);

//extracting the const name

*const_name=0;

sw=GetHead(str1,"=");

strcpy(const_name,sw);

free(sw);

Replace(const_name," ","",tmp);

strcpy(const_name,tmp);

//extracting the const value

sw=GetTail(str1,"=");

strcpy(const_val,sw);

free(sw);

Replace(const_val," ","",tmp);

strcpy(const_val,tmp);

s_cur=const_name;

if(Analyze_Identify()==true)

{

//writing out constants

*c_str=0;

strcat(c_str,"#define ");

strcat(c_str,const_name);

strcat(c_str," ");

strcat(c_str,const_val);

//printf("<c_str:>%s",c_str);

Output_C_lines(c_str);

}

else

{

*c_str=0;

strcat(c_str,str1);

strcat(c_str," ");

strcat(c_str,str2);

strcat(c_str,"/*ERR: Error in logical expression*/");

errors_counter++;

Output_C_lines(c_str);

}

return;

}

/*=========================================================================*/

void Analyze_Label(char *str1, char *str2)

//подпрограмма анализа ключевого слова 'Label'

//str1=исходное выражение

//str2=выходное выражение

{

fid=23;

char *work_str;

char str_buf_work[buf_len];

char c_str[buf_len];

//устанавливаем флажок ожидаемых операций other_oper_flag в 1.

//этот флажок анализируется в функции Analyze_Other_Operator

other_oper_flag=3; //означает: вошли в секцию Label

//write as comment

*c_str=0;

strcat(c_str, "/*<LABEL>*/");

Output_C_lines(c_str);

//возвращаем концевик в начало str_buf

*str_buf_work=0;

strcat(str_buf_work,str2);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

return;

}//proc

/*=========================================================================*/

void Analyze_Label_Oper(char *str1, char *str2)

//!!

//str1=исходное выражение

//str2=выходное выражение

{

fid=24;

char *work_str;

char str_buf_work[buf_len];

char c_str[buf_len];

//writing out as comments

*c_str=0;

strcat(c_str,"/*<label> ");

strcat(c_str,str1);

strcat(c_str,str2);

strcat(c_str,"*/");

Output_C_lines(c_str);

return;

}

/*=========================================================================*/

void Analyze_Var(char *str1, char *str2)

//подпрограмма анализа ключевого слова 'Var'

//str1=исходное выражение

//str2=выходное выражение

{

fid=25;

char *work_str;

char str_buf_work[buf_len];

char c_str[buf_len];

//устанавливаем флажок ожидаемых операций other_oper_flag в 1.

//этот флажок анализируется в функции Analyze_Other_Operator

other_oper_flag=4; //означает: вошли в секцию Var

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

*c_str=0;

strcat(c_str, "/*<VAR>*/");

Output_C_lines(c_str);

//возвращаем концевик в начало str_buf

*str_buf_work=0;

strcat(str_buf_work,str2);

strcat(str_buf_work,str_buf);

strcpy(str_buf,str_buf_work);

return;

}//proc

/*=========================================================================*/

void Analyze_Var_Oper(char *str1, char *str2)

//!!

//str1=исходное выражение

//str2=выходное выражение

{

fid=26;

char *work_str;

char str_buf_work[buf_len];

char c_str[buf_len];

char sw1[buf_len];

char sw2[buf_len];

char *tsw1;

char *tsw2;

char varoper[buf_len];

char varoper_up[buf_len];

char varname[buf_len];

char vararray[buf_len];

char vararray_tail[buf_len];

char vartype[buf_len_short];

char vartype_init[buf_len_short];

char seps[buf_len_short];

char arr_low_bound[buf_len_short];

char arr_high_bound[buf_len_short];

char arr_sz[buf_len_short];

int more_arr_desc;

int posnspace;

int string_size;

char string_size_char[buf_len_short];

int pas_lb_val;

int pas_hb_val;

int c_arr_size;

strcpy(seps," ");

//printf("var_oper: str1: <%s> str2: <%s>\n",str1,str2);

//gets(anykey);

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

//forming the whole asgn expression

*sw1=0;

strcat(sw1," ");

strcat(sw1,str1);

strcat(sw1," ");

strcat(sw1,str2);

strcat(sw1," ");

Replace(sw1,";"," ",sw2);strcpy(sw1,sw2);

Replace(sw1,":"," : ",sw2);strcpy(sw1,sw2);

Replace(sw1," "," ",sw2);strcpy(sw1,sw2);

strcpy(varoper,sw2);

strcpy(varoper_up,strupr(sw2));

//extracting the variable name

tsw1=GetHead(varoper,":");

strcpy(varname,tsw1);

free(tsw1);

LTrim(varname,seps,sw1);

RTrim(sw1,seps,sw2);

strcpy(varname,sw2);

//analyze varname on identify

Replace(varname," ","",str_expr);

strcpy(varname,str_expr);

s_cur=varname;

if(Analyze_Identify()==true)

{}

else

{

*c_str=0;

strcat(c_str,str1);

strcat(c_str," ");

strcat(c_str,str2);

strcat(c_str,"/*ERR: Error in logical expression*/");

errors_counter++;

Output_C_lines(c_str);

}

//printf("var_name: <%s>\n",varname);

//gets(anykey);

//extracting the variable array descriptor and type

tsw1=GetTail(varoper_up,"ARRAY");

strcpy(sw1,tsw1);

free(tsw1);

tsw1=GetHead(sw1,"OF");

strcpy(sw1,tsw1);

free(tsw1);

strcpy(vararray,sw1);

//extracting the variable type

strcpy(sw1,varoper);

LTrim(sw1,seps,sw2);strcpy(sw1,sw2);

RTrim(sw1,seps,sw2);strcpy(sw1,sw2);

Reverse(sw1,sw2);

tsw1=GetHead(sw2," ");

strcpy(sw1,tsw1);

free(tsw1);

Reverse(sw1,sw2);

strcpy(vartype_init,sw2);

strcpy(vartype,strupr(sw2));

//printf("varname:<%s> vararray:<%s> vartype:<%s>\n",varname,vararray,vartype);

*c_str=0;

//analyzing var type

string_size=-1;//not a string

if (strcmp(vartype,"INTEGER")==0)

{

strcat(c_str,"int");

}

else if (pos(vartype,"STRING")>-1)

{

strcat(c_str,"char");

string_size=0; //this is a string

strcpy(sw1,vartype_init);

tsw1=GetHead(sw1,"]");

strcpy(sw1,tsw1);

free(tsw1);

tsw1=GetTail(sw1,"[");

strcpy(sw1,tsw1);

free(tsw1);

if (strlen(sw1) > 0) //string size is specified

{

LTrim(sw1,seps,sw2);strcpy(sw1,sw2);

RTrim(sw1,seps,sw2);strcpy(sw1,sw2);

strcpy(string_size_char,sw1);

string_size=1;

}

}

else

{

strcat(c_str,"illegal");

}

strcat(c_str," ");

//adding var name

strcat(c_str,varname);

//printf("after var name: <%s>\n",c_str);

//was it a string with size?

if (string_size>0)

{

strcat(c_str,"[");

strcat(c_str,string_size_char);

strcat(c_str,"]");

}

//parsing the array descriptor

more_arr_desc=1;

if (strlen(vararray)==0)

{

more_arr_desc=0;

}

while (more_arr_desc==1)

{

tsw1=GetHead(vararray,"]");

strcpy(sw1,tsw1);

free(tsw1);

//printf("vararray1: <%s>\n",vararray);

tsw2=GetTail(vararray,"]");

strcpy(vararray_tail,tsw2);

free(tsw2);

//printf("vararray_tail1: <%s>\n",vararray_tail);

//gets(anykey);

tsw1=GetTail(sw1,"[");

strcpy(sw1,tsw1);

free(tsw1);

//printf("vararray_pas: <%s>\n",sw1);

if (strlen(sw1)==0)

{

more_arr_desc=0;

}

else

{

strcpy(arr_sz,sw1);

//low boundary

tsw1=GetHead(arr_sz,"..");

strcpy(sw1,tsw1);

free(tsw1);

LTrim(sw1,seps,sw2);strcpy(sw1,sw2);

RTrim(sw1,seps,sw2);strcpy(sw1,sw2);

pas_lb_val=atoi(sw1);

//high boundary

tsw1=GetTail(arr_sz,"..");

strcpy(sw1,tsw1);

free(tsw1);

LTrim(sw1,seps,sw2);strcpy(sw1,sw2);

RTrim(sw1,seps,sw2);strcpy(sw1,sw2);

pas_hb_val=atoi(sw1);

//C array size

c_arr_size = abs(pas_hb_val - pas_lb_val + 1);

//adding C definition of the array

itoa(c_arr_size, sw2, 10);

strcat(c_str,"[");

strcat(c_str,sw2);

strcat(c_str,"]");

strcpy(vararray,vararray_tail);//deleting the arr descr from vararray

//printf("c_str: <%s> vararray: <%s>\n",c_str,vararray);

//gets(anykey);

}

}

strcat(c_str,";");

//writing out

Output_C_lines(c_str);

return;

}

/*=========================================================================*/

void Pas_to_C(char* pas_str, char* c_str)

//подпрограмма анализа предложения на Паскале на ключевые слова и вызов

//необходимых подпрограмм обработки ключевых слов

{

fid=27;

char sw1[buf_len];

char sw2[buf_len];

char keyw_name0[buf_len]; //initial operator name

char keyw_name[buf_len]; //uppercased operator name

char keyw_list[buf_len];

char c_work[buf_len];

char c_work_work[buf_len];

char *sw;

int res;

strcpy(sw1,pas_str);

ClearOffBlanks(sw1,sw2); //обрабатываем пробелы

strcpy(c_work,sw2);

//анализ строки на ключевое слово

//выделяем само ключевое слово

strcpy(sw1,c_work);

sw=GetTail(sw1," ");

strcpy(sw1,sw);

free(sw);

//выделяем список параметров кл.слова (концевик)

sw=GetTail(sw1," ");

strcpy(keyw_list,sw);

free(sw);

//формируем для анализа ключевое слово в верхнем регистре

sw=GetHead(sw1," "); //ключевое слово - это первое слово (до пробела)

strcpy(keyw_name0,sw); //исходное ключевое слово

strcpy(keyw_name,sw); //ключевое словов верхнем регистре (загл.буквы)

free(sw);

if (strcmp(strupr(keyw_name),"IF")==0)

{

//анализ оп-ра "if"

Analyze_If(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"THEN")==0)

{

//анализ оп-ра "then"

Analyze_Then(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"ELSE")==0)

{

//анализ оп-ра "else"

Analyze_Else(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"BEGIN")==0)

{

//анализ оп-ра "begin"

Analyze_Begin(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"REPEAT")==0)

{

//анализ оп-ра "repeat"

Analyze_Repeat(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"UNTIL")==0)

{

//анализ оп-ра "until"

Analyze_Until(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"END")==0)

{

//анализ оп-ра "end"

Analyze_End(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"FUNCTION")==0)

{

//анализ оп-ра "function"

Analyze_Function(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"VAR")==0)

{

//анализ оп-ра "var"

Analyze_Var(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"CONST")==0)

{

//анализ оп-ра "const"

Analyze_Const(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"USES")==0)

{

//анализ оп-ра "uses"

Analyze_Uses(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"LABEL")==0)

{

//анализ оп-ра "label"

Analyze_Label(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"END.")==0)

{

//анализ оп-ра "end."

Analyze_End_Prog(keyw_name0,keyw_list);

}

else if (strcmp(strupr(keyw_name),"GOTO")==0)

{

//анализ оп-ра "goto"

Analyze_GoTo(keyw_name0,keyw_list);

}

else

{

//other

Analyze_Other_Operator(keyw_name0,keyw_list);

}

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

//исходного текста на Паскале как комментария на С

*c_work_work=0;

strcat(c_work_work,"{Pascal:<");

strcat(c_work_work,c_work);

strcat(c_work_work,"}");

strcpy(c_work,c_work_work);

//Output_C_lines(c_work);

}//proc

/*=========================================================================*/

int pos(char *str1, char *str2)

//функция pos находит позицию строки str2 внутри строки str1

{

char* strFind=strstr(str1,str2);

if(strFind==NULL)

{

return -1;

}

else

{

return strFind-str1;

}

}//proc

/*=================================================*/

void Replace(char* str1, char* str2, char* str3, char* str4)

{

//подпрограмма замены подстроки в строке

//str1-строка, в которой осуществляется перестановка

//str2-часть строки str1, которую нужно заменить на str3

//str3-строка, заменяющая все вхождения str2 в str1

//str4-полностью преобразованная строка

int str1_pos;

int str1_len;

int str2_pos;

int str2_len;

int str3_len;

str1_len = strlen(str1);

str2_len = strlen(str2);

str3_len = strlen(str2);

*str4=0;

if (str1_len==0)

{//если str1 - пустая строка, то возвращается пустая строка str4

return;

}

else if (str2_len==0)

{//если str2 - пустая строка, то строка str4 равна str1

strcpy(str4,str1);

return;

}

else

{

for (str1_pos=0;str1_pos<str1_len;str1_pos++)

{

str2_pos=pos(str1+str1_pos,str2);

if (str2_pos==0)

{

if (str3_len==0)

{//не приписываем пустую строку str3 к str4

}

else

{//приписываем строку str3 к str4

strcat(str4,str3);

str1_pos = str1_pos+str2_len-1; //перемещаемся в str1 в позицию,

} //следующую за подстрокой str2

}

else

{//приписываем текущий символ из str1 к str4

strncat(str4,str1+str1_pos,1);

}

}

}

}//proc

/*=========================================================================*/

void Reverse(char *str1, char *str2)

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

{

int n, //длина строки str

i, //счетчик

l;

n=strlen(str1);

*str2=0;

if (n<=1)

{

strcpy(str2,str1);

}

else

{

i=0;

l=n-1;

while(i<n)

{

str2[i]=str1[l];str2[i+1]='\0';

l--;i++;

}

str2[i]='\0';

}

return;

}//proc

/*=================================================*/

void LTrim(char *str1, char *seps, char *str2)

//trims left chars in string str1 (chars from seps); result is copied to str2

{

int posnspace;

posnspace=strspn(str1,seps);

strcpy(str2,str1+posnspace);

//printf("LTrim: str1:<%s>, seps:<%s>, str2:<%s>\n",str1,seps,str2);

}

/*=================================================*/

void RTrim(char *str1, char *seps, char *str2)

//trims right chars in string str1 (chars from seps); result is copied to str2

{

int posnspace;

char sw1[buf_len];

char sw2[buf_len];

Reverse(str1,sw1);

//printf("reverse in: <%s> out: <%s>\n",str1,sw1);

LTrim(sw1,seps,sw2);

Reverse(sw2,sw1);

//printf("reverse in: <%s> out: <%s>\n",sw2,sw1);

strcpy(str2,sw1);

//printf("RTrim: str1:<%s>, seps:<%s>, str2:<%s> \n",str1,seps,str2);

}

/*=================================================*/

char* GetHead(char *str1, char *str2)

//функция GetHead ищет в строке str1 строку str2.

//Если такая строка найдена, то возвращается указатель на

//динамически формируемую строку, содержащую текст из str1

//c 0-й позиции по позицию, предшествующую str2.

//Если такая строка не найдена, то возвращается указатель на

//динамически формируемую строку, содержащую пустой текст.

//Вызывающая программа должна освободить память ответной строки.

{

char *strres=NULL;

int ipos=pos(str1,str2);

if(ipos==-1)

{

strres=(char*)malloc(1);

*strres=0;

return(strres);

}

else

{

strres=(char*)malloc(ipos+1);

strncpy(strres,str1,ipos);

strres[ipos]='\0';

return strres;

}

}//proc

/*=================================================*/

//функция GetTail ищет в строке str1 строку str2.

//Если такая строка найдена, то возвращается указатель на

//динамически формируемую строку, содержащую текст из str1

//c позиции, следующей после конца str2 по последнюю позицию str1.

//Если такая строка не найдена, то возвращается указатель на

//динамически формируемую строку, содержащую пустой текст.

//Вызывающая программа должна освободить память ответной строки.

char* GetTail(char *str1, char* str2)

{

char *strres;

int istrlen=0;

int ipos=pos(str1,str2);

if(ipos==-1)

{

strres=(char*)malloc(1);

strres[0]='\0';

return strres;

}

istrlen=strlen(str1)-(ipos+strlen(str2));

strres=(char*)malloc(istrlen+1);

strres[0]='\0';

if(istrlen==0)

return strres;

strncpy(strres,str1+ipos+strlen(str2),istrlen);

strres[istrlen]='\0';

return strres;

}//proc

/*=================================================*/

void GetPaths()

{//получение путей доступа и имен исходного и выходного файлов

fid=28;

int RC=0;

int in_path_ok=0;

int out_path_ok=0;

char pas_name [buf_len];

char c_name [buf_len];

char in_path [buf_len];

char out_path [buf_len];

char sw1 [buf_len];

char sw2 [buf_len];

char *swork1; //рабочие строки (GetHead, GetTail)

char *swork2;

//входной файл

while (in_path_ok == 0)

{

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

gets(in_path);

*sw1=0;*sw2=0;

strcpy(sw1,in_path);

Reverse(sw1,sw2);

// swork1=GetHead(sw2,"\");

// strcpy(sw2,swork1);

// free(swork1);

Reverse(sw2,pas_name);

// free (swork1);

//проверка правильности ввода входного файла

if (strlen(pas_name)==0)

{//пустой путь

printf("Неверный путь: <%s>\n",in_path);

anomaly_counter++;

}

else

{

swork1=GetHead(pas_name,".pas");

strcpy(sw2,swork1);

free(swork1);

if (strlen(sw2)==0)

{//это не файл .pas

printf("Имя файла :<%s> задано некорректно. Это не .pas файл.\n",pas_name);

anomaly_counter++;

}

else

{

file_in=fopen(in_path, "r"); //открываем файл на чтение

if(file_in==NULL)

{//ошибка открытия файла

printf("Ошибка открытия входного файла <%s> - файл не найден; проверьте путь.\n",in_path);

anomaly_counter++;

}

else

{

strcpy(str_in,in_path);

//printf("OK: открытиe входного input файла <%s>\n",out_path);

fclose(file_in); //закрытие файла

in_path_ok=1;

}

}

}

}

//проверка правильности ввода выходного файла

while (out_path_ok == 0)

{

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

gets(out_path);

*sw1=0;*sw2=0;

strcpy(sw1,out_path);

Reverse(sw1,sw2);

// swork1=GetHead(sw2,"\\");

// strcpy(sw2,swork1);

// free(swork1);

Reverse(sw2,c_name);

// free (swork1);

if (strlen(c_name)==0)

{//пустой путь

printf("Некорректный путь: <%s>\n",out_path);

anomaly_counter++;

}

else

{

swork1=GetHead(c_name,".c");

strcpy(sw2,swork1);

free(swork1);

if (strlen(sw2)==0)

{//это не файл .c

printf("Имя файла :<%s> задано некорректно. Это не .c файл.\n",c_name);

anomaly_counter++;

}

else

{

file_out=fopen(out_path, "w"); //открываем файл на запись

if(file_in==NULL)

{//ошибка открытия файла

printf("Ошибка открытия выходного файла %s - проверьте путь.\n",out_path);

anomaly_counter++;

}

else

{

strcpy(str_out,out_path);

strcpy(sw1,c_name);

Replace(sw1,".","_",sw2); //заменяем . на _

strcpy(c_prog_name,sw2); //формируем имя программы

//printf("OK: открытиe выходного файла %s\n",out_path);

fclose(file_out); //закрытие файла

out_path_ok=1;

}

}

}

}

return;

}

/*=========================================================================*/

int Analyze_Ae2()

//функция анализа арифметического выражения Ae2

//функция возвращает 0, если выражение соответствует приведенной диаграмме

//функция возвращает 1, если выражение не соответствует приведенной диаграмме

{

if(ZNAK)

{

s_cur++;

}

while(false)

{

if(Analyze_Slag())

{

return false;

}

if(ZNAK)

{

s_cur++;

}

else

{

return true;

}

}

}//proc

/*=========================================================================*/

int Analyze_Slag()

//функция анализа слагаемого

{

while(false)

{

if(Analyze_Mnog())

{

return false;

}

if(*s_cur=='*' || *s_cur=='/')

{

s_cur++;

}

else

{

return true;

}

}

}//proc

/*=========================================================================*/

int Analyze_Mnog()

//функция анализа множителя

{

if(*s_cur=='(')

{

s_cur++;

if(Analyze_Ae2()) return false;

if(*s_cur!=')') return false;

else s_cur++;

}

else

{

if(Analyze_Perem() && Analyze_Const()) return false;

}

return true;

}//proc

/*=========================================================================*/

int Analyze_Perem()

{

if(Analyze_Identify()) return false;

if(*s_cur=='[')

{

do

{

s_cur++;

if(Analyze_Ae2()) return false;

}

while(*s_cur==',');

if(*s_cur!=']') return false;

s_cur++;

}

return true;

}//proc

/*=========================================================================*/

int Analyze_Identify()

//функция анализа идентификатора

{

if(isalpha(*s_cur)==0)

{

return false;

}

while(isalpha(*s_cur) || isdigit(*s_cur))

{

s_cur++;

}

return true;

}//proc

/*=========================================================================*/

int Analyze_Const()

//функция анализа константы без знака

{

int flag=false; //отвечает за наличие цифр в мантиссе

while(isdigit(*s_cur))

{

flag=0;

s_cur++;

}

if(*s_cur=='.')

{

s_cur++;

while(isdigit(*s_cur))

{

flag=0;

s_cur++;

}

}

if(flag)

{

return false;

}

if(*s_cur=='E')

{

s_cur++;

if(ZNAK)

{

s_cur++;

}

if(!isdigit(*s_cur))

{

return false;

}

while(isdigit(*s_cur))

{

s_cur++;

}

}

return true;

}//proc

/*=========================================================================*/

int Analyze_Symb_Le1()

//функция анализа символа между двумя Ae2

{

//1-й случай(начало - символ "=")

if(*s_cur=='=')

{

s_cur++;

return true;

}

//2-й случай(начало - символ "<")

if(*s_cur=='<')

{

s_cur++;

if(*s_cur=='=')

{

s_cur++;

return true;

}

if(*s_cur=='>')

{

s_cur++;

return true;

}

return true;

}

//3-й случай(начало - символ ">")

if(*s_cur=='>')

{

s_cur++;

if(*s_cur=='=')

{

s_cur++;

return true;

}

return true;

}

return false;

}//proc

/*=========================================================================*/

int Analyze_Le1()

//функция анализа анализа логического выражения Le1(на входе-Ae2)

{

if(Analyze_Ae2()==false)

{

return false;//Ae2 неверно

}

else

{

if(Analyze_Symb_Le1()==true && *s_cur!='\x0')

{

if(Analyze_Ae2()==true && *s_cur=='\x0')

{

return true;

}

}

return false;

}

return false;

}//proc

/*=========================================================================*/

/*=====================================================================*/

/*=====================================================================*/

/*=====================================================================*/

void main()

{

char sw1[buf_len];

char sw2[buf_len];

char *pas_str; //найденное оконченное предложение на Pascal'е

char *c_str; //часть предложения на C

char *swork1; //рабочие строки

char *swork2;

int more_pas_in_buf; //признак наличия ';' в буфере обработки

int pos_sep; //позиция символа ';'

int comments_flag; //флажок обработки комментария (0 или 1)

char comment_beg[buf_len]="{";

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

char comment_end[buf_len]="}";

//строка - признак конца комментария в Паскале

int pos_comment; //позиция комментария в исходнои тексте

int pos_c; //текущая позиция в исходной строке

int pos_comment_beg;//позиция начала комментария от текущей позиции

int pos_comment_end;//позиция конца комментария от текущей позиции

int last_comment_beg; //позиция последнего открытого комментария

clrscr(); //чистим экран

//*str_in=0;

//*str_out=0;

//GetPaths(); //получаем пути исходного (str_in) и выходного (str_out) файлов

fid=29;

strcpy(str_in,"D:\\file_in2.pas");

strcpy(str_out,"D:\\file_out.c");

file_in=fopen(str_in, "r"); //открываем файл на чтение

file_out=fopen(str_out, "w"); //открываем файл на запись

Analyze_Program_Start(); //выводим

//очистка буфера накопления чистого текста на Паскале

*str_buf=0;

//установка флажка обработки комментария

// 0=если комментарии еще найдены или уже обработаны (удалены)

// 1=в процессе накопления текста комментариев в буфер комментариев

comments_flag=0;

*comments_buf=0; //очистка буфера комменариев

*non_comments_buf=0; //очистка буфера Паскаля

while(fgets(str_temp, buf_len, file_in)) //чтение исходных строк

{

count_source_lines++;

//обработка комментариев

strcpy(str_temp_nocomments,str_temp);//в str_temp_nocomments - весь текст

//strcpy(sw1,str_temp); //замена коментариев '{' и '}'

//Replace(sw1,"{","/*",sw2);//на '/*' и '*/' соответственно

//strcpy(sw1,sw2);

//Replace(sw1,"}","*/",sw2);

//strcpy(str_temp,sw2);

for (pos_comment=0;pos_comment<strlen(str_temp_nocomments);pos_comment++)

{//выделение в str_temp_nocomments комментариев

pos_comment_beg=pos(str_temp_nocomments+pos_comment,comment_beg);

pos_comment_end=pos(str_temp_nocomments+pos_comment,comment_end);

if ((comments_flag==0) && (pos_comment_beg==0))

{//нашли начало комментария

strcpy(comments_buf,comment_beg);

last_comment_beg=pos_comment;

comments_flag=1;//теперь обрабатваем комментарии

}

else if ((comments_flag==1) && (pos_comment_end==0))

{//нашли конец комментария

strcat(comments_buf,comment_end);

//преобразуем комментарии { и } на '/*' и '*/' соответственно

strcpy(sw1,comments_buf);

Replace(sw1,"{","/*",sw2);

strcpy(sw1,sw2);

Replace(sw1,"}","*/",sw2);

strcpy(comments_buf,sw2);

Output_C_lines(comments_buf);//выводим накопленный

count_out_lines++; //комментарий

comments_flag=0; //снова ищем начало комментария

*comments_buf=0; //очищаем буфер комментария

}

else

{//либо мы внутри комментария и копим его,

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

if (comments_flag==1)

{//мы внутри комментария - накапливаем текст комментария

strncat(comments_buf,str_temp_nocomments+pos_comment,1);

}

else

{//мы вне комментария - накапливаем текст Паскаля

strncat(non_comments_buf,str_temp_nocomments+pos_comment,1);

}

}

}

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

strcat(str_buf,non_comments_buf);

*non_comments_buf=0; //и очищаем буфер Паскаля

//обрабатываем буфер накопления Паскаля

more_pas_in_buf=1;//признак: в буфере накопления Паскаля еще есть текст

while(more_pas_in_buf==1)

{

//обработка предложения Паскаля (текст, оканчивающийся на ";")

pos_sep=pos(str_buf,str_sep);//ищем в строке ';'

if(pos_sep==-1)

{//если нет ";" то добавляем пробел и завершаем поиск

strcat(str_buf," ");

more_pas_in_buf=0;

}

else

{//обработка первого из находящихся в буфере предложения

swork1=GetHead(str_buf,str_sep);//выделяем

strcpy(pas_str,swork1); //предложение

strcat(pas_str,";"); //на Паскале

free (swork1);

//выделяем концевик буфера

swork2=GetTail(str_buf,str_sep);//выбираем остальные предложения

strcpy(str_buf,swork2);//и возвращаем их в начало буфера

free (swork2);

//далее вызываем п/п анализа предложения на Паскале

//и получаем эквивалентное предложение на языке C

Pas_to_C(pas_str, c_str);

}

}

}

fid=30;

strcpy(pas_str,str_buf); //обработка остатка буфера после

Pas_to_C(pas_str, c_str);//чтения всего исходного файла

fclose(file_in); //закрытие входного файла

fclose(file_out);//закрытие в ходного файла

if (errors_counter > 0)

{

printf("Количество ошибок: %d\n",errors_counter);

}

else

{

printf("Обработан текст программы на языке Pascal в файле <%s>\n",str_in);

printf("Сформирован текст программы на языке C в файле <%s>\n",str_out);

printf("Количество входных строк: %d\n",count_source_lines);

printf("Количество выходных строк: %d\n",count_out_lines);

printf("Ошибок не обнаружено\n");

if (anomaly_counter == 0)

{

printf("Аномалий не обнаружено\n");

}

else

{

printf("Количество аномалий: %d\n",anomaly_counter);

}

}

getch();

}

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