- •Курсова робота
- •Виконав ст. Гр. Кі-35:
- •Завдання на курсову роботу:
- •Анотація
- •1. Огляд методів та способів проектування трансляторів 7
- •Огляд методів та способів проектування трансляторів
- •Формальний опис вхідної мови програмування
- •Деталізований опис вхідної мови в термінах розширеної нотації Бекуса-Наура(Backus/NaurForm - bnf).
- •2.2.Термінальні символи та ключові слова
- •Розробка транслятора вхідної мови програмування
- •Вибір технології програмування
- •Проектування таблиць транслятора
- •Розробка лексичного аналізатора
- •Опис лексичного аналізатора
- •3.3.2. Розробка граф-схеми алгоритму
- •Розробка синтаксичного та семантичного аналізатора
- •Опис синтаксичного аналізатора
- •Повне дерево граматичного розбору
- •Розробка генератора коду
- •Опис генератора коду
- •Опис програми(в тому числі граф-схем)
- •Опис інтерфейсу та інструкція користувачеві
- •Відлагодження та тестування програми
- •Виявлення лексичних помилок.
- •Список літератури
- •Додаток а. Лістингпрограми.
- •Додаток б. Приклад програми із лексичними та синтаксичними помилками та текст файлу з повідомленням про помилки.
- •Додаток в. Приклад коректної програми та результат її виконання.
- •Додаток г. Граф-схема алгоритму виконання програми через використання функцій.
Список літератури
В.С. Проценко, П.Й. Чаленко, А.Б.Ставровський “Техніка програмування мовою Сі”.-Київ “Либідь”, 1993. – 224с.
Б.Керниган, Д.Ритчи “Язык программирования Си”. – Москва “Финансы и статистика”, 1992. – 271с.
Додаток а. Лістингпрограми.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
enum LexemType //
{ program_, //Початок програми
variable_, //Блок оголошення змінних
int_, // integer16_t-тип
start_, //Початок блоку
stop_, //Кінець блоку
input_, //Оператор вводу
output_, //Оператор виводу
if_, //
then_, //
else_, //
newval_, // :=
add_, //
sub_, //
mul_, //
div_, //
mod_, //
equ_, //
notequ_, //
le_, //
ge_, //
not_, //
and_, //
or_, //
eof_, //
EndGroup_, // ;
komma_, // ,
ident_,
number_,
LeftBraket_, // (
RightBraket_, // )
unknown_
};
typedef struct Lexem
{
char name[50];
int value;
LexemType type;
int line;
}Lexema;
typedef struct Ident
{
char name[50];
int value;
}Identifier;
typedef struct L //Структура-реєстр в якій зберігаються всі дані програми
{
Lexema LexArray[1000]; //Таблиця лексем
int length; //
Identifier IdTable[50]; //Таблиця ідентифікаторів
int idnum; //
int PFExpr[200]; //Буфер для виразу в постфіксній формі
}Data;
Data Reg;
typedef struct Stacks
{
int st[200];
int top;
}StackType;
typedef class stack
{
public:
StackType S;
void Init(StackType* s)
{
s->top = -1;
}
void Push(int i, StackType* s)
{
if(IsFull(s))
{
puts("Stack error (is full)");
exit(0);
}
else
{
++s->top;
s->st[s->top] = i;
}
}
int Pop(StackType* s)
{
int i;
if(IsEmpty(s))
{
puts("Stack error (is empty)");
exit(0);
}
else
{
i = s->st[s->top];
--s->top;
}
return i;
}
bool IsEmpty(StackType* s)
{
if(s->top == -1)
{
return true;
}
else
{
return false;
}
}
bool IsFull(StackType* s)
{
if(s->top == 199)return true;
else return false;
}
void prints(StackType s)
{
int i=0;
for(;i<10;++i)
{
printf("%d_",s.st[i]);
}
}
}Stack;
Stack s;
Stack if_s;
Stack start_s;
int Balans(int, LexemType, LexemType, LexemType);
void BeginASMFile();
void BeginCodeSegm();
void CheckPresentInputOutput();
void CodeGenerator(FILE*);
int ConvertToPostfixForm(int);
int FindErrors();
void GenASMCode(const char *, FILE*);
//Lexema* GetLexema(FILE*);
bool IsElsePresent(int);
int IsExpression(int, FILE*);
bool IsOperation(LexemType);
int LexicalAnalyze(FILE*);
void MakeLexOutFile();
void PrintData(FILE*);
void PrintCode(FILE*);
//void PrintCorrectFPU(FILE*);
void PrintAND(FILE*);
void PrintOR(FILE*);
void PrintNOT(FILE*);
void PrintEQ(FILE*);
void PrintGE(FILE*);
void PrintLE(FILE*);
void PrintMOD(FILE*);
void PrintEnding(FILE*);
void PrintInput(FILE*);
void PrintOutput(FILE*);
bool Prioritet(LexemType,StackType);
bool IsPresentInput, IsPresentOutput;
char InputFileName[15], OutFileName[12];
FILE *fin, *fout;
int Error_num;
Lexema* GetLexema(FILE* f)
{
char ch,buf[50];
Lexema* rez;
static int line=1;
rez = (Lexema*)calloc(1,sizeof(Lexema));
for (;;)
{
ch = getc(f);
if (ch=='\n') line++;
else if (ch==EOF)
{
strncpy(rez->name,"EOF",4);
rez->type=eof_;
rez->value=0;
rez->line=line;
break;
}
else if (ch == '@')
{
char c = getc(f);
if (c == '@')
{
while (getc(f) != '\n');
}
}
else if (ch=='(')
{
strncpy(rez->name,"(",2);
rez->type=LeftBraket_;
rez->value=0;
rez->line=line;
break;
}
else if (ch==')')
{
strncpy(rez->name,")",2);
rez->type=RightBraket_;
rez->value=0;
rez->line=line;
break;
}
else if (ch==';')
{
strncpy(rez->name,";",2);
rez->type=EndGroup_;
rez->value=0;
rez->line=line;
break;
}
else if (ch=='+')
{
strncpy(rez->name,"+",2);
rez->type=add_;
rez->value=0;
rez->line=line;
break;
}
else if (ch==',')
{
strncpy(rez->name,",",2);
rez->type=komma_;
rez->value=0;
rez->line=line;
break;
}
else if (ch=='*')
{
strncpy(rez->name,"*",2);
rez->type=mul_;
rez->value=0;
rez->line=line;
break;
}
else if (ch=='%')
{
strncpy(rez->name,"%",2);
rez->type=mod_;
rez->value=0;
rez->line=line;
break;
}
else if (ch=='-')
{
strncpy(rez->name,"-",2);
rez->type=sub_;
rez->value=0;
rez->line=line;
break;
}
else if (ch==':')
{
char c;
c=getc(f);
if (c=='=')
{
strncpy(rez->name,":=",3);
rez->type=newval_;
rez->value=0;
rez->line=line;
break;
}
}
else if (ch=='=')
{
char c;
c=getc(f);
if (c=='=')
{
strncpy(rez->name,"==",3);
rez->type=equ_;
rez->value=0;
rez->line=line;
break;
}
else
{
ungetc(c,f);
strncpy(rez->name,"=",2);
rez->type=unknown_;
rez->value=0;
rez->line=line;
break;
}
}
else if (ch=='>')
{
char c;
c=getc(f);
if (c=='>')
{
strncpy(rez->name,">>",3);
rez->type=ge_;
rez->value=0;
rez->line=line;
break;
}
else
{
ungetc(c,f);
strncpy(rez->name,">",2);
rez->type=unknown_;
rez->value=0;
rez->line=line;
break;
}
}
else if (ch=='<')
{
char c;
c=getc(f);
if (c=='<')
{
strncpy(rez->name,"<<",3);
rez->type=le_;
rez->value=0;
rez->line=line;
break;
}
else if (c == '>')
{
strncpy(rez->name,"<>",3);
rez->type=notequ_;
rez->value=0;
rez->line=line;
break;
}
else
{
ungetc(c,f);
strncpy(rez->name,"<",2);
rez->type=unknown_;
rez->value=0;
rez->line=line;
break;
}
}
else if (ch == '_') //iндикатор
{
int cnt;
int fl ;
char l_buf[50];
l_buf[0] = ch;
for (cnt = 1;;++cnt)
{
ch=getc(f);
if ((isdigit(ch)!=0)||(isalpha(ch)!=0)) l_buf[cnt] = ch;
else break;
}
ungetc(ch,f);
l_buf[cnt] = '\0';
if (cnt <= 3)
{
strncpy(rez->name,l_buf,cnt);
rez->type=ident_;
rez->value=1;
rez->line=line;
break;
}
else {
strncpy(rez->name,l_buf,cnt);
rez->type=unknown_;
rez->value=0;
rez->line=line;
break;
}
}
else if (isalpha(ch)!=0) //Зарезервоване слово
{
int i=0, j, flag=0;
buf[0]=ch;
for (i=1;;++i)
{
ch=getc(f);
flag=0;
if ((isdigit(ch)!=0)||(isalpha(ch)!=0)||(ch=='_')) buf[i] = ch;
else break;
}
ungetc(ch,f);
buf[i] = '\0';
for (j=0;j<=i;j++)
if (isupper(buf[j])==0) {}
else
{
flag=-1;
break;
}
strncpy(rez->name,buf,i);
if ((strcmp(buf,"VARIABLE"))== 0) {rez->type = variable_;rez->line=line; break;}
else if ((strcmp(buf,"STARTPROGRAM"))== 0) {rez->type = program_;rez->line=line; break;}
else if ((strcmp(buf,"STARTBLOK"))== 0) {rez->type = start_;rez->line=line; break;}
else if ((strcmp(buf,"ENDBLOK"))== 0) {rez->type = stop_;rez->line=line; break;}
else if ((strcmp(buf,"scandata"))== 0) {rez->type = input_;rez->line=line; break;}
else if ((strcmp(buf,"printdata"))== 0) {rez->type = output_;rez->line=line; break;}
else if ((strcmp(buf,"if"))== 0) {rez->type = if_;rez->line=line; break;}
else if ((strcmp(buf,"then"))== 0) {rez->type = then_;rez->line=line; break;}
else if ((strcmp(buf,"else"))== 0) {rez->type = else_;rez->line=line; break;}
else if ((strcmp(buf,"div"))== 0) {rez->type = div_;rez->line=line; break;}
else if ((strcmp(buf,"not"))== 0) {rez->type = not_;rez->line=line; break;}
else if ((strcmp(buf,"and"))== 0) {rez->type = and_;rez->line=line; break;}
else if ((strcmp(buf,"or"))== 0) {rez->type = or_;rez->line=line; break;}
else if ((strcmp(buf,"integer16_t"))==0) {rez->type = int_;rez->line=line; break;}
else
{
strncpy(rez->name,buf,i);
rez->type=unknown_;
rez->value=0;
rez->line=line;
break;
}
rez->value=0;
rez->line=line;
}
else if (ch=='-') //відємне число
{
char c;
c = getc(f);
if(isdigit(c))
{
int i=2;
buf[0] = ch;
buf[1] = c;
for(;isdigit(ch = getc(f));++i)
{
buf[i] = ch;
}
ungetc(ch,f);
buf[i] = '\0';
strncpy(rez->name,buf,i);
rez->type = number_;
rez->value = atoi(buf);
rez->line=line;
break;
}
else
{
ungetc(c,f);
strncpy(rez->name,"-",2);
rez->type = sub_;
rez->value = 0;
rez->line=line;
break;
}
}
else if(isdigit(ch)) //додатнє число
{
int i=1;
buf[0] = ch;
for(;isdigit(ch = getc(f));++i)
{
buf[i] = ch;
}
ungetc(ch,f);
buf[i] = '\0';
strncpy(rez->name,buf,i);
rez->type = number_;
rez->value = atoi(buf);
rez->line=line;
break;
}
else if((ch!='\n')&&(ch!='\t')&&(ch!=' '))
{
char bufer[50];
char c;
int i;
bufer[0]=ch;
for (i=1;;i++)
{
c=fgetc(f);
if ((c == '\n')||(c == '\t')||(c==' ')||(c==';'))
{
if (c=='\n') {line++;break;}
else break;
}
bufer[i]=c;
}
ungetc(c,f);
bufer[i]='\0';
strncpy(rez->name,bufer,i);
rez->type=unknown_;
rez->value=0;
rez->line=line;
break;
}
}
return rez;
}
int LexicalAnalyze(FILE *fi) //повертає значення довжини масиву лексем
{
Lexema* Lex;
int i=0;
char type[50];
printf("Lexycal Analyze is running...\n");
strcpy(type,"");
do{
Lex = GetLexema(fi);
strncpy(Reg.LexArray[i].name,Lex->name,49);
Reg.LexArray[i].type = Lex->type;
Reg.LexArray[i].value = Lex->value;
Reg.LexArray[i].line = Lex->line;
++i;
}while(Lex->type != eof_);
return i;
}
void MakeLexOutFile()
{
FILE* f;
char type[50];
int i;
f = fopen("LexFile.txt","w");
fputs("Output lexem file. Results of the lexical analyze: next lexems found:\n",f);
fputs("\tName\t\tType\t\t\tValue\t\tLine\n",f);
for(i=0;i<Reg.length;++i)
{
switch(Reg.LexArray[i].type)
{
case program_ : strncpy(type,"STARTPROGRAM",13);break;
case variable_ : strncpy(type,"VARIABLE",9);break;
case int_ : strncpy(type,"integer16_t",12);break;
case start_ : strncpy(type,"STARTBLOK",10);break;
case stop_ : strncpy(type,"ENDBLOK",9);break;
case input_ : strncpy(type,"scandata",9);break;
case output_ : strncpy(type,"printdata",10);break;
case if_ : strncpy(type,"if",3);break;
case then_ : strncpy(type,"then",5);break;
case else_ : strncpy(type,"else",5);break;
case newval_ : strncpy(type,"new_value",10);break;
case add_ : strncpy(type,"add",4);break;
case sub_ : strncpy(type,"sub",4);break;
case mul_ : strncpy(type,"mul",4);break;
case div_ : strncpy(type,"div",4);break;
case mod_ : strncpy(type,"mod",4);break;
case equ_ : strncpy(type,"equal",6);break;
case notequ_ : strncpy(type,"not_equal",10);break;
case not_ : strncpy(type,"not",4);break;
case le_ : strncpy(type,"less_or_equal",14);break;
case ge_ : strncpy(type,"greater_or_equal",17);break;
case and_ : strncpy(type,"and",4);break;
case or_ : strncpy(type,"or",3);break;
case eof_ : strncpy(type,"end_of_file",12);break;
case EndGroup_ : strncpy(type,"EndGroup",9);break;
case komma_ : strncpy(type,"komma",6);break;
case ident_ : strncpy(type,"identifier",11);break;
case number_ : strncpy(type,"number",7);break;
case LeftBraket_ : strncpy(type,"Left_Braket",12);break;
case RightBraket_ : strncpy(type,"Right_Braket",13);break;
case unknown_ : strncpy(type,"unknown",11);break;
}
fprintf(f,"%d\t%s\t\t%s\t\t\t%d\t\t%d\n",i+1,Reg.LexArray[i].name,type,Reg.LexArray[i].value,Reg.LexArray[i].line);
}
printf("%d lexems found.\n", Reg.length);
}
int Balans(int nom, LexemType ends, LexemType open, LexemType close)
{
Stack ss;
int j=0,i;
i=nom;
ss.Init(&ss.S);
for (;Reg.LexArray[i].type!=ends;i++)
{
if (Reg.LexArray[i].type==open)
{
ss.Push(i,&ss.S);
}
if (Reg.LexArray[i].type==close)
{
if (ss.IsEmpty(&ss.S))
{
j=1; // Too much ')';
break;
}
else
{
ss.Pop(&ss.S);
if ((open==start_)&&(Reg.LexArray[nom-2].type==int_)&&(ss.IsEmpty(&ss.S)))
{
j=3;
break;
}
}
}
}
if (!(ss.IsEmpty(&ss.S)))
{
j=2; // ')' expected;
}
return j;
}
int FindErrors()
{
int i=0, /*jj,*/ j=1,temp=0,ValNum=0;
FILE* ef;
int Err;
int if_then_num=0, start_stop_num=0;//, r1, r2;
int Err_num=0;
ef = fopen("Errors.txt","w");
fputs("Error output file. Next errors found:\n\n",ef);
Reg.idnum=1;
if (Reg.LexArray[0].type != program_) //перевірка, чи першим словом в програмі є STARTPROGRAM
{
Err_num++;
fprintf(ef,"%d line %d: \t'STARTPROGRAM' expected! (File must begin from the keyword 'STARTPROGRAM')\n",Err_num,Reg.LexArray[0].line);
}
if (Reg.LexArray[1].type != variable_) //перевірка, чи другим словом в програмі є VARIABLE
{
Err_num++;
fprintf(ef,"%d line %d: \tVARIABLE expected!\n",Err_num,Reg.LexArray[1].line);
}
if (Reg.LexArray[1].type == variable_)
{
i=2;
if (Reg.LexArray[i].type != ident_) //перевірка, чи після VARIABLE йдуть ідентифікатори
{
Err_num++;
fprintf(ef,"line %d: \tIdentifier expected!\n",Reg.LexArray[i].line);
}
else
{
do
{
if ((Reg.LexArray[i].type==ident_)&&(Reg.LexArray[i+1].type==komma_))
{
strcpy(Reg.IdTable[Reg.idnum].name, Reg.LexArray[i].name);
Reg.idnum++;
i=i+2;
}
} while ((Reg.LexArray[i].type==ident_)&&(Reg.LexArray[i+1].type==komma_));
if ((Reg.LexArray[i].type==ident_)&&(Reg.LexArray[i+1].type==int_))
{
strcpy(Reg.IdTable[Reg.idnum].name,Reg.LexArray[i].name);
Reg.idnum++;
i=i+2;
goto label1;
}
if (Reg.LexArray[i].type!=int_)
{
if (Reg.LexArray[i].type==komma_)
{
Err_num++;
fprintf(ef,"line %d: \tToo much kommas or identifier expected!\n",Reg.LexArray[i].line);
}
else
{
Err_num++;
fprintf(ef,"line %d: \tType of VARIABLE ('integer16_t') expected!\n",Reg.LexArray[i].line);
}
}
else
{
Err_num++;
fprintf(ef,"line %d: \tToo much kommas or identifier expected!\n",Reg.LexArray[i].line);
}
}
i++;
label1:;
}
if (Reg.LexArray[i].type!=EndGroup_)
{
Err_num++;
fprintf(ef,"line %d: \t';' expected!\n",Reg.LexArray[i].line);
i++;
}
else {i++;}
if (Reg.LexArray[i].type != start_) //перевірка, чи після оголошення даних йде STARTBLOK
{
Err_num++;
fprintf(ef,"%d line %d: \tSTARTBLOK expected!\n",Err_num,Reg.LexArray[3].line);
}
if (Reg.LexArray[Reg.length-2].type!=stop_)
{
Err_num++;
fprintf(ef,"line %d: \t'ENDBLOK' expected!\n",Reg.LexArray[i].line);
}
if (Reg.LexArray[Reg.length-1].type!=eof_)
{
Err_num++;
fprintf(ef,"line %d: \tEnd of file expected!\n",Reg.LexArray[i].line);
}
for (j=0;Reg.LexArray[j].type!=start_;j++)
{}
Err=Balans(j-1,eof_,start_,stop_);
if (Err==1)
{
Err_num++;
fprintf(ef,"line %d: \tToo much 'ENDBLOK'!\n",Reg.LexArray[Reg.length-1].line);
}
if (Err==2)
{
Err_num++;
fprintf(ef,"line %d: \t'ENDBLOK' expected!\n",Reg.LexArray[Reg.length-1].line);
}
for (j=0;;j++)
{
int BraketErr;
if (Reg.LexArray[j].type==unknown_) //Пошук невідомих слів(не ідентифікаторів)
{
Err_num++;
fprintf(ef,"line %d: \tUnknown identifier!(%s)\n",Reg.LexArray[j].line,Reg.LexArray[j].name);
}
if ((Reg.LexArray[j].type==ident_)&&(Reg.LexArray[j-1].type!=variable_))
{
int k=1,flag=0;
for (k=1;k<=Reg.idnum;k++)
{
if (strcmp(Reg.LexArray[j].name,Reg.IdTable[k].name)==0)
{
flag=1;
break;
}
}
if (flag!=1)
{
Err_num++;
fprintf(ef,"line %d: \tUnknown identifier!(%s)\n",Reg.LexArray[j].line,Reg.LexArray[j].name);
}
}
if (Reg.LexArray[j].type==newval_)
{
int buf;
BraketErr = Balans(j,EndGroup_,LeftBraket_,RightBraket_);
if (BraketErr==1) //Баланс дужок після знаку =
{
Err_num++;
fprintf(ef,"line %d: \tToo much ')'!\n",Reg.LexArray[j].line);
}
if (BraketErr==2)
{
Err_num++;
fprintf(ef,"line %d: \t')' expected!\n",Reg.LexArray[j].line);
}
buf = IsExpression((j+1),ef);
Err_num=Err_num+buf;
}
if (Reg.LexArray[j].type==output_)
{
int buf, brak;
if (Reg.LexArray[j+1].type!=LeftBraket_)
{
Err_num++;
fprintf (ef,"line %d: \t'(' expected!\n",Reg.LexArray[j+1].line);
}
buf = IsExpression((j+1),ef);
Err_num=Err_num+buf;
brak = Balans(j,EndGroup_,LeftBraket_,RightBraket_);
if (brak==1)
{
Err_num++;
fprintf(ef,"line %d: \tToo much ')'!\n",Reg.LexArray[j].line);
}
if (brak==2)
{
Err_num++;
fprintf(ef,"line %d: \t')' expected!\n",Reg.LexArray[j].line);
}
}
if (Reg.LexArray[j].type==input_)
{
if (Reg.LexArray[j+1].type!=LeftBraket_)
{
Err_num++;
fprintf (ef,"line %d: \t'(' expected!\n",Reg.LexArray[j+1].line);
}
if (Reg.LexArray[j+2].type!=ident_)
{
Err_num++;
fprintf (ef,"line %d: \tIdentifier expected!\n",Reg.LexArray[j+2].line);
}
if (Reg.LexArray[j+3].type!=RightBraket_)
{
Err_num++;
fprintf (ef,"line %d: \t')' expected!\n",Reg.LexArray[j+3].line);
}
if (Reg.LexArray[j+4].type!=EndGroup_)
{
Err_num++;
fprintf (ef,"line %d: \t';' expected!\n",Reg.LexArray[j+4].line);
}
}
if (Reg.LexArray[j].type==if_) //Баланс дужок після if
{
int buf;
if (Reg.LexArray[j+1].type==LeftBraket_)
{
int temp=0;
BraketErr = Balans(j,then_,LeftBraket_,RightBraket_);
if (BraketErr==1)
{
Err_num++;
fprintf(ef,"line %d: \tToo much ')'\n!",Reg.LexArray[j].line);
}
if (BraketErr==2)
{
Err_num++;
fprintf(ef,"line %d: \t')' expected!\n",Reg.LexArray[j].line);
}
for (temp=j;Reg.LexArray[temp].type!=then_;temp++)
{}
if (Reg.LexArray[temp-1].type!=RightBraket_)
{
Err_num++;
fprintf(ef,"line %d: \t')' before 'then' expected!\n",Reg.LexArray[temp-1].line);
}
}
else
{
Err_num++;
fprintf(ef,"line %d: \t'(' expected!\n",Reg.LexArray[j+1].line);
}
buf = IsExpression((j+1),ef);
Err_num=Err_num+buf;
}
if (Reg.LexArray[j].type==then_)
{
if (Reg.LexArray[j+1].type!=start_)
{
Err_num++;
fprintf (ef,"line %d: \t'STARTBLOK' expected!\n",Reg.LexArray[j+1].line);
}
}
if (Reg.LexArray[j].type==else_)
{
if (Reg.LexArray[j+1].type!=start_)
{
Err_num++;
fprintf (ef,"line %d: \t'STARTBLOK' expected!\n",Reg.LexArray[j+1].line);
}
if (Reg.LexArray[j-1].type!=EndGroup_)
{
Err_num++;
fprintf (ef,"line %d: \t';' expected!\n",Reg.LexArray[j-1].line);
}
if (Reg.LexArray[j-2].type!=stop_)
{
Err_num++;
fprintf (ef,"line %d: \t'ENDBLOK' expected!\n",Reg.LexArray[j-2].line);
}
}
if (Reg.LexArray[j].type==start_)
{
if (Reg.LexArray[j-2].type==int_)
{
int buf;
buf=j;
do
{
buf++;
if ((Reg.LexArray[buf].type==stop_)&&(Reg.LexArray[buf+1].type!=eof_))
{
Err_num++;
fprintf(ef,"line %d: \tUnexpected end of file!\n",Reg.LexArray[buf].line);
break;
}
}
while ((Reg.LexArray[buf].type!=start_)&&(Reg.LexArray[buf].type!=eof_));
buf=Balans(j-1,eof_,start_,stop_);
if (buf==3)
{
Err_num++;
fprintf(ef,"line %d: \tUnexpected end of file!//\n",Reg.LexArray[j].line);
}
}
if (Reg.LexArray[j-1].type!=EndGroup_)
{
if (Reg.LexArray[j-1].type!=then_)
{
if (Reg.LexArray[j-1].type!=else_)
{
Err_num++;
fprintf(ef,"line %d: \tUnexpected 'STARTBLOK'!\n",Reg.LexArray[j].line);
}
}
}
}
if (Reg.LexArray[j].type==eof_) break;
}
if (Err_num==0) fprintf(ef,"No errors found.");
return Err_num;
}
int IsExpression(int i, FILE* ef)
{
int nom, error=0;
nom=i;
if ((Reg.LexArray[nom].type!=LeftBraket_)&&(Reg.LexArray[nom].type!=ident_)&&(Reg.LexArray[nom].type!=number_))
{
fprintf(ef,"line %d: \tExpression must begin from identifier, number or ')'!\n",Reg.LexArray[nom].line);
error++;
}
for (;((Reg.LexArray[nom].type!=EndGroup_)&&(Reg.LexArray[nom].type!=then_)&&(Reg.LexArray[nom].type!=else_));nom++)
{
if (Reg.LexArray[nom].type==RightBraket_)
if (!(IsOperation(Reg.LexArray[nom+1].type))&&(Reg.LexArray[nom+1].type!=EndGroup_)&&(Reg.LexArray[nom+1].type!=RightBraket_)&&(Reg.LexArray[nom+1].type!=not_)&&(Reg.LexArray[nom+1].type!=then_)&&(Reg.LexArray[nom+1].type!=else_))
{
fprintf(ef,"line %d: \tAfter ')' must be ')', operation or ';'!\n", Reg.LexArray[nom].line);
error++;
}
if(Reg.LexArray[nom].type==LeftBraket_)
{
if ((Reg.LexArray[nom+1].type!=ident_)&&(Reg.LexArray[nom+1].type!=LeftBraket_)&&(Reg.LexArray[nom+1].type!=not_)&&
(Reg.LexArray[nom+1].type!=number_))
{
fprintf(ef,"line %d: \tAfter '(' must be '(' or identifier!\n",Reg.LexArray[nom].line);
error++;
}
}
if (IsOperation(Reg.LexArray[nom].type))
{
if ((Reg.LexArray[nom+1].type!=ident_)&&(Reg.LexArray[nom+1].type!=LeftBraket_)&&(Reg.LexArray[nom+1].type!=number_))
{
fprintf (ef,"line %d: \tAfter operation must be '(' or idetifier!\n",Reg.LexArray[nom].line);
error++;
}
}
if ((Reg.LexArray[nom].type==ident_)||(Reg.LexArray[nom].type==number_))
{
if (!(IsOperation(Reg.LexArray[nom+1].type))&&(Reg.LexArray[nom+1].type!=not_)&&(Reg.LexArray[nom+1].type!=RightBraket_)&&(Reg.LexArray[nom+1].type!=EndGroup_)&&(Reg.LexArray[nom+1].type!=else_))
{
fprintf(ef,"line %d: \tAfter identifier must be ')',';',or operation!\n",Reg.LexArray[nom].line);
error++;
}
}
}
return error;
}
void BeginASMFile()
{
fprintf(fout,"DOSSEG\n.MODEL SMALL\n.STACK 100h\n.DATA\n");
}
void BeginCodeSegm()
{fprintf(fout,".CODE\n\tmov ax,@data\n\tmov ds,ax\n");
fprintf(fout,"finit\nfstcw rc\nor rc,0c00h\nfldcw rc\n");
}
void CheckPresentInputOutput() //Визначення присутності операторів put i get
{
int i=0;
do
{
++i;
}while(Reg.LexArray[i-1].type != start_);
for(;Reg.LexArray[i].type != eof_;++i)
{
if(Reg.LexArray[i].type == input_) IsPresentInput = true;
if(Reg.LexArray[i].type == output_) IsPresentOutput = true;
if(IsPresentInput && IsPresentOutput) break;
}
}
void PrintMOD(FILE* f) //!!!new
{
fputs("\n;===Procedure mod_====================\n",f);
fputs("\nmod_ PROC\n\n",f);
fputs("\tfistp lb1\n",f);
fputs("\tfistp lb2\n",f);
fputs("\tfild lb1\n",f);
fputs("\tfild lb2\n",f);
fputs("\tfprem\n",f);
fputs("\tret\n",f);
fputs("mod_ ENDP\n",f);
fputs(";======================================\n\n",f);
}
void PrintAND(FILE* f)
{
fputs("\n;===Procedure and_====================\n",f);
fputs("\nand_ PROC\n\n",f);
fputs("\tpush ax\n",f);
fputs("\tpush dx\n",f);
fputs("\tpushf\n",f);
fputs("\tfistp lb1\n",f);
fputs("\tfist lb2\n",f);
fputs("\tmov ax,lb1\n",f);
fputs("\tcmp ax,0\n",f);
fputs("\tjnz true_and1\n",f);
fputs("\tjz false_and\n",f);
fputs("\n true_and1:\n",f);
fputs("\tmov ax,lb2\n",f);
fputs("\tcmp ax,0\n",f);
fputs("\tjnz true_and\n",f);
fputs("\n false_and:\n",f);
fputs("\tfldz\n",f);
fputs("\tjmp l_and\n",f);
fputs("\n true_and:\n",f);
fputs("\tfld1\n",f);
fputs("\n l_and:\n\n",f);
fputs("\tpopf\n",f);
fputs("\tpop dx\n",f);
fputs("\tpop ax\n\n",f);
fputs("\tret\n",f);
fputs("and_ ENDP\n",f);
fputs(";======================================\n\n",f);
}
void PrintOR(FILE* f)
{
fputs("\n;===Procedure or_======================\n",f);
fputs("\nor_ PROC\n\n",f);
fputs("\tpush ax\n",f);
fputs("\tpush dx\n",f);
fputs("\tpushf\n",f);
fputs("\tfistp lb1\n",f);
fputs("\tfist lb2\n",f);
fputs("\tmov ax,lb1\n",f);
fputs("\tcmp ax,0\n",f);
fputs("\tjnz true_or\n",f);
fputs("\tmov ax,lb2\n",f);
fputs("\tcmp ax,0\n",f);
fputs("\tjnz true_or\n",f);
fputs("\tfldz\n",f);
fputs("\tjmp l_or\n",f);
fputs("\n true_or:\n",f);
fputs("\tfld1\n",f);
fputs("\n l_or:\n\n",f);
fputs("\tpopf\n",f);
fputs("\tpop dx\n",f);
fputs("\tpop ax\n\n",f);
fputs("\tret\n",f);
fputs("or_ ENDP\n",f);
fputs(";======================================\n\n",f);
}
void PrintNOT(FILE* f)
{
fputs("\n;===Procedure not_====================\n",f);
fputs("\nnot_ PROC\n\n",f);
fputs("\tpush ax\n",f);
fputs("\tpushf\n",f);
fputs("\tfistp lb1\n",f);
fputs("\tmov ax,lb1\n",f);
fputs("\tcmp ax,0\n",f);
fputs("\tjne is_true\n",f);
fputs("\tfld1\n",f);
fputs("\tjmp l_not\n",f);
fputs("\n is_true:\n",f);
fputs("\tfldz\n",f);
fputs("\n l_not:\n\n",f);
fputs("\tpopf\n",f);
fputs("\tpop ax\n\n",f);
fputs("\tret\n",f);
fputs("not_ ENDP\n",f);
fputs(";======================================\n\n",f);
}
void PrintEQ(FILE* f)
{
fputs("\n;===Procedure eq_======================\n",f);
fputs("\neq_ PROC\n\n",f);
fputs("\tpush ax\n",f);
fputs("\tpush dx\n",f);
fputs("\tpushf\n",f);
fputs("\tfistp lb1\n",f);
fputs("\tfistp lb2\n",f);
fputs("\tmov ax,lb1\n",f);
fputs("\tmov dx,lb2\n",f);
fputs("\tcmp ax,dx\n",f);
fputs("\tjne not_eq\n",f);
fputs("\tfld1\n",f);
fputs("\tjmp l_eq\n",f);
fputs("\n not_eq:\n",f);
fputs("\tfldz\n",f);
fputs("\n l_eq:\n",f);
fputs("\tpopf\n",f);
fputs("\tpop dx\n",f);
fputs("\tpop ax\n\n",f);
fputs("\tret\n",f);
fputs("eq_ ENDP\n",f);
fputs(";======================================\n\n",f);
}
void PrintGE(FILE* f)
{
fputs("\n;===Procedure ge_======================\n",f);
fputs("\nge_ PROC\n\n",f);
fputs("\tpush ax\n",f);
fputs("\tpush dx\n",f);
fputs("\tpushf\n",f);
fputs("\tfistp lb1\n",f);
fputs("\tfistp lb2\n",f);
fputs("\tmov ax,lb1\n",f);
fputs("\tmov dx,lb2\n",f);
fputs("\tcmp dx,ax\n",f);
fputs("\tjl lov\n",f);
fputs("\tfld1\n",f);
fputs("\tjmp l_ge\n",f);
fputs("\n lov:\n",f);
fputs("\tfldz\n",f);
fputs("\n l_ge:\n",f);
fputs("\tpopf\n",f);
fputs("\tpop dx\n",f);
fputs("\tpop ax\n\n",f);
fputs("\tret\n",f);
fputs("ge_ ENDP\n",f);
fputs(";======================================\n\n",f);
}
void PrintLE(FILE* f)
{
fputs("\n;===Procedure le_======================\n",f);
fputs("\nle_ PROC\n\n",f);
fputs("\tpush ax\n",f);
fputs("\tpush dx\n",f);
fputs("\tpushf\n",f);
fputs("\tfistp lb1\n",f);
fputs("\tfistp lb2\n",f);
fputs("\tmov ax, lb1\n",f);
fputs("\tmov dx, lb2\n",f);
fputs("\tcmp dx,ax\n",f);
fputs("\tjg gr\n",f);
fputs("\n lo:\n",f);
fputs("\tfld1\n",f);
fputs("\tjmp l_le\n",f);
fputs("\n gr:\n",f);
fputs("\tfldz\n",f);
fputs("\n l_le:\n",f);
fputs("\tpopf\n",f);
fputs("\tpop dx\n",f);
fputs("\tpop ax\n\n",f);
fputs("\tret\n",f);
fputs("le_ ENDP\n",f);
fputs(";======================================\n\n",f);
}
void PrintEnding(FILE* f)
{
fputs(";======================================\n",f);
fputs("MOV AH,4Ch\nINT 21h\n",f);
if(IsPresentInput)
{
PrintInput(f);
}
if(IsPresentOutput)
{
PrintOutput(f);
}
PrintMOD(f);
PrintAND(f);
PrintOR(f);
PrintNOT(f);
PrintEQ(f);
PrintGE(f);
PrintLE(f);
fputs(";======================================\n\n",f);
fputs("END",f);
}
void PrintInput(FILE* f)
{
fputs("\n;====Input procedure Input()=============\n",f);
fputs("input PROC\n\n",f);
fputs("\tpush ax\n",f);
fputs("\tpush bx\n",f);
fputs("\tpush cx\n",f);
fputs("\tpush dx\n",f);
fputs("\tpush di\n",f);
fputs("\tpush si\n",f);
fputs("\n\tlea dx,In_Str\n",f);
fputs("\tmov ah,09\n",f);
fputs("\tint 21h\n",f);
fputs("\tmov di,offset buf\n",f);
fputs("\tmov MaxLen,5\n",f);
fputs("\tmov cx,MaxLen\n\n",f);
fputs("\tmov si,0\n",f);
fputs("\n In_00:\n",f);
fputs("\tmov ah,01\n",f);
fputs("\tint 21h\n",f);
fputs("\tcmp al,0Dh\n",f);
fputs("\tje In_1\n",f);
fputs("\tcmp al,'-'\n",f);
fputs("\tjne In_0\n",f);
fputs("\tmov FlagS,1\n",f);
fputs("\tjmp In_00\n",f);
fputs("\n In_0:\n",f);
fputs("\tmov dl,al\n",f);
fputs("\tcall CHECK_BYTE\n",f);
fputs("\tmov TStr[si],dl\n",f);
fputs("\tinc si\n",f);
fputs("\tloop In_00\n",f);
fputs("\n In_1:\n",f);
fputs("\tpush si\n",f);
fputs("\tdec si\n",f);
fputs("\tcmp cx,MaxLen\n",f);
fputs("\tjne In_2\n",f);
fputs("\tlea dx,erStr1\n",f);
fputs("\tmov ah,09\n",f);
fputs("\tint 21h\n",f);
fputs("\tmov erFlag,1\n",f);
fputs("\tjmp In_5\n",f);
fputs("\n In_2:\n",f);
fputs("\tmov bh,0\n",f);
fputs("\tmov bl,TStr[si]\n",f);
fputs("\tMY_MUL Mul10,bx,my_z\n",f);
fputs("\tadd TBin,ax\n",f);
fputs("\tadc TBin+2,dx\n",f);
fputs("\tmov bh,0\n",f);
fputs("\tmov bl,10\n",f);
fputs("\tMY_MUL Mul10,bx,my_z\n",f);
fputs("\tmov Mul10,ax\n",f);
fputs("\tmov Mul10+2,dx\n",f);
fputs("\tdec si\n",f);
fputs("\tcmp si,0\n",f);
fputs("\tjge In_2\n",f);
fputs("\tmov ax,TBin\n",f);
fputs("\tmov dx,TBin+2\n",f);
fputs("\tpop si\n",f);
fputs("\tcmp si,MaxLen\n",f);
fputs("\tjl In_3\n",f);
fputs("\tcmp MaxLen,5\n",f);
fputs("\tjl In_2_1\n",f);
fputs("\tjs In_Err\n",f);
fputs("\tcmp dx,7FFFh\n",f);
fputs("\tja In_Err\n",f);
fputs("\tjmp In_3\n",f);
fputs("\n In_2_1:\n",f);
fputs("\tcmp MaxLen,5\n",f);
fputs("\tjl In_2_2\n",f);
fputs("\tcmp dx,00\n",f);
fputs("\tja In_Err\n",f);
fputs("\tcmp ah,7fh\n",f);
fputs("\tja In_Err\n",f);
fputs("\tjmp In_3\n",f);
fputs("\n In_2_2:\n",f);
fputs("\tcmp ax,007Fh\n",f);
fputs("\tjbe In_3\n",f);
fputs("\n In_Err:\n",f);
fputs("\tlea dx,erStr3\n",f);
fputs("\tmov ah,09\n",f);
fputs("\tint 21h\n",f);
fputs("\tmov erFlag,1\n",f);
fputs("\tjmp In_5\n",f);
fputs("\n In_3:\n",f);
fputs("\tcmp FlagS,1\n",f);
fputs("\tjne In_4\n",f);
fputs("\tmov bx,0\n",f);
fputs("\tsub bx,ax\n",f);
fputs("\tmov ax,bx\n",f);
fputs("\tmov bx,0\n",f);
fputs("\tsbb bx,dx\n",f);
fputs("\tmov dx,bx\n",f);
fputs("\n In_4:\n",f);
fputs("\tmov [di],ax\n",f);
fputs("\tmov [di+2],dx\n",f);
fputs("\tmov TBin,0\n",f);
fputs("\tmov TBin+2,0\n",f);
fputs("\tmov Mul10,1\n",f);
fputs("\tmov Mul10+2,0\n",f);
fputs("\tmov FlagS,0\n",f);
fputs("\n In_5:\n\n",f);
fputs("\tpop si\n",f);
fputs("\tpop di\n",f);
fputs("\tpop dx\n",f);
fputs("\tpop cx\n",f);
fputs("\tpop bx\n",f);
fputs("\tpop ax\n\n",f);
fputs("\tret\n",f);
fputs("input ENDP\n\n",f);
fputs("CHECK_BYTE PROC\n",f);
fputs("\tsub dl,30h\n",f);
fputs("\tcmp dl,00\n",f);
fputs("\tjl ErS\n",f);
fputs("\tcmp dl,0Ah\n",f);
fputs("\tjl GO\n",f);
fputs("\n ErS:\n",f);
fputs("\tlea dx,erStr2\n",f);
fputs("\tmov ah,09\n",f);
fputs("\tint 21h\n",f);
fputs("\n GO:\n",f);
fputs("\tret\n",f);
fputs("CHECK_BYTE ENDP\n",f);
fputs(";======================================\n\n",f);
}
void PrintOutput(FILE* f)
{
fputs("\n;===Output procedure output()=============\n",f);
fputs("\noutput PROC\n\n",f);
fputs("\tpush ax\n",f);
fputs("\tpush bx\n",f);
fputs("\tpush cx\n",f);
fputs("\tpush dx\n",f);
fputs("\tpush di\n",f);
fputs("\tpush si\n\n",f);
fputs("\tmov cl,byte ptr buf+3\n",f);
fputs("\tand cl,80h\n",f);
fputs("\tje m6\n",f);
fputs("\tfild buf\n",f);
fputs("\tfchs\n",f);
fputs("\tfistp buf\n",f);
fputs("\tmov MSign,\'-\'\n",f);
fputs("\n M6:\n",f);
//=================
fputs("\tmov cx,5\n",f);
fputs("\tmov di,0\n",f);
fputs("\n O_1:\n",f);
fputs("\tffree st(0)\n",f);
fputs("\tffree st(1)\n",f);
fputs("\tfild ten\n",f);
fputs("\tfild buf\n",f);
fputs("\tfprem\n",f);
fputs("\tfistp X1\n",f);
fputs("\tmov dl,byte ptr X1\n",f);
fputs("\tadd dl,30h\n",f);
fputs("\tmov X_Str[di],dl\n",f);
fputs("\tinc di\n",f);
fputs("\tfild buf\n",f);
fputs("\tfxch st(1)\n",f);
fputs("\tfdiv\n",f);
fputs("\tfrndint\n",f);
fputs("\tfistp buf\n",f);
fputs("\tloop O_1\n\n",f);
fputs("\tmov dx,offset MX1\n",f);
fputs("\tmov ah,09\n",f);
fputs("\tint 21h\n",f);
fputs("\tmov dl,MSign\n",f);
fputs("\tmov ah,02\n",f);
fputs("\tint 21h\n",f);
fputs("\tinc di\n",f);
fputs("\tmov cx,7\n",f);
fputs("\n O_2:\n",f);
fputs("\tmov dl,X_Str[di]\n",f);
fputs("\tmov ah,02h\n",f);
fputs("\tint 21h\n",f);
fputs("\tdec di\n",f);
fputs("\tloop O_2\n\n",f);
fputs("\tmov MSign,\'+\'\n\n",f);
fputs("\tpop si\n",f);
fputs("\tpop di\n",f);
fputs("\tpop dx\n",f);
fputs("\tpop cx\n",f);
fputs("\tpop bx\n",f);
fputs("\tpop ax\n\n",f);
fputs("\tret\n",f);
fputs("output ENDP\n",f);
fputs(";======================================\n\n",f);
}
bool IsOperation(LexemType t)
{
bool r;
r = ((t==add_)||(t==sub_)||(t==div_)||(t==mul_)||(t==mod_)||
(t==and_)||(t==or_)||(t==equ_)||(t==notequ_)||(t==le_)||(t==ge_));
return r;
}
bool Prioritet(LexemType t,StackType s)
{
bool r;
r = (
((t==div_)&&(Reg.LexArray[s.st[s.top]].type==add_))||
((t==div_)&&(Reg.LexArray[s.st[s.top]].type==sub_))||
((t==div_)&&(Reg.LexArray[s.st[s.top]].type==or_))||
((t==div_)&&(Reg.LexArray[s.st[s.top]].type==and_))||
((t==div_)&&(Reg.LexArray[s.st[s.top]].type==equ_))||
((t==div_)&&(Reg.LexArray[s.st[s.top]].type==notequ_))||
((t==div_)&&(Reg.LexArray[s.st[s.top]].type==le_))||
((t==div_)&&(Reg.LexArray[s.st[s.top]].type==ge_))||
((t==mul_)&&(Reg.LexArray[s.st[s.top]].type==add_))||
((t==mul_)&&(Reg.LexArray[s.st[s.top]].type==sub_))||
((t==mul_)&&(Reg.LexArray[s.st[s.top]].type==or_))||
((t==mul_)&&(Reg.LexArray[s.st[s.top]].type==and_))||
((t==mul_)&&(Reg.LexArray[s.st[s.top]].type==equ_))||
((t==mul_)&&(Reg.LexArray[s.st[s.top]].type==notequ_))||
((t==mul_)&&(Reg.LexArray[s.st[s.top]].type==le_))||
((t==mul_)&&(Reg.LexArray[s.st[s.top]].type==ge_))||
((t==mod_)&&(Reg.LexArray[s.st[s.top]].type==add_))||
((t==mod_)&&(Reg.LexArray[s.st[s.top]].type==sub_))||
((t==mod_)&&(Reg.LexArray[s.st[s.top]].type==or_))||
((t==mod_)&&(Reg.LexArray[s.st[s.top]].type==and_))||
((t==mod_)&&(Reg.LexArray[s.st[s.top]].type==equ_))||
((t==mod_)&&(Reg.LexArray[s.st[s.top]].type==notequ_))||
((t==mod_)&&(Reg.LexArray[s.st[s.top]].type==le_))||
((t==mod_)&&(Reg.LexArray[s.st[s.top]].type==ge_))
);
return r;
}
int ConvertToPostfixForm(int i) //Формує в масиві послідовність номерів лексем яка відповідає постфіксній формі
{
s.Init(&s.S);
int n,z;
n = 0;
for(;((Reg.LexArray[i+n].type!=EndGroup_)&&(Reg.LexArray[i+n].type!=then_)&&(Reg.LexArray[i+n].type!=if_));++n); //Встановлення коректності та довжини вхідного масиву
int k;
k=i+n;
for(z=0;i < k;++i)
{
LexemType in;
in = Reg.LexArray[i].type;
if((in == ident_)||(in == number_)||(in == not_)) //!!!!!!
{
Reg.PFExpr[z] = i;
++z;
}
else if(IsOperation(in))
{
if(s.IsEmpty(&s.S)||Prioritet(in,s.S))
{
s.Push(i,&s.S);
}
else
{
if(Reg.LexArray[s.S.st[s.S.top]].type!=LeftBraket_)
{
do
{
Reg.PFExpr[z] = s.Pop(&s.S);
++z;
}while((!(Prioritet(in,s.S)))&&(!(s.IsEmpty(&s.S)))&&(Reg.LexArray[s.S.st[s.S.top]].type!=LeftBraket_));
}
s.Push(i,&s.S);
}
}
if(in == LeftBraket_)
{
s.Push(i,&s.S);
Reg.PFExpr[z] = i;
++z;
}
if(in == RightBraket_)
{
for (;(Reg.LexArray[s.S.st[s.S.top]].type != LeftBraket_);)
{
Reg.PFExpr[z] = s.Pop(&s.S); //s.S.st[s.S.top];
++z;
}
s.Pop(&s.S);
Reg.PFExpr[z] = i;
++z;
}
}
for(;!(s.IsEmpty(&s.S));)
{
Reg.PFExpr[z] = s.Pop(&s.S);
++z;
}
Reg.PFExpr[z] = 3000;
z++;
return k;
}
void CodeGenerator(FILE* f)
{
BeginASMFile();
CheckPresentInputOutput();
PrintData(f);
BeginCodeSegm();
PrintCode(f);
PrintEnding(f);
}
void PrintData(FILE* f) //Друк сегмету даних
{
if(IsPresentInput)
{
fputs("MY_MUL MACRO X,Y,Z\n",f);
fputs("\tmov z,0\n",f);
fputs("\tmov z+2,0\n",f);
fputs("\tmov ax,x\n",f);
fputs("\tmul y\n",f);
fputs("\tmov z,ax\n",f);
fputs("\tmov z+2,dx\n",f);
fputs("\tmov ax,x+2\n",f);
fputs("\tmul y\n",f);
fputs("\tadd z+2,ax\n",f);
fputs("\tmov ax,z\n",f);
fputs("\tmov dx,z+2\n",f);
fputs("ENDM\n\n",f);
}
int i;
for(i = 1; i<Reg.idnum; ++i)
{
fprintf(f,"\t%s\tdw\t0%xh\n",Reg.IdTable[i].name,Reg.IdTable[i].value);
}
fputs("\tlb1\tdw\t0h\n",f); //Змінні для обробки логічних операцій
fputs("\tlb2\tdw\t0h\n",f);
fputs("\tbuf_if\tdw\t0h\n",f);
fprintf(fout,"buf\tdd\t0\nrc\tdw\t0\n");
if(IsPresentInput)
{
fputs(";======Data for input() functions======\n",f);
fputs("\terFlag\tdb\t0\n",f);
fputs("\tTStr\tdb\t10 dup (0)\n",f);
fputs("\tTBin\tdw\t0,0\n",f);
fputs("\tMaxLen\tdw\t0\n",f);
fputs("\tFlagS\tdb\t0\n",f);
fputs("\tMul10\tdw\t1,0\n",f);
fputs("\tmy_z\tdw\t0,0\n\n",f);
fputs("\tIn_Str\tdb\t13,10,\'<< $\'\n",f);
fputs("\terStr1\tdb\t13,10,\'Data not input_variable\',13,10,\'$\'\n",f);
fputs("\terStr2\tdb\t13,10,\'Incorrectly data \',13,10,\'$\'\n",f);
fputs("\terStr3\tdb\t13,10,\'Data is too long \',13,10,\'$\'\n",f);
fputs(";======================================\n\n",f);
}
if(IsPresentOutput)
{
fputs(";=======Data for output===================\n",f);
fputs("\tMSign\tdb\t\'+\',\'$\'\n",f);
fputs("\tX_Str\tdb\t12 dup (0)\n",f);
fputs("\tten\tdw\t10\n",f);
fputs("\tX1\tdw\t0h\n",f);
fputs("\tMX1\tdb\t13,10,\'>> $\'\n",f);
fputs(";======================================\n\n",f);
}
}
void PrintCode(FILE* f)
{
int lab=0;
Lexema l; //Поточна лексема
int i=0;
do //Пошук початку коду
{
++i;
}while(Reg.LexArray[i].type != start_);
++i;
if_s.Init(&if_s.S);
start_s.Init(&start_s.S);
for(;;++i)
{
static int labelnom=0;
l.type = Reg.LexArray[i].type;
strncpy(l.name,Reg.LexArray[i].name,50);;
l.value = Reg.LexArray[i].value;
if(l.type == eof_) break;
if (l.type==if_)
{
labelnom++;
if_s.Push(labelnom,&if_s.S);
i = ConvertToPostfixForm(i+1);
GenASMCode("buf_if",f);
fputs("\tcmp buf_if,0\n",f);
fprintf(f,"\tjne label_%dne\n",labelnom);
fprintf(f,"\tjmp label_%d\n",labelnom);
fprintf(f,"label_%dne:\n",labelnom);
}
if (l.type==start_)
{
if (Reg.LexArray[i-1].type==then_)
{
start_s.Push(1,&start_s.S);
}
if (Reg.LexArray[i-1].type==else_)
{
start_s.Push(2,&start_s.S);
}
}
if ((l.type==stop_)&&(Reg.LexArray[i+1].type!=eof_))
{
if (start_s.S.st[start_s.S.top]==1)
{
if (Reg.LexArray[i+2].type==else_)
{
fprintf(f,"\tjmp label_%d_\n",if_s.S.st[if_s.S.top]);
fprintf(f,"label_%d:\n",if_s.S.st[if_s.S.top]);
}
else
{
fprintf(f,"label_%d:\n",if_s.S.st[if_s.S.top]);
if_s.Pop(&if_s.S);
}
}
if (start_s.S.st[start_s.S.top]==2)
{
if (Reg.LexArray[i+2].type==else_)
{
fprintf(f,"label_%d_:\n",if_s.S.st[if_s.S.top]);
if_s.Pop(&if_s.S);
fprintf(f,"\tjmp label_%d_\n",if_s.S.st[if_s.S.top]);
fprintf(f,"label_%d:\n",if_s.S.st[if_s.S.top]);
}
else
{
fprintf(f,"label_%d_:\n",if_s.S.st[if_s.S.top]);
if_s.Pop(&if_s.S);
}
}
start_s.Pop(&start_s.S);
}
if(l.type == output_)
{
i = ConvertToPostfixForm(i+1);
GenASMCode("buf",f);
fputs("\tcall output\n",f);
}
if(l.type == input_)
{
fputs("\tcall input\n",f);
fprintf(f,"\tfild buf\n");
fprintf(f,"\tfistp %s\n",Reg.LexArray[i+2].name);
i +=4;
}
if(l.type == newval_)
{
int bufi;
bufi = i;
i = ConvertToPostfixForm(i+1);//Генерація постфіксного виразу
if(i<0)
{
i = -i;
puts("IE\n");
continue;
}
//Генерація асемблерного коду з постфіксного виразу
GenASMCode(Reg.LexArray[bufi-1].name,f);
}
}
}
bool IsElsePresent(int i)
{
int bufer, nom=0;
bufer=i;
for (;(Reg.LexArray[bufer].type!=then_);bufer++)
{}
bufer++;
if (Reg.LexArray[bufer].type==start_)
{
nom++;
do
{
bufer++;
if (Reg.LexArray[bufer].type==start_)
nom++;
if (Reg.LexArray[bufer].type==stop_)
nom--;
}while (nom!=0);
if (Reg.LexArray[bufer+1].type==else_)
return true;
else return false;
}
else
{
for (;((Reg.LexArray[bufer].type!=EndGroup_)&&(Reg.LexArray[bufer].type!=if_));bufer++);
if (Reg.LexArray[bufer+1].type==else_)
return true;
else return false;
}
}
void GenASMCode(const char * str, FILE* f)
{
int n;
for(n=0;Reg.PFExpr[n] != 3000;++n)
{
//puts("pf");
s.Init(&s.S);
if((!IsOperation(Reg.LexArray[Reg.PFExpr[n]].type))&&(Reg.LexArray[Reg.PFExpr[n]].type != not_))
{
if/*(*/(Reg.LexArray[Reg.PFExpr[n]].type == ident_)/*&&(Reg.LexArray[Reg.PFExpr[n]].type!=newval_))*/
{
fprintf(f,"\tfild %s\n",Reg.LexArray[Reg.PFExpr[n]].name);
}
else if(Reg.LexArray[Reg.PFExpr[n]].type == number_)
{
char buf[10];
buf[0] = '0';
sprintf(&buf[1],"%04x",Reg.LexArray[Reg.PFExpr[n]].value);
buf[6] = '\0';
fprintf(f,"\tmov word ptr buf,%sh\n",buf);
fputs("\tfild buf\n",f);
}
else if((Reg.LexArray[Reg.PFExpr[n]].type == LeftBraket_)||(Reg.LexArray[Reg.PFExpr[n]].type == RightBraket_))
{
continue;
}
}
else
{
switch(Reg.LexArray[Reg.PFExpr[n]].type)
{
case add_: fputs("\tfadd\n",f);
break;
case sub_: fputs("\tfsub\n",f);
break;
case div_: fputs("\tfdiv\n",f);
break;
case mod_: fputs("\tcall mod_\n",f);
break;
case mul_: fputs("\tfmul\n",f);
break;
case and_: fputs("\tcall and_\n",f);
break;
case or_: fputs("\tcall or_\n",f);
break;
case not_: fputs("\tcall not_\n",f); break;
case equ_: fputs("\tcall eq_\n",f); break;
case notequ_: fputs("\tcall eq_\n",f);
fputs("\tcall not_\n",f);break;
case le_: fputs("\tcall le_\n",f); break;
case ge_: fputs("\tcall ge_\n",f); break;
}
}
}
fprintf(f,"\tfistp %s\n",str);
}
void main(int argc, char* argv[])
{
printf("\n\n===============================================================\n");
printf("\t\tP13-into-ASM Translator. V1.0.\n");
printf("-------------------------------------------------------------------\n");
if (argc!=2)
{ printf("Warning! You have to write a input file name as a second parameter!\n");
printf("Syntax example:\nv13.exe input.v13");
getchar();
exit(1);}
strcpy(InputFileName,argv[1]);
strncpy(OutFileName,InputFileName,strlen(InputFileName)-4);
strcat(OutFileName,".asm"); //Utvorennja imeni vyxidnoho fajlu
printf("Translating file: %s\n",InputFileName);
if ((fin = fopen(InputFileName,"r"))==0)
{printf("Error opening input file\n"); getchar(); exit(1);}
else if ((fout = fopen(OutFileName,"w"))==0)
{printf("Error opening output file\n");}
else {printf("Output ASM file: %s\n",OutFileName);}
Reg.length=LexicalAnalyze(fin);
MakeLexOutFile();
printf("Scanning for errors... Output file - error.txt.\n");
Error_num=FindErrors();
printf("%d errors found.\n",Error_num);
if (Error_num!=0)
{
printf("Cannot translate because of errors. Put changes into input file.\n");
}
else
{
printf("Translating...\n");
CodeGenerator(fout);
printf("Done!\n");
printf("===============================================================================\n");
}
}
