Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Zapiska_-_31_1 (1).docx
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
536.65 Кб
Скачать

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

  1. В.С. Проценко, П.Й. Чаленко, А.Б.Ставровський “Техніка програмування мовою Сі”.-Київ “Либідь”, 1993. – 224с.

  2. Б.Керниган, Д.Ритчи “Язык программирования Си”. – Москва “Финансы и статистика”, 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");

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]