| Test-c++-lang |
| 1 | #include "translator.h" int main() { //Загрузка ключевых слов. for(unsigned int i=0;i<TOTAL_KEYWORDS;i++) keywords.push_back(keywrd[i]); char file_read='\0'; int linecount=1; ifstream input(FILE_READ); //Начало чтения входного файла. while(input.get(file_read)) { if(file_read==' ') linecount++; if(file_read!=' '&&file_read!='\t'&&file_read!=' ') { input.seekg(-1,ios::cur); lexemer(input,linecount); //Начало создания лексем } } input.close(); tok.clas="error"; tok.index=-10; tokens.push_back(tok); //Начало парсинга syntax_box(); //Начало генерации кода code_generator(); cout<<" \"ZeddTranslator\" has sucessfully assemblied code from input file(c_code.txt)" <<endl<<"see output file (asm_code.txt)"; cout<<" "; getch(); return(0); } ///**********************/// ///**********************/// /// /// /// Лексический анализ /// /// /// ///**********************/// ///**********************/// void lexemer(ifstream& input,int& line) { char character_read='\0'; char lexeme_buffer[LEXEME_SIZE]; memset(lexeme_buffer,'\0',LEXEME_SIZE); int counter=0; int current_state=0,starting_state=0; bool read_flag=true; streampos lexeme_begining=input.tellg(); while(read_flag){ switch(current_state) { case 0:input.get(character_read); if(isalpha(character_read)||character_read=='_') {current_state=1;lexeme_buffer[counter]=character_read;counter++;starting_state=0;} else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining); break; case 1:input.get(character_read); if(isalpha(character_read)||character_read=='_'||isdigit(character_read)) {current_state=1;lexeme_buffer[counter]=character_read;counter++;} else current_state=2; break; case 2: input.seekg(-1,ios::cur); read_flag=false; break; case 3:input.get(character_read); if(character_read=='=') {current_state=4;lexeme_buffer[counter]=character_read;counter++;starting_state=3;} else if(character_read=='<') {current_state=7;lexeme_buffer[counter]=character_read;counter++;starting_state=3;} else if(character_read=='>') {current_state=11;lexeme_buffer[counter]=character_read;counter++;starting_state=3;} else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining); break; case 4:input.get(character_read); if(character_read=='=') {current_state=5;lexeme_buffer[counter]=character_read;counter++;} else current_state=6; break; case 5: read_flag=false; break; case 6: input.seekg(-1,ios::cur); read_flag=false; break; case 7:input.get(character_read); if(character_read=='=') {current_state=8;lexeme_buffer[counter]=character_read;counter++;} else if(character_read=='>') {current_state=9;lexeme_buffer[counter]=character_read;counter++;} else current_state=10; break; case 8: read_flag=false; break; case 9: read_flag=false; break; case 10: input.seekg(-1,ios::cur); read_flag=false; break; case 11:input.get(character_read); if(character_read=='=') {current_state=12;lexeme_buffer[counter]=character_read;counter++;} else current_state=13; break; case 12: read_flag=false; break; case 13: input.seekg(-1,ios::cur); read_flag=false; break; case 14: input.get(character_read); if(character_read=='+'|| character_read=='-'||character_read=='*'||character_read=='/'||character_read=='%') {current_state=15;lexeme_buffer[counter]=character_read;counter++;starting_state=14;} else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining); break; case 15: read_flag=false; break; case 16: input.get(character_read); if(character_read=='('||character_read==')'||character_read=='{'||character_read=='}'||character_read==','||character_read==';'||character_read=='['||character_read==']') {current_state=17;lexeme_buffer[counter]=character_read;counter++;starting_state=16;} else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining); break; case 17: read_flag=false; break; case 18: input.get(character_read); if(isdigit(character_read)) {current_state=19;lexeme_buffer[counter]=character_read;counter++;starting_state=18;} else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining); break; case 19: input.get(character_read); if(isdigit(character_read)) {current_state=19;lexeme_buffer[counter]=character_read;counter++;} else if(character_read=='L'||character_read=='l') {current_state=20;lexeme_buffer[counter]=character_read;counter++;} else current_state=21; break; case 20: read_flag=false; break; case 21: input.seekg(-1,ios::cur); read_flag=false; break; case 100: input.get(character_read); {current_state=100;lexeme_buffer[counter]=character_read;counter++;starting_state=100;} read_flag=false; break; } } lexeme_buffer[counter]='\0'; tokenizer(lexeme_buffer,starting_state); } int lexemer_fail(ifstream& input,char& faulty_character,int& line,int& starting_state,streampos& lexeme_begining) { switch(starting_state) { case 0: input.seekg(lexeme_begining);starting_state=3;break; case 3: input.seekg(lexeme_begining);starting_state=14;break; case 14: input.seekg(lexeme_begining);starting_state=16;break; case 16: input.seekg(lexeme_begining);starting_state=18;break; case 18: input.seekg(lexeme_begining);starting_state=100;break; } return starting_state; } void lexemer_error(char& faulty_character,int &line) { cout<<" Some Ir-Recoverable Error Occured in LEXICAL ANALYZER!---Possibly" <<" An Invalid Lexeme Caused it,Which is Not Part Of Our Language" <<"The Starting SYMBOL Of Lexeme is "<<faulty_character<<" Line Number Is "<<line<<endl; getch(); exit(-1); } void tokenizer(char* lexeme_buffer,int& starting_state) { tok.clas=" "; tok.index=-10; string lexeme; lexeme.assign(lexeme_buffer); unsigned int j=0,k=0; long num; switch(starting_state) { case 0: for(k=0;k<keywords.size();k++) { if(lexeme==keywords[k]) { if(lexeme=="int"||lexeme=="long") { tok.clas="dt"; tok.index=(lexeme=="int")?0:1; } else{ tok.clas=lexeme; tok.index=-10; } tokens.push_back(tok); return; } } for(j=0;j<lex_identifier.size();j++) if(lex_identifier[j]==lexeme) { tok.clas="id"; tok.index=j; tokens.push_back(tok); return; } //проверка на повтор идентификаторов if(lex_identifier.size()==0||lex_identifier.size()==j) { lex_identifier.push_back(lexeme); tok.clas="id"; tok.index=j; tokens.push_back(tok); return; } break; case 3: if(lexeme=="=") tok.clas="assignop"; else tok.clas="relop"; if(lexeme=="==") tok.index=8; else if(lexeme=="<>") tok.index=9; else if(lexeme==">=") tok.index=10; else if(lexeme=="<=") tok.index=11; else if(lexeme==">") tok.index=12; else if(lexeme=="<") tok.index=13; else if(lexeme=="=") tok.index=14; //вбивание токенов в стек tokens.push_back(tok); break; case 14: tok.clas=(lexeme=="+" ||lexeme=="-") ? "add_sub" : "mul_div_mod"; if(lexeme=="+") tok.index=15; else if(lexeme=="-") tok.index=16; else if(lexeme=="*") tok.index=17; else if(lexeme=="/") tok.index=18; else if(lexeme=="%") tok.index=19; tokens.push_back(tok); break; case 16: if(lexeme=="{") { tok.clas="braces_open"; tok.index=2; tokens.push_back(tok); } else if(lexeme=="}") { tok.clas="braces_close"; tok.index=3; tokens.push_back(tok); } else if(lexeme=="(") { tok.clas="parenthesis_open"; tok.index=4; tokens.push_back(tok); } else if(lexeme==")") { tok.clas="parenthesis_close"; tok.index=5; tokens.push_back(tok); } else if(lexeme==",") { tok.clas="comma"; tok.index=6; tokens.push_back(tok); } else if(lexeme==";") { tok.clas="semicolon"; tok.index=7; tokens.push_back(tok); } else if(lexeme=="[") { tok.clas="square_open"; tok.index=20; tokens.push_back(tok); } else if(lexeme=="]") { tok.clas="square_close"; tok.index=21; tokens.push_back(tok); } break; case 18: num=lexeme.find('L'); if (num==-1) num=lexeme.find('l'); if(num!=-1) { lexeme.erase(num,1); num=0; const char *temp=lexeme.c_str(); num=atol(temp); for(m=0;m<number_long.size();m++) if(number_long[m]==num) { tok.clas="long_const"; tok.index=m; tokens.push_back(tok); return; } if(number_long.size()==0||number_long.size()==m) { number_long.push_back(num); tok.clas="long_const"; tok.index=m; tokens.push_back(tok); return; } } else { int num=0; num=atoi(lexeme_buffer); for(m=0;m<number_int.size();m++) if(number_int[m]==num) { tok.clas="int_const"; tok.index=m; tokens.push_back(tok); return; } if(number_int.size()==0||number_int.size()==m) { number_int.push_back(num); tok.clas="int_const"; tok.index=m; tokens.push_back(tok); return; } } break; case 100: tok.clas="error"; tok.index=-10; tokens.push_back(tok); break; } } ///**********************/// ///**********************/// /// /// /// Синтаксический /// /// анализатор /// ///**********************/// ///**********************/// |
| 2 | to input; //Используется для чтения лексемы из анализатоа выше |
| 3 | struct id{ string name; int datatype; int scope; int binding; bool func_or_not; int type; int offset; int xtra; }ident; vector<id> syn_identifier; vector<id> args_identifier; int syn_index=0; |
| 4 | int scopecount=-10; stack <int> scopestack; int func_index=-10; bool main_func=false; bool isreturn=false; //Используется для промежуточного кода struct expr{ int index; int datatype; int whichtable; }dump; int table=-10; struct atom{ string op; int type; expr arg1; expr arg2; expr result; }atm; vector<atom> atoms; vector<string> labels; long init_arg=-10,fin_arg=-10; void advanc(); void reject(); void settype(int index,int type); void settype_args(int index,int type); expr newtemp(int type); string newtempname(void); long chk_ident(long index); bool chk_types(expr v1,expr v2); void setatom(int op,expr arg1,expr arg2,expr result); int newlabel(void); long chk_func(long index); void args_info(long index,long &init_arg,long &fin_arg); int calc_param_offset(); int calc_local_offset(); |
| 5 | void program(); void data_or_function(int type); void function_or_main(); void function_body(); void variable_declarations(); void variable_list(int type); void argument_list(); void argument(); void compound_statement(); void statements(); void statement(); void optional_else(); void right_hand_side(expr &r); void function_call(expr &f); void optional_expression_list(); void expression_listf(); void expression_list_element(); void expression(expr &k); void relational(expr &k,expr &t1); void arithmetic(expr &p); void subtract(expr p,expr &q); void t(expr &p); void add(expr p,expr &q); void u(expr &p); void multiply(expr p,expr &q); void v(expr &p); void divide(expr p,expr &q); void w(expr &p); void mod(expr p,expr &q); void x(expr &p); void advanc() { if(syn_index!=(tokens.size()-1)) { syn_index++; input=tokens[syn_index]; } } void reject() { cout<<" Parser Failed"; cout<<" Parser has parsed "<< syn_index+1 <<" Tokens "; //cout<<"See \"parser_log.txt\" For Details "; getch(); exit(-1); } void settype(int index,int type) { string name=lex_identifier[index]; for(unsigned int j=0;j<syn_identifier.size();j++) { if(syn_identifier[j].name==name && syn_identifier[j].scope==scopestack.top()) { cout<<"Variable name->"<< name<<" with scope "<< scopestack.top()<<" and datatype "<< type <<endl <<"Already exists With name->"<< syn_identifier[j].name<<" ,scope "<<syn_identifier[j].scope <<" and datatype "<< syn_identifier[j].datatype<<endl; reject(); } } if(func_index!=-10) { for(unsigned int j=0;j<args_identifier.size();j++) { if(args_identifier[j].name==name && args_identifier[j].binding==func_index) { cout<<endl<<"Redifinition of formal parameter "<< name <<" in "<<syn_identifier[func_index].name; reject(); } } } ident.name=name; ident.datatype=type; ident.scope=scopestack.top(); ident.func_or_not=false; ident.xtra=-10; if(func_index==-10 && main_func==false) { ident.binding=-2; ident.type=0; ident.offset=-10; } else if(func_index==-10 && main_func==true) { ident.binding=-1; ident.type=1; ident.offset=-10; } else if(func_index!=-10 && main_func==false) { ident.binding=func_index; ident.type=2; ident.offset=-10; } syn_identifier.push_back(ident); } //For Arguments void settype_args(int index,int type) { string name=lex_identifier[index]; int binding=syn_identifier.size()-1; for(unsigned int j=0;j<args_identifier.size();j++) { if(args_identifier[j].name==name && args_identifier[j].binding==binding) { cout<<"Variable name->"<< name<<" with binding "<< binding <<" and datatype "<< type <<endl <<"Already exists With name->"<< args_identifier[j].name<<" ,binding " <<args_identifier[j].binding<<" and datatype "<< args_identifier[j].datatype<<endl; reject(); } } ident.name=name; ident.datatype=type; ident.scope=-10; ident.binding=binding; ident.func_or_not=false; ident.type=3; ident.offset=-10; ident.xtra=-10; args_identifier.push_back(ident); } expr newtemp(int type) { if(type==23) type=0; if(type==24) type=1; expr temp; ident.name=newtempname(); ident.datatype=type; ident.scope=scopestack.top(); ident.func_or_not=false; ident.type=4; ident.offset=-10; ident.xtra=-10; if(main_func==true) ident.binding=-1; else ident.binding=func_index; syn_identifier.push_back(ident); temp.index=syn_identifier.size()-1; temp.datatype=type; temp.whichtable=0; return temp; } string newtempname(void) { static long count=1; char name[10]; char temp[5]; ltoa(count,temp,10); strcpy(name,"t"); strcat(name,temp); count++; return string(name); } long chk_ident(long index) { table=-10; string name=lex_identifier[index]; unsigned int j=0; for(j=0;j<syn_identifier.size();j++) { if(syn_identifier[j].name==name && syn_identifier[j].scope==scopestack.top() && syn_identifier[j].func_or_not==false) { table=0; return j; } } if(func_index!=10) { for(j=0;j<args_identifier.size();j++) { if(args_identifier[j].name==name && args_identifier[j].binding==func_index) { table=1; return j; } } } for(j=0;j<syn_identifier.size();j++) { if(syn_identifier[j].name==name && syn_identifier[j].scope==0 && syn_identifier[j].func_or_not==false) { table=0; //For syn_identifier return j; } } return -10; } bool chk_types(expr v1,expr v2) { v1.datatype=v1.datatype==23 ? 0 : v1.datatype; v1.datatype=v1.datatype==24 ? 1 : v1.datatype; v2.datatype=v2.datatype==23 ? 0 : v2.datatype; v2.datatype=v2.datatype==24 ? 1 : v2.datatype; return(v1.datatype==v2.datatype); } void setatom(int op,expr arg1,expr arg2,expr result) { atm.type=op; atm.arg1=arg1; atm.arg2=arg2; atm.result=result; switch(op) { //Addition case 15: atm.op="ADD"; break; //Subtraction case 16: atm.op="SUB"; break; //Multiply case 17: atm.op="MUL"; break; //Division case 18: atm.op="DIV"; break; //Remainder case 19: atm.op="MOD"; break; //Assign case 26: atm.op="ASSIGN"; break; //Label case 25: atm.op="LABEL"; break; //Conditional Jump case 27: atm.op="CONDJUMP"; break; //Jump case 28: atm.op="JUMP"; break; //Return case 29: atm.op="RETURN"; break; //Param case 30: atm.op="PARAM"; break; //CALL case 31: atm.op="CALL"; break; //PROC_MARKER case 34: atm.op="PROC_MARKER"; break; //JUMPF case 8: case 9: case 10: case 11: case 12: case 13: atm.op="JUMPF"; break; //CMP case 108: case 109: case 110: case 111: case 112: case 113: atm.op="CMP"; //atm.type=op-100; break; default: cout<<" No Matching Found"; } atoms.push_back(atm); } int newlabel(void) { static long count=1; char name[10]; char temp[5]; ltoa(count,temp,10); strcpy(name,"L"); strcat(name,temp); string s1=name; labels.push_back(s1); count++; return(labels.size()-1); } long chk_func(long index) { string name=lex_identifier[index]; for(unsigned int j=0;j<syn_identifier.size();j++) { if(syn_identifier[j].name==name && syn_identifier[j].func_or_not==true) { table=0; return j; } } return -10; } void args_info(long index,long &init_arg,long &fin_arg) { init_arg=-10; fin_arg=-10; vector<int> temp; for(unsigned int j=0;j<args_identifier.size();j++) if(args_identifier[j].binding==index) temp.push_back(j); if(temp.size()!=0) { init_arg=temp[0]; fin_arg=temp[temp.size()-1]; } } int calc_param_offset() { int index=func_index; //Берёт индекс функции bool flag=false; int counter=0; int k=args_identifier.size()-1; int tot_len=0; while(index==func_index) { if(flag==false){ counter=6; args_identifier[k].offset=counter; counter+=args_identifier[k].datatype==0 ? 2 : 4; tot_len+=args_identifier[k].datatype==0 ? 2 : 4; flag=true; } else{ args_identifier[k].offset=counter; counter+=args_identifier[k].datatype==0 ? 2 : 4; tot_len+=args_identifier[k].datatype==0 ? 2 : 4; } k--; if(k<0) break; index=args_identifier[k].binding; } return tot_len; } int calc_local_offset() { int counter=0; for(unsigned int i=0;i<syn_identifier.size();i++) if(syn_identifier[i].binding==func_index) { counter+=syn_identifier[i].datatype==0 ? 2 : 4; syn_identifier[i].offset=counter; } return counter; } void syntax_box() { syn_index=0; input=tokens[syn_index]; scopecount=0; scopestack.push(scopecount); dump.index=-10; dump.datatype=-10; dump.whichtable=-10; program(); if(input.clas=="error") { } else { cout<<" Parser Failed Reasons: Bad syntaxys No 'main' function"; cout<<" Parser has parsed "<< syn_index+1 <<" Tokens "; } } void program() { if(input.clas=="dt") { int type=input.index; advanc(); if(input.clas=="id") { int index=input.index; settype(index,type); advanc(); } else reject(); data_or_function(type); program(); } else if(input.clas=="void") { advanc(); function_or_main(); } else reject(); } void data_or_function(int type) { if(input.clas=="comma") { advanc(); if(input.clas=="id") { int index=input.index; settype(index,type); advanc(); } else reject(); data_or_function(type); } else if(input.clas=="semicolon") advanc(); else if(input.clas=="parenthesis_open") { isreturn=false; advanc(); argument_list(); if(input.clas=="parenthesis_close") advanc(); else reject(); function_body(); } else reject(); } void function_or_main() { if(input.clas=="main") { main_func=true; advanc(); if(input.clas=="parenthesis_open") advanc(); else reject(); if(input.clas=="void") advanc(); else reject(); if(input.clas=="parenthesis_close") advanc(); else reject(); function_body(); } else if(input.clas=="id") { settype(input.index,22); advanc(); if(input.clas=="parenthesis_open") advanc(); else reject(); argument_list(); if(input.clas=="parenthesis_close") advanc(); else reject(); function_body(); program(); } else reject(); } void function_body() { int start_atom,end_atom,total; start_atom=end_atom=total=-10; if(input.clas=="braces_open") { |
| 6 | if(main_func==true) { expr temp; temp.index=-1; temp.datatype=1; temp.whichtable=-10; setatom(34,temp,dump,dump); } else { expr temp; temp.index=func_index; temp.datatype=1; temp.whichtable=-10; setatom(34,temp,dump,dump); start_atom=atoms.size()-1; } scopecount++; scopestack.push(scopecount); advanc(); variable_declarations(); statements(); if(input.clas=="braces_close") { if((scopestack.size()-1)>0) scopestack.pop(); else reject(); advanc(); } else reject(); if(main_func==true) { expr temp; temp.index=-1; temp.datatype=0; temp.whichtable=-10; setatom(34,temp,dump,dump); } else { expr temp; temp.index=func_index; temp.datatype=0; temp.whichtable=-10; setatom(34,temp,dump,dump); end_atom=atoms.size()-1; } if(func_index!=-10) { total=calc_local_offset(); atoms[start_atom].arg1.whichtable=total; atoms[end_atom].arg1.whichtable=total; } if(func_index!=-10) { if(isreturn!=true&& syn_identifier[func_index].datatype!=22/*Shldn't Be void*/) { cout<<endl<<"Fucntion named "<< syn_identifier[func_index].name <<" Shld return "<< syn_identifier[func_index].datatype <<endl; reject(); } } main_func=false; func_index=-10; isreturn=false; } else reject(); } void variable_declarations() { if(input.clas=="dt") { int type=input.index; advanc(); if(input.clas=="id") { int index=input.index; settype(index,type); advanc(); } else reject(); variable_list(type); if(input.clas=="semicolon") advanc(); else reject(); variable_declarations(); } else if(input.clas=="id" || input.clas=="braces_open" || input.clas=="while" || input.clas=="for" || input.clas=="do" || input.clas=="return" || input.clas=="if" || input.clas=="square_open" || input.clas=="braces_close" ) { } else reject(); } void variable_list(int type) { if(input.clas=="comma") { advanc(); if(input.clas=="id") { int index=input.index; settype(index,type); advanc(); } else reject(); variable_list(type); } else if(input.clas=="semicolon") { } else reject(); } void argument_list() { if(input.clas=="void") { ident.name="void"; ident.datatype=22; ident.scope=-10; ident.binding=syn_identifier.size()-1; ident.func_or_not=false; ident.type=3; ident.offset=-10; ident.xtra=-10; args_identifier.push_back(ident); int ind=syn_identifier.size()-1; ident=syn_identifier[ind]; ident.func_or_not=true; syn_identifier[ind]=ident; func_index=ind; advanc(); } else if(input.clas=="dt") { int type=input.index; advanc(); if(input.clas=="id") { int index=input.index; settype_args(index,type); advanc(); } else reject(); argument(); int ind=syn_identifier.size()-1; ident=syn_identifier[ind]; ident.func_or_not=true; syn_identifier[ind]=ident; func_index=ind; int ret=calc_param_offset(); syn_identifier[ind].xtra=ret; } else reject(); } void argument() { if(input.clas=="comma") { int type; advanc(); if(input.clas=="dt") { type=input.index; advanc(); } else reject(); if(input.clas=="id") { int index=input.index; settype_args(index,type); advanc(); } else reject(); argument(); } else if(input.clas=="parenthesis_close") { } else reject(); } void compound_statement() { if(input.clas=="braces_open") { advanc(); statements(); if(input.clas=="braces_close") advanc(); else reject(); } else reject(); } void statements() { if(input.clas=="id"||input.clas=="braces_open"||input.clas=="while"|| input.clas=="for"||input.clas=="do"||input.clas=="return"|| input.clas=="if"||input.clas=="square_open") { statement(); statements(); } else if(input.clas=="braces_close") { } else reject(); } void statement() { if(input.clas=="id") { long ind=chk_ident(long(input.index)); if(ind==-10) { cout<<" Failed in <Statement>-->id=<right_hand_side>;"; cout<<" Variable Not Found "; reject(); } expr t; t.index=ind; t.whichtable=table; if(table==0) t.datatype=syn_identifier[ind].datatype; else if(table==1) t.datatype=args_identifier[ind].datatype; advanc(); if(input.clas=="assignop") advanc(); else reject(); expr r; right_hand_side(r); if(input.clas=="semicolon") advanc(); else reject(); if(chk_types(t,r)==true) { setatom(26,r,dump,t); } else { cout<<" Type of id != <right_hand_side>"; reject(); } } else if(input.clas=="braces_open") { compound_statement(); } else if(input.clas=="while") { expr temp; int start=newlabel(); int end=newlabel(); temp.datatype=25; temp.index=start; temp.whichtable=4; setatom(25,dump,dump,temp); advanc(); if(input.clas=="parenthesis_open") advanc(); else reject(); expr k; expression(k); if(input.clas=="parenthesis_close") advanc(); else reject(); temp.datatype=25; temp.index=end; temp.whichtable=4; expr temp1; temp1.datatype=0; temp1.index=-10; temp1.whichtable=-10; setatom(27,k,temp1,temp); statement(); temp.datatype=25; temp.index=start; temp.whichtable=4; setatom(28,dump,dump,temp); temp.datatype=25; temp.index=end; temp.whichtable=4; setatom(25,dump,dump,temp); } else if(input.clas=="for") { int start=newlabel(); int end=newlabel(); int t_1=newlabel(); int t_2=newlabel(); expr i,e,s,i2,e2,ed,t1,t2,i4,e4; int r; s.index=start; s.datatype=25; s.whichtable=4; ed.index=end; ed.datatype=25; ed.whichtable=4; t1.index=t_1; t1.datatype=25; t1.whichtable=4; t2.index=t_2; t2.datatype=25; t2.whichtable=4; advanc(); if(input.clas=="parenthesis_open") advanc(); else reject(); if(input.clas=="id") { long ind=chk_ident(long(input.index)); if(ind==-10) { cout<<" Failed in <Statement>-->for(id=<expression>.......;"; cout<<" Variable Not Found "; reject(); } i.index=ind; i.whichtable=table; if(table==0) i.datatype=syn_identifier[ind].datatype; else if(table==1) i.datatype=args_identifier[ind].datatype; advanc(); } else reject(); if(input.clas=="assignop") advanc(); else reject(); expression(e); if(chk_types(i,e)==true) setatom(26,e,dump,i); else { cout<<" Type of id!!!!!!!======<right_hand_side>"; reject(); } if(input.clas=="semicolon") advanc(); else reject(); setatom(25,dump,dump,s); if(input.clas=="id") { long ind=chk_ident(long(input.index)); if(ind==-10) { cout<<" Failed in <Statement>-->for(id=<expression>.......;"; cout<<" Variable Not Found "; reject(); } i2.index=ind; i2.whichtable=table; if(table==0) i2.datatype=syn_identifier[ind].datatype; else if(table==1) i2.datatype=args_identifier[ind].datatype; advanc(); } else reject(); if(input.clas=="relop") { r=input.index; advanc(); } else reject(); expression(e2); if(chk_types(i2,e2)!=true) { cout<<" Type of id!!!!!!!======<right_hand_side>"; reject(); } setatom(r,i2,e2,ed); setatom(28,dump,dump,t1); if(input.clas=="semicolon") advanc(); else reject(); setatom(25,dump,dump,t2); if(input.clas=="id") { long ind=chk_ident(long(input.index)); if(ind==-10) { cout<<" Failed in <Statement>-->for(id=<expression>.......;"; cout<<" Variable Not Found "; reject(); } i4.index=ind; i4.whichtable=table; if(table==0) i4.datatype=syn_identifier[ind].datatype; else if(table==1) i4.datatype=args_identifier[ind].datatype; advanc(); } else reject(); if(input.clas=="assignop") advanc(); else reject(); expression(e4); if(chk_types(i4,e4)==true) setatom(26,e4,dump,i4); else { cout<<" Type of id!!!!!!!======<right_hand_side>"; reject(); } setatom(28,dump,dump,s); if(input.clas=="parenthesis_close") advanc(); else reject(); setatom(25,dump,dump,t1); statement(); setatom(28,dump,dump,t2); setatom(25,dump,dump,ed); } else if(input.clas=="do") { int start=newlabel(); expr temp; temp.datatype=25; temp.index=start; temp.whichtable=4; setatom(25,dump,dump,temp); advanc(); compound_statement(); if(input.clas=="while") advanc(); else reject(); if(input.clas=="parenthesis_open") advanc(); else reject(); expr k; expression(k); if(input.clas=="parenthesis_close") advanc(); else reject(); if(input.clas=="semicolon") advanc(); else reject(); expr temp1; temp1.datatype=1; temp1.index=-10; temp1.whichtable=-10; setatom(27,k,temp1,temp); } else if(input.clas=="return") { isreturn=true; advanc(); expr r; right_hand_side(r); int t=args_identifier[args_identifier.size()-1].binding; expr temp; temp.datatype=syn_identifier[t].datatype; temp.index=t; temp.whichtable=0; if(chk_types(temp,r)!=true) { if(func_index!=-10) cout<<" Function "<<syn_identifier[t].name << " is trying to Return mismatching datatype "<< r.datatype; else cout<<" Function void main(void) is trying to Return a Value"; reject(); } if(input.clas=="semicolon") advanc(); else reject(); setatom(29,temp,dump,r); } else if(input.clas=="if") { int end=newlabel(); int end2=newlabel(); advanc(); if(input.clas=="parenthesis_open") advanc(); else reject(); expr k; expression(k); if(input.clas=="parenthesis_close") advanc(); else reject(); expr temp1; temp1.datatype=0; temp1.index=-10; temp1.whichtable=-10; expr temp; temp.datatype=25; temp.index=end; temp.whichtable=4; setatom(27,k,temp1,temp); statement(); temp.datatype=25; temp.index=end2; temp.whichtable=4; setatom(28,dump,dump,temp); temp.datatype=25; temp.index=end; temp.whichtable=4; setatom(25,dump,dump,temp); optional_else(); temp.datatype=25; temp.index=end2; temp.whichtable=4; setatom(25,dump,dump,temp); } else if(input.clas=="square_open") { advanc(); expr f; function_call(f); if(input.clas=="square_close") advanc(); else reject(); if(input.clas=="semicolon") advanc(); else reject(); if(f.datatype!=22) { cout<<endl<<"Fucntion named "<<syn_identifier[f.index].name <<" is returning a value,Which is Not being CAUGHT"; reject(); } } else reject(); } void optional_else() { if(input.clas=="else") { advanc(); statement(); } else if(input.clas=="id"||input.clas=="while"||input.clas=="braces_open"|| input.clas=="for"||input.clas=="do"||input.clas=="return"|| input.clas=="if"||input.clas=="braces_close"||input.clas=="square_open") { } else reject(); } void right_hand_side(expr &r) { if(input.clas=="parenthesis_open" ||input.clas=="id" ||input.clas=="int_const" || input.clas=="long_const") { expression(r); } else if(input.clas=="square_open") { advanc(); function_call(r); if(input.clas=="square_close") advanc(); else reject(); if(r.datatype!=22) { for(unsigned int i=0;i<atoms.size();i++) if(atoms[i].type==29 && atoms[i].arg1.index==r.index) { r=atoms[i].result; break; } } else{ cout<<endl<<"Fucntion named "<<syn_identifier[r.index].name <<"is returning a void."; reject(); } } else reject(); } void function_call(expr &f) { if(input.clas=="id") { expr temp; long indx=chk_func(input.index); int no_args=-10; if(indx==-10) { cout<<" Failed in <function_call>-->id=(<optional_expression_list>)"; cout<<" Using Undefined Fuction--> "<< lex_identifier[input.index]; reject(); } f.index=indx; f.datatype=syn_identifier[indx].datatype; f.whichtable=table; args_info(indx,init_arg,fin_arg); if(args_identifier[init_arg].datatype!=22) no_args=(fin_arg-init_arg)+1; else no_args=0; temp.datatype=-10; temp.index=no_args; temp.whichtable=-10; advanc(); if(input.clas=="parenthesis_open") advanc(); else reject(); optional_expression_list(); if(input.clas=="parenthesis_close") advanc(); else reject(); if(args_identifier[init_arg].datatype!=22) { if(init_arg <= fin_arg) { cout<<" Less arguments are passed to function " << syn_identifier[indx].name; reject(); } if((init_arg-1) > fin_arg) { cout<<" More arguments are passed to function " << syn_identifier[indx].name; reject(); } } setatom(31,temp,dump,f); } else reject(); } void optional_expression_list() { if(input.clas=="parenthesis_close") { } else if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const" || input.clas=="square_open" ) { expression_list_element(); expression_listf(); } else reject(); } void expression_listf() { if(input.clas=="comma") { advanc(); expression_list_element(); expression_listf(); } else if(input.clas=="parenthesis_close") { } else reject(); } void expression_list_element() { if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const") { expr k; expr temp; temp.index=init_arg; temp.datatype=args_identifier[init_arg].datatype; temp.whichtable=1; expression(k); if(init_arg > fin_arg) { cout<<" void expression_list_element() More arguments are passed to function " << syn_identifier[args_identifier[fin_arg].binding].name; reject(); } if(chk_types(k,temp)==true) { setatom(30,dump,dump,k); } else { cout<<"Type mismatched in passing arguments to Fucntion " << syn_identifier[args_identifier[fin_arg].binding].name; reject(); } init_arg++; } else if(input.clas=="square_open") { advanc(); expr f; function_call(f); if(input.clas=="square_close") advanc(); else reject(); } else reject(); } void expression(expr &k) { if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const") { expr t1; arithmetic(t1); relational(k,t1); } else reject(); } void relational(expr &k,expr &t1) { if(input.clas=="relop") { int op=input.index; advanc(); expr t2; arithmetic(t2); if(chk_types(t1,t2)==true) { k=newtemp(t2.datatype); setatom(op+100,t1,t2,k); } else { cout<<" Failed in <Relational>--->.... "<<t1.index <<" is different from "<<t2.index; reject(); } } else if(input.clas=="parenthesis_close" ||input.clas=="semicolon" ||input.clas=="comma") { k=t1; } else reject(); } void arithmetic(expr &p) { if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const") { expr p1; t(p1); subtract(p1,p); } else reject(); } void subtract(expr p,expr &q) { if(input.clas=="add_sub" && input.index==16) { advanc(); expr q1; t(q1); if(chk_types(p,q1)==true) { expr r1=newtemp(p.datatype); setatom(16,p,q1,r1); subtract(r1,q); } else { cout<<" Failed in <Subract>--->"<< p.index<<" is different from "<<q1.index; reject(); } } else if(input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" || input.clas=="comma") { q=p; } else reject(); } void t(expr &p) { if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const" ) { expr p1; u(p1); add(p1,p); } else reject(); } void add(expr p,expr &q) { if(input.clas=="add_sub" && input.index==15) { advanc(); expr q1; u(q1); if(chk_types(p,q1)==true) { expr r1=newtemp(p.datatype); setatom(15,p,q1,r1); add(r1,q); } else { cout<<" Failed in <Add>--->"<< p.index<<" is different from "<<q1.index; reject(); } } else if(input.clas=="add_sub" || input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" || input.clas=="comma") { q=p; } else reject(); } void u(expr &p) { if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const" ) { expr p1; v(p1); multiply(p1,p); } else reject(); } void multiply(expr p,expr &q) { if(input.clas=="mul_div_mod" && input.index==17 ) { advanc(); expr q1; v(q1); if(chk_types(p,q1)==true) { expr r1=newtemp(p.datatype); setatom(17,p,q1,r1); multiply(r1,q); } else { cout<<" Failed in <Multiply>--->"<<p.index<<" is different from "<<q1.index; reject(); } } else if(input.clas=="add_sub" || input.clas=="add_sub" || input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" || input.clas=="comma" ) { q=p; } else reject(); } void v(expr &p) { if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const") { expr p1; w(p1); divide(p1,p); } else reject(); } void divide(expr p,expr &q) { if(input.clas=="mul_div_mod" && input.index==18) { advanc(); expr q1; w(q1); if(chk_types(p,q1)==true) { expr r1=newtemp(p.datatype); setatom(18,p,q1,r1); divide(r1,q); } else { cout<<" Failed in <Divide>--->"<<p.index<<" is different from "<<q1.index; reject(); } } else if(input.clas=="mul_div_mod" || input.clas=="add_sub" || input.clas=="add_sub" || input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" || input.clas=="comma") { q=p; } else reject(); } void w(expr &p) { if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const") { expr p1; x(p1); mod(p1,p); } else reject(); } void mod(expr p,expr &q) { if(input.clas=="mul_div_mod" && input.index==19) { advanc(); expr q1; x(q1); if(chk_types(p,q1)==true) { expr r1=newtemp(p.datatype); setatom(19,p,q1,r1); mod(r1,q); } else { cout<<" Failed in <Mod>---> "<< p.index<<"is different from "<< q1.index; reject(); } } else if(input.clas=="mul_div_mod" || input.clas=="mul_div_mod" || input.clas=="add_sub" || input.clas=="add_sub" || input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" || input.clas=="comma") { q=p; } else reject(); } void x(expr &p) { if(input.clas=="parenthesis_open") { advanc(); expression(p); if(input.clas=="parenthesis_close") advanc(); else reject(); } else if(input.clas=="id") { long indx=chk_ident(input.index); if(indx!=-10) { p.index=indx; p.whichtable=table; if(table==0) p.datatype=syn_identifier[indx].datatype; else if(table==1) p.datatype=args_identifier[indx].datatype; } else { cout<<" Failed in <X>-->...." <<" Variable "<<lex_identifier[input.index]<<" Not Found "; reject(); } advanc(); } else if(input.clas=="int_const") { p.datatype=23; p.index=input.index; p.whichtable=3; advanc(); } else if(input.clas=="long_const") { p.datatype=24; p.index=input.index; p.whichtable=2; advanc(); } else reject(); } ///**********************/// ///**********************/// /// /// /// Генератор кода /// /// /// ///**********************/// ///**********************/// // //Глобальные переменные генератора // ofstream code(FILE_WRITE); bool collect_ebx=false; void mangle_globals(); string name_resolve(expr& e); void putvariables(); string number2string(long count); string jcond4cmps(int& indx); string jcond4jumpf(int& indx); void proc_marker(atom& atm); void adds(atom& atm); void assign(atom& atm); void subs(atom& atm); void mul(atom& atm); void divs(atom& atm); void label(atom& atm); void jump(atom& atm); void cmps(atom& atm); void condjump(atom& atm); void jumpf(atom& atm); void call(atom& atm); void param(atom& atm); void returns(atom& atm); void mangle_globals() { for(unsigned int i=0;i<syn_identifier.size();i++) if(syn_identifier[i].binding==-2 && syn_identifier[i].func_or_not==false) { syn_identifier[i].name="g"+syn_identifier[i].name; } } void putvariables() { for(unsigned int i=0;i<syn_identifier.size();i++) if((syn_identifier[i].binding==-2 || syn_identifier[i].binding==-1) && syn_identifier[i].func_or_not==false) { if(syn_identifier[i].datatype==0 ||syn_identifier[i].datatype==23) code<<syn_identifier[i].name<<" dw "<<0<<endl; else code<<syn_identifier[i].name<<" dd "<<0<<endl; } } void proc_marker(atom& atm) { switch(atm.arg1.datatype) { //For Start Of Fucntion case 1: { switch(atm.arg1.index) { //It's main() case -1: code<<"main proc"<<endl <<"mov eax,@data"<<endl <<"mov ds,ax"<<endl; break; //It's an Ordinary Function default: code<<syn_identifier[atm.arg1.index].name <<" proc"<<endl <<"push bp"<<endl <<"mov bp,sp"<<endl <<"sub sp,"<<atm.arg1.whichtable<<endl; } } break; //For End Of Fucntion case 0: { switch(atm.arg1.index) { //It's main() case -1: code<<"mov ax,4c00h"<<endl <<"int 21h"<<endl <<"main endp"<<endl; break; //It's an Ordinary Function default: code<<"add sp,"<<atm.arg1.whichtable<<endl <<"pop bp"<<endl <<"ret"<<endl <<syn_identifier[atm.arg1.index].name <<" endp"<<endl; } } break; default: cout<<endl<<"Error in Fucntion Tagging"; exit(-1); } } string name_resolve(expr& e) { string name; switch(e.whichtable) { //Belongs to number_long case 2: name+=number2string(number_long[e.index]); break; //Belongs to number_int case 3: name+=number2string(number_int[e.index]); break; //Belongs to syn_identifier case 0: //If it Belongs to an Ordinary Fucntion if(syn_identifier[e.index].offset!=-10) { name+="[bp-"; name+=number2string(syn_identifier[e.index].offset); name+="]"; } //else it Belongs to a main() or a global variable else name=syn_identifier[e.index].name; break; //Belongs to args_identifier case 1: name+="[bp+"; name+=number2string(args_identifier[e.index].offset); name+="]"; break; } return name; } string number2string(long count) { char name[40]; char temp[40]; ltoa(count,temp,10); strcpy(name,temp); return string(name); } void adds(atom& atm) { if(atm.result.datatype==0) { code<<"push cx"<<endl //16 бит регистр <<"mov cx,0"<<endl <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl <<"add cx,word ptr "<<name_resolve(atm.arg2)<<endl <<"mov "<<name_resolve(atm.result)<<",cx"<<endl <<"pop cx"<<endl; } else { code<<"push ecx"<<endl //32 бит регистр <<"mov ecx,0"<<endl <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl <<"add ecx,dword ptr "<<name_resolve(atm.arg2)<<endl <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl <<"pop ecx"<<endl; } } void assign(atom& atm) { if(atm.result.datatype==0) { if(collect_ebx==true) { code<<"mov "<<name_resolve(atm.result)<<",bx"<<endl; collect_ebx=false; } else { code<<"push cx"<<endl <<"mov cx,0"<<endl <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl <<"mov "<<name_resolve(atm.result)<<",cx"<<endl <<"pop cx"<<endl; } } else { if(collect_ebx==true) { code<<"mov "<<name_resolve(atm.result)<<",ebx"<<endl; collect_ebx=false; } else { code<<"push ecx"<<endl <<"mov ecx,0"<<endl <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl <<"pop ecx"<<endl; } } } void subs(atom& atm) { if(atm.result.datatype==0) { code<<"push cx"<<endl <<"mov cx,0"<<endl <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl <<"sub cx,word ptr "<<name_resolve(atm.arg2)<<endl <<"mov "<<name_resolve(atm.result)<<",cx"<<endl <<"pop cx"<<endl; } else { code<<"push ecx"<<endl <<"mov ecx,0"<<endl <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl <<"sub ecx,dword ptr "<<name_resolve(atm.arg2)<<endl <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl <<"pop ecx"<<endl; } } void mul(atom& atm) { if(atm.result.datatype==0) { code<<"push cx"<<endl <<"mov cx,0"<<endl <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl <<"mov "<<name_resolve(atm.result)<<",cx"<<endl <<"mov cx,"<<name_resolve(atm.arg2)<<endl <<"imul cx,word ptr "<<name_resolve(atm.result)<<endl <<"mov "<<name_resolve(atm.result)<<",cx"<<endl <<"pop cx"<<endl; } else { code<<"push ecx"<<endl <<"mov ecx,0"<<endl <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl <<"mov ecx,dword ptr "<<name_resolve(atm.arg2)<<endl <<"imul ecx,"<<name_resolve(atm.result)<<endl <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl <<"pop ecx"<<endl; } } void divs(atom& atm) { if(atm.result.datatype==0) { code<<"push ax"<<endl <<"push cx"<<endl <<"push dx"<<endl <<"mov ax,0"<<endl <<"mov cx,0"<<endl <<"mov dx,0"<<endl <<"mov ax,word ptr "<<name_resolve(atm.arg1)<<endl <<"mov cx,word ptr "<<name_resolve(atm.arg2)<<endl <<"div cx"<<endl <<"mov "<<name_resolve(atm.result)<<",ax"<<endl <<"pop dx"<<endl <<"pop cx"<<endl <<"pop ax"<<endl; } else { code<<";Warning: Long Division is LOGICALLY FLAWED due to EAX"<<endl <<"push eax"<<endl <<"push ecx"<<endl <<"push edx"<<endl <<"mov eax,0"<<endl <<"mov ecx,0"<<endl <<"mov edx,0"<<endl <<"mov eax,dword ptr "<<name_resolve(atm.arg1)<<endl <<"mov ecx,dword ptr "<<name_resolve(atm.arg2)<<endl <<"div ecx"<<endl <<"mov "<<name_resolve(atm.result)<<",eax"<<endl <<"pop edx"<<endl <<"pop ecx"<<endl <<"pop eax"<<endl; } } void mods(atom& atm) { if(atm.result.datatype==0) { code<<"push ax"<<endl <<"push cx"<<endl <<"push dx"<<endl <<"mov ax,0"<<endl <<"mov cx,0"<<endl <<"mov dx,0"<<endl <<"mov ax,word ptr "<<name_resolve(atm.arg1)<<endl <<"mov cx,word ptr "<<name_resolve(atm.arg2)<<endl <<"div cx"<<endl <<"mov "<<name_resolve(atm.result)<<",dx"<<endl <<"pop dx"<<endl <<"pop cx"<<endl <<"pop ax"<<endl; } else { code<<";Warning: Long MOD is LOGICALLY FLAWED due to EAX"<<endl <<"push eax"<<endl <<"push ecx"<<endl <<"push edx"<<endl <<"mov eax,0"<<endl <<"mov ecx,0"<<endl <<"mov edx,0"<<endl <<"mov eax,dword ptr "<<name_resolve(atm.arg1)<<endl <<"mov ecx,dword ptr "<<name_resolve(atm.arg2)<<endl <<"div ecx"<<endl <<"mov "<<name_resolve(atm.result)<<",edx"<<endl <<"pop edx"<<endl <<"pop ecx"<<endl <<"pop eax"<<endl; } } void label(atom& atm) { code<<labels[atm.result.index]<<":"<<'\t'<<";It's a Label"<<endl; } void jump(atom& atm) { code<<"jmp "<<labels[atm.result.index]<<endl; } void cmps(atom& atm) { //генерит 2 лейбла int i=newlabel(); string set=labels[i]; i=newlabel(); string notset=labels[i]; //какой оператор использовать string jcond=jcond4cmps(atm.type); if(atm.result.datatype==0) { code<<"push cx"<<endl <<"mov cx,0"<<endl <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl <<"cmp cx,word ptr "<<name_resolve(atm.arg2)<<endl <<jcond<<" "<<set<<endl <<"mov "<<name_resolve(atm.result)<<",word ptr 0"<<endl <<"jmp "<<notset<<endl <<set<<":"<<endl <<"mov "<<name_resolve(atm.result)<<",word ptr 1"<<endl <<notset<<":"<<endl <<"pop cx"<<endl; } else { code<<"push ecx"<<endl <<"mov ecx,0"<<endl <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl <<"cmp ecx,dword ptr "<<name_resolve(atm.arg2)<<endl <<jcond<<" "<<set<<endl <<"mov "<<name_resolve(atm.result)<<",dword ptr 0"<<endl <<"jmp "<<notset<<endl <<set<<":"<<endl <<"mov "<<name_resolve(atm.result)<<",dword ptr 1"<<endl <<notset<<":"<<endl <<"pop ecx"<<endl; } } string jcond4cmps(int& indx) { string op; switch(indx) { case 8: op="je"; break; case 9: op="jne"; break; case 10: op="jge"; break; case 11: op="jle"; break; case 12: op="jg"; break; case 13: op="jl"; break; } return op; } void condjump(atom& atm) { if(atm.arg1.datatype==0) code<<"cmp "<<name_resolve(atm.arg1)<<",word ptr "<<atm.arg2.datatype<<endl <<"je "<<labels[atm.result.index]<<endl; else code<<"cmp "<<name_resolve(atm.arg1)<<",dword ptr "<<atm.arg2.datatype<<endl <<"je "<<labels[atm.result.index]<<endl; } void jumpf(atom& atm) { string jcond=jcond4jumpf(atm.type); if(atm.arg1.datatype==0) { code<<"mov cx,0"<<endl <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl <<"cmp cx,word ptr "<<name_resolve(atm.arg2)<<endl <<jcond<<" "<<labels[atm.result.index]<<endl; } else { code<<"mov ecx,0"<<endl <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl <<"cmp ecx,dword ptr "<<name_resolve(atm.arg2)<<endl <<jcond<<" "<<labels[atm.result.index]<<endl; } } string jcond4jumpf(int& indx) { string op; switch(indx) { case 8: op="jne"; break; case 9: op="je"; break; case 10: op="jnge"; break; case 11: op="jnle"; break; case 12: op="jng"; break; case 13: op="jnl"; break; } return op; } void call(atom& atm) { int data_type=atm.result.datatype; int pushed_values=syn_identifier[atm.result.index].xtra; code<<"call "<<syn_identifier[atm.result.index].name<<endl; if(pushed_values!=-10) { for(int i=0;i<pushed_values;i+=2) code<<"pop ax"<<endl; } if(data_type!=22) collect_ebx=true; } void param(atom& atm) { switch(atm.result.datatype) { case 0: case 23: code<<"mov cx,word ptr "<<name_resolve(atm.result)<<endl <<"push cx"<<endl; break; case 1: case 24: code<<"mov ecx,dword ptr "<<name_resolve(atm.result)<<endl <<"push ecx"<<endl; break; } } void returns(atom& atm) { switch(atm.result.datatype) { case 0: case 23: code<<"mov bx,word ptr "<<name_resolve(atm.result)<<endl; break; case 1: case 24: code<<"mov ebx,dword ptr "<<name_resolve(atm.result)<<endl; break; } } //сам генератор void code_generator() { int atmtype; mangle_globals(); code<</*"page ,"<<132*/endl <<"*** Assemblied By ZeddTranslator *** "<<endl <<endl<<".model medium"<<endl <<".stack 200h"<<endl <<".386"<<endl <<".code"<<endl; //Start Processing ATOMS. for(unsigned int k=0;k<atoms.size();k++) { atmtype=atoms[k].type; switch(atmtype) { //PROC_MARKER case 34: proc_marker(atoms[k]); break; //ADD case 15: adds(atoms[k]); break; //ASSIGN case 26: assign(atoms[k]); break; //SUB case 16: subs(atoms[k]); break; //MUL case 17: mul(atoms[k]); break; //DIV case 18: divs(atoms[k]); break; //DIV case 19: mods(atoms[k]); break; //LABEL case 25: label(atoms[k]); break; //JUMP case 28: jump(atoms[k]); break; //CMP case 108: case 109: case 110: case 111: case 112: case 113: atoms[k].type=atoms[k].type-100; //восстановить оригинальный ид cmps(atoms[k]); break; //CONDJUMP case 27: condjump(atoms[k]); break; //JUMPF case 8: case 9: case 10: case 11: case 12: case 13: jumpf(atoms[k]); break; //CALL case 31: call(atoms[k]); break; //PARAM case 30: param(atoms[k]); break; //RETURN case 29: returns(atoms[k]); break; }//End Switch }//End Processing ATOMS. //добавление финального кода code<<".data"<<endl; putvariables(); code<<"end main"<<endl; code.close(); } |
Комментарии