基于扩展C0文法的编译器设计(Part3)
来源:互联网 发布:ubuntu显示桌面图标 编辑:程序博客网 时间:2024/05/22 09:54
代码
main.cpp
#include <iostream>#include <string>#include <fstream>#include <sstream>#include <string.h>#include "asm.cpp"#define after_switch 1using namespace std ;int main(){ string fileName ; cin >> fileName ; //const char* fileName = "code8.txt" ; src.open(fileName.c_str(), ios::in) ; result.open("result.txt", ios::out) ; _gramma.open("gramma.txt", ios::out) ; outputfile.open("midcode.txt", ios::out) ; afteroutputfile.open("aftermidcode.txt", ios::out) ; rstfile.open("asmcode.asm", ios::out) ; if(!src.is_open()){ cout << "file open failed" << endl ; return -1 ; } init() ; getsym() ; program() ; stt() ; if(!after_switch){ run() ; } combine() ; if(after_switch){ run() ; } result.close() ; src.close() ; _gramma.close() ; outputfile.close() ; afteroutputfile.close() ; rstfile.close() ; getchar() ; return 0;}
lex.cpp
#include <iostream>#include <string>#include <fstream>#include <sstream>#include <string.h>#include "error.cpp"/** * author by JiaKai Wang,2016/11/7 * a lexical analysis program */////////////////////reversed word id//////#define INTSYM 1 // int#define CHARSYM 2 // char#define CONSTSYM 3 // const#define MAINSYM 4 // main#define IFSYM 5 // if#define ELSESYM 6 // else#define DOSYM 7 // do#define WHILESYM 8 // while#define VOIDSYM 9 // void#define FORSYM 10 // for#define SCANFSYM 11 // scanf#define PRINTFSYM 12 // printf#define RETURNSYM 13 // return#define IDSYM 14 // identifier#define PLUSSYM 15 // +#define MINUSSYM 16 // -#define MULTISYM 17 // *#define DIVSYM 18 // /#define BIGTHSYM 19 // >#define SMALLTHSYM 20 // <#define NOTBTHSYM 21 // <=#define NOTSTHSYM 22 // >=#define EQUSYM 23 // ==#define NOTESYM 24 // !=#define COMMASYM 24 // ,#define LBPARENSYM 25 // {#define RBPARENSYM 26 // }#define LMPARENSYM 27 // [#define RMPARENSYM 28 // ]#define LPARENSYM 29 // (#define RPARENSYM 30 // )#define SQUOTESYM 31 // '#define DQUOTESYM 32 // "#define ASSIGNSYM 33 // =#define STRINGSYM 34 // "it's a string"#define COLONSYM 35 // :#define SEMICSYM 36 // ;#define DIGSYM 37 // number//////////////////////warning///////////////////#define WARNING "warning"#define WARNING_0SURPLUS 1 // 012344//////////////////////error/////////////////////#define ERROR "error"#define ERROR_OPERATION 2 // !#define ERROR_FORMAT 3 // ' ' " "#define ERROR_SYMBOL 4////////////////////////////////////////////////using namespace std;/** * what to distinguishe * identifier //word start (word and num permitted) * reserved //int char const main if else do while void for scanf printf return * string //' ','!','#','"'(need \),'$',...'~' * op // + - * / > >= < <= == != * symbol //( ) { } [ ] ' ' " " , * num //only int and start with 0 is not permitted * * global variable : token(save string),num(save number),ch(save char),indexInLine(save index of line counter), * indexInFile(save index of file counter),lenOfCLine(length of current line) */string word[] = {"int","char","const","main","if","else", "do","while","void","for","scanf","printf","return"} ;string wSymbol[] = {"INTSYM","CHARSYM","CONSTSYM","MAINSYM","IFSYM","ELSESYM", "DOSYM","WHILESYM","VOIDSYM","SCANFSYM","PRINTFSYM","RETURNSYM"} ;const int reversWordNum = 13 ;char line[512] ; // line bufferchar retypeLine[512] ; // error outputint indexInLine = 0 ;int indexInFile = 0 ;int lenOfCLine = 0 ;char token[512] ;int indexInToken ;string sym = "" ;int symId ;char ch = ' ';int num ;ifstream src ; // source fileofstream result ;ofstream _gramma ;int isTab(){ return ch == '\t' ? 1 : 0 ;}int isSpace(){ return ch == ' ' ? 1 : 0 ;}int isNewLine(){ return ch == '\n' ? 1 : 0 ;}int isLetter(){ return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') ? 1 : 0 ;}int isDigit(){ return ch <= '9' && ch >= '0' ? 1 : 0 ;}int isPlus(){ return ch == '+' ? 1 : 0 ;}int isMinus(){ return ch == '-' ? 1 : 0 ;}int isDiv(){ return ch == '/' ? 1 : 0 ;}int isMulti(){ return ch == '*' ? 1 : 0 ;}int isBigSym(){ return ch == '>' ? 1 : 0 ;}int isSamSym(){ return ch == '<' ? 1 : 0 ;}int isEquSym(){ return ch == '=' ? 1 : 0 ;}int isNotSym(){ return ch == '!' ? 1 : 0 ;}int isComma(){ return ch == ',' ? 1 : 0 ;}int isColon(){ return ch == ':' ? 1 : 0 ; }int isSemic(){ return ch == ';' ? 1 : 0 ; }int isLBParen(){ return ch == '{' ? 1 : 0 ;}int isRBParen(){ return ch == '}' ? 1 : 0 ;}int isLMParen(){ return ch == '[' ? 1 : 0 ;}int isRMParen(){ return ch == ']' ? 1 : 0 ;}int isLParen(){ return ch == '(' ? 1 : 0 ;}int isRParen(){ return ch == ')' ? 1 : 0 ;}int isChar(){ return ch == 32 || ch == 33 || (ch >= 35 && ch <= 126) ? 1 : 0 ;}int isSigQuote(){ return ch == '\'' ? 1 : 0 ;}int isDoubQuote(){ return ch == '\"' ? 1 : 0 ;}/** * [getch description]this part to read in a charactor */void getch(){ if(lenOfCLine == indexInLine){ indexInFile++ ; //cout << indexInFile + 1 << endl ; if(src.getline(line, 512) != NULL){ ; lenOfCLine = strlen(line) ; int i = lenOfCLine - 1 ; for( ; line[i] == ' ' || line[i] == '\t' ; i--){ line[i] = '\0' ; } lenOfCLine = i + 1 ; indexInLine = 0 ; ch = ' ' ; } } else{ ch = line[indexInLine] ; indexInLine++ ; }}/** * [getsym description]read in a symbol * @return [description]return a symbol id */void getsym(){ indexInToken = 0 ; //getch() ; if(ch == NULL){ return ; } while(isSpace() || isTab() || isNewLine()){ if(isNewLine()){ indexInLine = 0 ; } getch() ; } /** * if NULL,file finish and exit */ /** * [if description] identifier branch * @param isLetter [description] _ | a...z | A...Z * @return [description] 1-true | 0-false */ if(isLetter()){ while(isLetter() || isDigit()){ token[indexInToken++] = ch ; getch() ; } token[indexInToken] = '\0' ; //indexInLine-- ; int i ; for(i = 0 ; i < reversWordNum ; i++){ if(!strcmp(word[i].c_str(), token)){ //sym = wSymbol[i] ; symId = i+1 ; break ; } } if(i == reversWordNum){ sym = "IDSYM" ; symId = IDSYM ; } } /** * [if description] number branch * @param isDigit [description] 0...9 * @return [description] 1-true | 0-false */ else if(isDigit()){ sym = "DIGSYM" ; symId = DIGSYM ; num = 0 ; int flag = ch == '0' ? 1 : 0 ; while(isDigit()){ token[indexInToken++] = ch ; num = num * 10 + (int)(ch - '0') ; getch() ; } token[indexInToken] = '\0' ; if(flag == 1){ if(num != 0){ error(ZEROSTART_ERROR,indexInFile) ; // a number should not start with charactor '0' } } } /** * [if description] = and == branches * @param isEquSym [description] = * @return [description] 1-true | 0-false */ else if(isEquSym()){ token[indexInToken++] = ch ; sym = "ASSIGNSYM" ; symId = ASSIGNSYM ; getch() ; if(isEquSym()){ token[indexInToken++] = ch ; sym = "EQUSYM" ; symId = EQUSYM ; getch() ; } token[indexInToken] = '\0' ; } /** * [if description] > and >= * @param isBigSym [description] > * @return [description] 1-true | 0-false */ else if(isBigSym()){ token[indexInToken++] = ch ; sym = "BIGTHSYM" ; symId = BIGTHSYM ; getch() ; if(isEquSym()){ token[indexInToken++] = ch ; sym = "NOTSTHSYM" ; symId = NOTSTHSYM ; getch() ; } token[indexInToken] = '\0' ; } /** * [if description] < and <= * @param isSamSym [description] < * @return [description] 1-true | 0-fasle */ else if(isSamSym()){ token[indexInToken++] = ch ; sym = "SMALLTHSYM" ; symId = SMALLTHSYM ; getch() ; if(isEquSym()){ token[indexInToken++] = ch ; sym = "NOTBTHSYM" ; symId = NOTBTHSYM ; getch() ; } token[indexInToken] = '\0' ; } /** * [if description] != * @param isNotSym [description] ! * @return [description] 1-true | 0-false */ else if(isNotSym()){ token[indexInToken++] = ch ; getch() ; if(isEquSym()){ token[indexInToken++] = ch ; sym = "NOTESYM" ; symId = NOTESYM ; getch() ; } token[indexInToken] = '\0' ;/* else{ error(PRENOTONLY_ERROR,indexInFile) ; // ! can not appear by only return ; }*/ } /** * [if description] '(+|-|*|/|_|a...z|A...Z|0...9)' * @param isSigQuote [description] ' * @return [description] 1-true | 0-false */ else if(isSigQuote()){ getch() ; if(isPlus() || isMinus() || isMulti() || isDiv() || isLetter() || isDigit()){ token[indexInToken++] = ch ; getch() ; } else{ token[indexInToken] = '\0' ; error(UNDEFCHAR_ERROR,indexInFile) ; // ' ' } if(isSigQuote()){ sym = "CHARSYM" ; symId = CHARSYM ; getch() ; } else{ error(UNMATCHSQ_ERROR,indexInFile) ; } } /** * [if description] "(ascii == 32|33| [35,126])" * @param isDoubQuote [description] " * @return [description] 1-true | 0-false */ else if(isDoubQuote()){ char tempStr[512] ; int index = 0 ; getch() ; while(isChar()){ if(ch == '\\'){ tempStr[index++] = ch ; } tempStr[index++] = ch ; getch() ; } tempStr[index] = '\0' ; if(isDoubQuote()){ strcpy(token, tempStr) ; sym = "STRINGSYM" ; symId = STRINGSYM ; getch() ; } else{ error(UNMATCHDQ_ERROR,indexInFile) ; // a string must be surrounded by " " } } /** * other branches */ else { /** * branch , */ if(isComma()){ sym = "COMMASYM" ; symId = COMMASYM ; } /** * [if description] branch : * @param isColon [description] : * @return [description] 1-true | 0-false */ else if(isColon()){ sym = "COLONSYM" ; symId = COLONSYM ; } /** * [if description] branch ; * @param isSemic [description] ; * @return [description] 1-true | 0-false */ else if(isSemic()){ sym = "SEMICSYM" ; symId = SEMICSYM ; } /** * [if description] branch { * @param isLBParen [description] { * @return [description] 1-true | 0-false */ else if(isLBParen()){ sym = "LBPARENSYM" ; symId = LBPARENSYM ; } /** * [if description] branch } * @param isRBParen [description] } * @return [description] 1-true | 0-false */ else if(isRBParen()){ sym = "RBPARENSYM" ; symId = RBPARENSYM ; } /** * [if description] branch [ * @param isLMParen [description] [ * @return [description] 1-true | 0-false */ else if(isLMParen()){ sym = "LMPARENSYM" ; symId = LMPARENSYM ; } /** * [if description] branch ] * @param isRMParen [description] ] * @return [description] 1-true | 0-false */ else if(isRMParen()){ sym = "RMPARENSYM" ; symId = RMPARENSYM ; } /** * [if description] branch ( * @param isLParen [description] ( * @return [description] 1-true | 0-false */ else if(isLParen()){ sym = "LPARENSYM" ; symId = LPARENSYM ; } /** * [if description] branch ) * @param isRParen [description] ) * @return [description] 1-true | 0-false */ else if(isRParen()){ sym = "RPARENSYM" ; symId = RPARENSYM ; } else if(isPlus()){ sym = "PLUSSYM" ; symId = PLUSSYM ; } else if(isMinus()){ sym = "MINUSSYM" ; symId = MINUSSYM ; } else if(isMulti()){ sym = "MULTISYM" ; symId = MULTISYM ; } else if(isDiv()){ sym = "DIVSYM" ; symId = DIVSYM ; } token[indexInToken++] = ch ; token[indexInToken] = '\0' ; getch() ; } /** * means sym is an int */ if(!sym.compare("DIGSYM")){ //cout << sym << ':' << symId << ' ' << token << ' ' << num << endl ; result << sym << ':' << symId << ' ' << token << ' ' << num << endl ; } else{ //cout << sym << ':' << symId << ' ' << token << endl ; result << sym << ' ' << symId << ' ' << token << endl ; }}
grammar.cpp
#include <iostream>#include <string>#include <fstream>#include <sstream>#include <string.h>#include "lex.cpp"#include "midcode.cpp"/** * author by JiaKai Wang,2016/11/15 * a gramma analysis program *////////////////////////////////////////////////#define max 512#define maxPre 512#define maxTab 512///////////////////////////////////using namespace std ;/** * what to distinguishe * identifier //word start (word and num permitted) * reserved //int char const main if else do while void for scanf printf return * string //' ','!','#','"'(need \),'$',...'~' * op // + - * / > >= < <= == != * symbol //( ) { } [ ] ' ' " " , * num //only int and start with 0 is not permitted * * global variable : token(save string),num(save number),ch(save char),indexInLine(save index of line counter), * indexInFile(save index of file counter),lenOfCLine(length of current line) *//////////////////语法分析相关//////////////////////////////符号表相关///////////////typedef struct{ char name[max] ; //name of identifier int type ;//0-const 1-var 2-function 3-para int value ;//常量的值,特别的,如果标识符是一个函数名,则用1表示函数类型为int,0为void int address ;//标识符存储地址或者地址位移 int para ;//表示函数参数个数或者数组大小}symbol ;typedef struct{ symbol element[maxTab];//符号表 int index;//符号表栈顶指针, number of symbol table int toltalPre;//当前符号表拥有的分程序总数 int indexOfPre[maxPre];//分程序索引 find index in table}symbolTab ;symbolTab symTable ;char idName[max] ;int value ;int para ;int address ;int isArray ;int preSymId ;char preToken[max] ;int preIndex ;char preCh ;//in order to deal with the condition for( ; i ; )int isFor = 0 ;//in order to deal with the void returnint isVoid = 0 ;//in order to deal with the error read arrayint isArr = 0 ;//to deal not void func without ret valueint hasRet = 0 ;/////////////////四元式相关///////////////// outputfilechar temp[128] ;char nowitem[max] ; // save item resultint factorType ;char procname[512] ;int tempSym ;//just use in func definationint isconst ;int isMain = 0 ;//////////////对方法进行声明/////////////////////gramma analysevoid states() ;void item() ;void factor() ;void valueOfPara() ;void condition() ;void loopSta() ;void writeSta() ;void readSta() ;void returnSta() ;void conditionSta() ;void declHead() ;///symbol tablevoid pushSymTab(char* name, int type, int value, int address, int para) ;void insertSymTab(char* name, int type,int value, int address, int para) ;int searchSymTab(char* name) ;void insertPara(int para) ;void delSymTab() ;////////////////////symtable///////////////////////////////maybe use token/ num /symid/ in lexvoid insertSymTab(char* name, int type, int value, int address, int para){ if(symTable.index > maxTab){ error(OUTOFTABINDEXX_ERROR, indexInFile); return ; } pushSymTab(name, type, value, address, para); //output return ;}void insertPara(int para){ int i ; i = symTable.indexOfPre[symTable.toltalPre - 1] ; symTable.element[i].para = para ;}int searchSymTab(char* name, int flag){ //when use a id or a function name ,we should ensure if it is leagal isArr = 0 ; if(flag == 1){//search function name int i ; for(i = 1 ; i < symTable.toltalPre ; i++){ if(strcmp(symTable.element[symTable.indexOfPre[i]].name, name) == 0){ break ; } } if(i >= symTable.toltalPre){//use undefined identifier //cout << name << ": undefined function !" << endl ; return 0 ; } if(symTable.element[symTable.indexOfPre[i]].para != para){//checked paramenter error(PARANUM_ERROR, indexInFile) ; return -1 ; } //return symTable.element[symTable.indexOfPre[i]].address ; return 1 ; } else{//search id int i ; for(i = symTable.indexOfPre[symTable.toltalPre-1] ; i < symTable.index ; i++ ){ if(strcmp(symTable.element[i].name, name) == 0){ break ; } } if(i == symTable.index){//find in main symbolTable int i = 0 ; int n = symTable.indexOfPre[1] ;//end index of main symbolTable for( ; i < n ; i++){ if(strcmp(symTable.element[i].name, name) == 0){ break ; } } if(i == n){ cout << indexInFile << " : " << name << ": " << "undefined identifier!" << endl ; return 0 ; } if(symTable.element[i].type == 1){ factorType = symTable.element[i].value ; if(symTable.element[i].para != -1){ isArr = 1 ; } return symTable.element[i].address ; } if(symTable.element[i].type == 0){//const isconst = 1 ; return symTable.element[i].value ; } if(symTable.element[i].type == 3){//paramenter return -1 ; } } else{ if(symTable.element[i].type == 1){ factorType = symTable.element[i].value ; if(symTable.element[i].para != -1){ isArr = 1 ; } return symTable.element[i].address ; } if(symTable.element[i].type == 0){//const isconst = 1 ; return symTable.element[i].value ; } if(symTable.element[i].type == 3){//paramenter return -1 ; } } return 1 ; }}int arrLength(char* name){//once a array was used, search the length in symbol table, so that ensure it is lagal int i ; i = symTable.indexOfPre[symTable.toltalPre-1] ; for( ; i < symTable.index ; i++){ if(strcmp(symTable.element[i].name, name) == 0){ return symTable.element[i].para ; } } if(i == symTable.index){ i = 0 ; for( ; i < symTable.indexOfPre[1] ; i++){ if(strcmp(symTable.element[i].name, name) == 0){ return symTable.element[i].para ; } } } return -1 ;}void pushSymTab(char* name, int type, int value, int address, int para){ if(type == 2){ int i ; for(i = 1 ; i < symTable.toltalPre ; i++){ if(strcmp(symTable.element[symTable.indexOfPre[i]].name, name) == 0){ error(FUNCNAMECOMPLICT_ERROR,indexInFile) ; return ; } } if(i >= symTable.toltalPre){//function can be defined symTable.indexOfPre[symTable.toltalPre++] = symTable.index ; } } else{ int i = symTable.indexOfPre[symTable.toltalPre-1] ;// 查找当前符号表 for( ; i < symTable.index ; i++){ if(strcmp(symTable.element[i].name, name) == 0){ error(VARNAMECOMPLICT_ERROR,indexInFile) ; return ; } }/* if(type != 3){//if not paramenter, var or const cannot be multidefined i = 0 ; for(; i < symTable.indexOfPre[1] ; i++){ if(strcmp(symTable.element[i].name, name) == 0){ error(NAMECOMPLICTGLOBAL_ERROR,indexInFile) ; return ; } } } */ } strcpy(symTable.element[symTable.index].name, name) ; symTable.element[symTable.index].type = type ; symTable.element[symTable.index].value = value ; symTable.element[symTable.index].address = address ; symTable.element[symTable.index].para = para ; symTable.index++ ; //cout << "name: " << name << " type: " << type << " value: " << value << " address: " << address << " para: " << para << endl ;}void delSymTab(){}////////////////////gramma/////////** * [compoundSta description]声明头部子程序,仅针对又返回值函数使用 * <声明头部> ::= int<标识符>|char<标识符> */void declHead(){ if(symId == INTSYM || symId == CHARSYM){ getsym() ; if(symId != IDSYM){ error(DELHEAD_IDMIS_ERROR,indexInFile) ; return ; } strcpy(idName, token) ; value = -11 ; address = 0 ;//set as 0 tem para = 0 ; insertSymTab(idName, 2, value, address, para) ; strcpy(procname, idName) ; getsym() ; }}/** * [constDef description]常量定义子程序 * <常量定义> ::= int<标识符>=<整数>{,<标识符>=<整数>}| char<标识符>=<字符>{,<标识符>=<字符>} * 为了定义的简单,这里只考虑<标识符> = <整数(字符)> */void constDef(int type){ getsym() ; if(symId == IDSYM){ strcpy(idName, token) ; getsym() ; if(symId == ASSIGNSYM){ getsym() ; if(symId == PLUSSYM || symId == MINUSSYM){ int tempSymId = symId ;//record + / - getsym() ; if(type == INTSYM && symId == DIGSYM){ if(tempSymId == PLUSSYM){ value = num ; } else if(tempSymId == MINUSSYM){ value = 0 - num ; } //插入符号表 address++ ; para = -1 ; insertSymTab(idName, 0, value, address, para); //生成四元式 sprintf(temp, "%d", value) ; genMidCode(consts, ints, temp, idName) ; } } else if(type == CHARSYM && symId == CHARSYM){ value = token[0] ; //插入符号表 address++ ; para = -1 ; insertSymTab(idName, 0, value, address, para); //生成四元式 sprintf(temp, "%d", value) ; genMidCode(consts, chars, temp, idName) ; } else if(type == INTSYM && symId == DIGSYM){ value = num ; //插入符号表 address++ ; para = -1 ; insertSymTab(idName, 0, value, address, para); //生成四元式 sprintf(temp, "%d", value) ; genMidCode(consts, chars, temp, idName) ; } else{ error(AFTERASS_NOTIDEN_ERROR,indexInFile) ; return ; } _gramma << "it is a const defination " << endl ;// //cout << "it is a const defination " << endl ; } else{ error(CONSTDEF_ASSMIS_ERROR,indexInFile) ; return ; } }}/** * [constDecl description]常量声明子程序 * <常量说明> ::= const<常量定义>;{ const<常量定义>;} */void constDecl(){ //getsym() ; if(symId != CONSTSYM){ error(0,0) ;//this error will not appear return ; } getsym() ; int type ; type = symId == INTSYM ? INTSYM : (symId == CHARSYM ? CHARSYM : -1) ; if(type == -1){ error(CONSTDEF_TYPE_ERROR,indexInFile) ; return ; } do{ constDef(type) ; getsym() ; }while(symId == COMMASYM) ; if(symId == SEMICSYM){ getsym() ; if(symId == CONSTSYM){ constDecl() ; } else{ _gramma << "it is a const declariton " << endl ; //cout << "it is a const declariton finished" << endl ; //result << "it is a const declariton " << endl ; } } else{ error(SEMICSYMMIS_ERROR,indexInFile) ; return ; }}/** * [compoundSta description]变量定义子程序 * <变量定义> ::= <类型标识符>(<标识符>|<标识符>‘[’<无符号整数>‘]’){,(<标识符>|<标识符>‘[’<无符号整数>‘]’) } */void varDef(){ if(symId == INTSYM || symId == CHARSYM){ int tempType ; tempType = symId ; do{ para = 0 ; getsym() ; if(symId == IDSYM){ strcpy(idName, token) ;//name getsym() ; if(symId == LMPARENSYM){//array getsym() ; if(symId != DIGSYM){ error(VARDEF_ARRAYINDEX_ERROR,indexInFile) ; //read next ; skip read do{ getsym() ; }while(symId != SEMICSYM) ; return ; } para = num ;//para getsym() ; if(symId == RMPARENSYM){ value = tempType ; address += num ; insertSymTab(idName, 1, value, address, para); _gramma << "it is a array var defination" << endl ; //cout << "it is a array var defination" << endl ; if(tempType == INTSYM){ genMidCode(inta, space, para, idName) ; } else if(tempType == CHARSYM){ genMidCode(chara, space, para, idName) ; } } else{ error(RMPARENSYMMIS_ERROR,indexInFile) ; //read next ; skip read do{ getsym() ; }while(symId != SEMICSYM) ; return ; } getsym() ; } else{ value = tempType ; address++ ; para = -1 ; insertSymTab(idName, 1, value, address, para); _gramma << "it is a var defination" << endl ; //cout << "it is a var defination" << endl ; if(tempType == INTSYM){ genMidCode(ints, space, space, idName) ; } else if(tempType == CHARSYM){ genMidCode(chars, space, space, idName) ; } } } else{ error(VARDEF_TYPE_ERROR,indexInFile) ; //read next ; skip read do{ getsym() ; }while(symId != SEMICSYM) ; return ; } }while(symId == COMMASYM) ; //getsym() ; }}/** * [compoundSta description]变量声明子程序 * <变量说明> ::= <变量定义>;{<变量定义>;} */void varDecl(){ do{ varDef() ; if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; //read next int/char/void skip read do{ getsym() ; }while(symId != INTSYM && symId != CHARSYM && symId != VOIDSYM) ; return ; } getsym() ; } while(symId == INTSYM || symId == CHARSYM) ;}/** * [compoundSta description]复合语句子程序 */void compoundSta(){ if(symId == CONSTSYM){ constDecl() ; } if(symId == INTSYM || symId == CHARSYM){ varDecl() ; } states() ;}/** * [compoundSta description]主函数子程序 * <主函数> ::= void main‘(’‘)’ ‘{’<复合语句>‘}’ */void mainFunc(){ if(symId == VOIDSYM){ getsym() ; if(symId != MAINSYM){ error(MAINSYM_ERROR,indexInFile) ;//this may not appeared return ; } strcpy(idName, token) ; insertSymTab(idName, 2, -1, 0, 0) ; strcpy(procname, idName) ; genMidCode(func, space, space, procname) ; isMain = 1 ; getsym() ; if(symId != LPARENSYM){ error(LPARENSYMMIS_ERROR,indexInFile) ; //read next { skip read do{ getsym() ; }while(symId != LBPARENSYM) ; return ; } getsym() ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; //read next { skip read do{ getsym() ; }while(symId != LBPARENSYM) ; return ; } getsym() ; if(symId != LBPARENSYM){ error(LBPARENSYMMIS_ERROR,indexInFile) ; //skip read do{ getsym() ; }while(symId != CONSTSYM && symId != INTSYM && symId != CHARSYM && symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM) ; return ; } getsym() ; compoundSta() ; if(symId != RBPARENSYM){ error(RBPARENSYMMIS_ERROR,indexInFile) ; //skip read do{ getsym() ; }while(symId != CONSTSYM && symId != INTSYM && symId != CHARSYM && symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM) ; return ; } genMidCode(myend, space, space, procname) ; _gramma << "it is a main function" << endl ; //cout << "it is a main function" << endl ; getsym() ; }}/** * [compoundSta description]表达式子程序 * <表达式> ::= [+|-]<项>{<加法运算符><项>} */void expr(){ factorType = 0 ; char place1[256] ; char place2[256] ; char place3[256] ; if(symId == PLUSSYM || symId == MINUSSYM){ factorType = INTSYM ; if(symId == PLUSSYM){ getsym() ; item() ; strcpy(place3, nowitem) ; } if(symId == MINUSSYM){ getsym() ; item() ; strcpy(place1, nowitem) ; strcpy(place3, genVar()) ; char myzero[] = {'0','\0'} ; genMidCode(sub, myzero, place1, place3) ; // get -n } do{ if(symId == PLUSSYM || symId == MINUSSYM){ factorType = INTSYM ; strcpy(place1, place3) ; if(symId == PLUSSYM){ getsym() ; item() ; strcpy(place2, nowitem) ; strcpy(place3, genVar()) ; genMidCode(add, place1, place2, place3) ; } else if(symId == MINUSSYM){ getsym() ; item() ; strcpy(place2, nowitem) ; strcpy(place3, genVar()) ; genMidCode(sub, place1, place2, place3) ; } } }while(symId == PLUSSYM || symId == MINUSSYM) ; _gramma << "it is a expr" << endl ; strcpy(nowitem, place3) ; //cout << "it is a expr" << endl ; } else{ item() ; strcpy(place3, nowitem) ; do{ if(symId == PLUSSYM || symId == MINUSSYM){ factorType = INTSYM ; strcpy(place1, place3) ; if(symId == PLUSSYM){ getsym() ; item() ; strcpy(place2, nowitem) ; strcpy(place3, genVar()) ; genMidCode(add, place1, place2, place3) ; } else if(symId == MINUSSYM){ getsym() ; item() ; strcpy(place2, nowitem) ; strcpy(place3, genVar()) ; genMidCode(sub, place1, place2, place3) ; } } }while(symId == PLUSSYM || symId == MINUSSYM) ; _gramma << "it is a expr" << endl ; //cout << "it is a expr" << endl ; } strcpy(nowitem, place3) ;//save fianl value reg}/** * [compoundSta description]项子程序 * <项> ::= <因子>{<乘法运算符><因子>} */void item(){ char place1[128], place2[128], place3[256] ; factor() ; strcpy(place3, nowitem) ; // assign need temp variable to save result do{ if(symId == MULTISYM || symId == DIVSYM){ strcpy(place1, place3) ; if(symId == MULTISYM){ getsym() ; factor() ; strcpy(place2, nowitem) ; strcpy(place3, genVar()) ; genMidCode(mul, place1, place2, place3) ; } else if(symId == DIVSYM){ getsym() ; factor() ; strcpy(place2, nowitem) ; strcpy(place3, genVar()) ; genMidCode(divs, place1, place2, place3) ; } } }while(symId == MULTISYM || symId == DIVSYM) ; strcpy(nowitem, place3) ;}/** * [compoundSta description]因子子程序 * <因子> ::= <标识符>|<标识符>‘[’<表达式>‘]’|<整数>|<字符>|<有返回值函数调用语句>|‘(’<表达式>‘)’ * 需要注意,标识符和有返回值函数调用存在嵌套部分,即,二者均以symId == IDSYM 开始 */void factor(){ int t ; //record if id is leagal char place3[256] ; strcpy(place3, space) ; if(symId == IDSYM){ char tempIdName[max] ; strcpy(idName, token) ; strcpy(tempIdName, token) ; getsym() ; if(symId == LPARENSYM){//function call getsym() ; valueOfPara() ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != SEMICSYM) ; return ; } t = searchSymTab(tempIdName, 1) ; if(t == 0){ error(UNDEFFUNC_ERROR, indexInFile) ; } //cout << t << endl ; strcpy(place3, genVar()) ;// generate temp variable genMidCode(call, tempIdName, space, place3) ; strcpy(nowitem, place3) ; getsym() ; } else if(symId == LMPARENSYM){ //array getsym() ; int tempFactType = factorType ; expr() ; factorType = tempFactType ; char ttt[256] ;//not necessery strcpy(ttt, nowitem) ; if((nowitem[0] >= '0' && nowitem[0] <= '9') ? 1 : 0){ int arrLen = 0 ; arrLen = arrLength(idName) ; if(arrLen != -1 && atoi(ttt) >= arrLen){ cout << "Warning " << indexInFile << endl ; } } if(symId != RMPARENSYM){ error(RMPARENSYMMIS_ERROR,indexInFile) ; //array ] missed do{ getsym() ; }while(symId != SEMICSYM && symId != ASSIGNSYM && symId != PLUSSYM && symId != MINUSSYM && symId != MULTISYM && symId != DIVSYM && symId != RPARENSYM && symId != COMMASYM && symId != BIGTHSYM && symId != SMALLTHSYM && symId != NOTBTHSYM && symId != NOTSTHSYM && symId != EQUSYM && symId != NOTESYM); return ; } t = searchSymTab(tempIdName, 0) ; //cout << t << endl ; strcpy(nowitem, genVar()) ; genMidCode(aAssign, tempIdName, ttt, nowitem) ; getsym() ; } else{//identifier, is variable t = searchSymTab(idName, 0) ; //cout << t << endl ; if(isconst){ strcpy(nowitem, int2array(t)) ; isconst = 0 ; } else{ strcpy(nowitem, idName) ; } } }//‘(’’表达式')' else if(symId == LPARENSYM){ getsym() ; expr() ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; // do{ getsym() ; }while(symId != SEMICSYM && symId != MULTISYM && symId != DIVSYM && symId != RPARENSYM && symId != RMPARENSYM && symId != BIGTHSYM && symId != SMALLTHSYM && symId != NOTBTHSYM && symId != NOTSTHSYM && symId != EQUSYM && symId != NOTESYM && symId != PLUSSYM && symId != MINUSSYM) ; return ; } getsym() ; } else if(symId == DIGSYM || symId == PLUSSYM || symId == MINUSSYM){ if(symId == PLUSSYM || symId == MINUSSYM){//integer with +/- symbol int sign ; sign = symId == PLUSSYM ? 1 : -1 ; getsym() ; //int flag = symId == PLUSSYM ? 1 : 0 ; if(symId != DIGSYM){ error(AFTEROP_NUMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != SEMICSYM && symId != MULTISYM && symId != DIVSYM && symId != RPARENSYM && symId != BIGTHSYM && symId != SMALLTHSYM && symId != NOTBTHSYM && symId != NOTSTHSYM && symId != EQUSYM && symId != NOTESYM && symId != PLUSSYM && symId != MINUSSYM) ; return ; } num = num * sign ; sprintf(nowitem, "%d", num) ; factorType = INTSYM ; getsym() ; } else{ sprintf(nowitem, "%d", num) ; factorType = INTSYM ; getsym() ; } } else if(symId == CHARSYM){ factorType = CHARSYM ; sprintf(nowitem, "%d", token[0]) ; getsym() ; //if(symId == DIGSYM){ // //} } else{ error(FACTOR_ERROR,indexInFile) ; do{ getsym() ; }while(symId != SEMICSYM && symId != MULTISYM && symId != DIVSYM && symId != RPARENSYM && symId != RMPARENSYM && symId != BIGTHSYM && symId != SMALLTHSYM && symId != NOTBTHSYM && symId != NOTSTHSYM && symId != EQUSYM && symId != NOTESYM && symId != PLUSSYM && symId != MINUSSYM) ; return ; }}/** * [compoundSta description]语句子程序 * <语句> ::= <条件语句>|<循环语句>|‘{’<语句列>‘}’| * <有返回值函数调用语句>;|<无返回值函数调用语句>;|<赋值语句>;| * <读语句>;|<写语句>;|<空>;|<返回语句>; */void state(){ /** * <条件语句> */ if(symId == IFSYM){ conditionSta() ; return ; } /** * <循环语句> */ else if(symId == DOSYM || symId == FORSYM){ loopSta() ; return ; } /** * ‘{’<语句列>‘}’ */ else if(symId == LBPARENSYM){ getsym() ; states() ; if(symId != RBPARENSYM){ error(RBPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; return ; } /** * <赋值语句>; */ else if(symId == IDSYM){ /** * [compoundSta description]赋值语句子程序 * <赋值语句> ::= <标识符>=<表达式>|<标识符>‘[’<表达式>‘]’=<表达式> */ char place1[128] ; char place2[128] ; char place3[128] ; strcpy(place1, space) ; strcpy(place2, space) ; strcpy(place3, space) ; char tempIdName[max] ; strcpy(idName, token) ; strcpy(tempIdName, token) ; strcpy(place3, token) ; int t ; getsym() ; if(symId == ASSIGNSYM){ t = searchSymTab(idName, 0) ; //cout << t << endl ; getsym() ; expr() ; strcpy(place1, nowitem) ; if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } genMidCode(ass, place1, space, place3) ; getsym() ; _gramma << "it is a assign statement" << endl ; //cout << "it is a assign statement" << endl ; } else if(symId == LMPARENSYM){ t = searchSymTab(idName, 0) ; //cout << t << endl ; getsym() ; expr() ; strcpy(place2, nowitem) ; if(symId != RMPARENSYM){ error(RMPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != SEMICSYM) ; return ; } getsym() ; if(symId == ASSIGNSYM){ getsym() ; expr() ; strcpy(place1, nowitem) ; if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } genMidCode(assignA, place1, place2, place3) ; } getsym() ; _gramma << "it is a assign statement" << endl ; //cout << " it is a assign statement" << endl ; } /** * <有返回值函数调用语句> ::= <标识符>‘(’<值参数表>‘)’ *<无返回值函数调用语句> ::= <标识符>‘(’<值参数表>‘)’ */ else if(symId == LPARENSYM){ getsym() ; valueOfPara() ; t = searchSymTab(tempIdName, 1) ; if(t == 0){// not fund error(UNDEFFUNC_ERROR, indexInFile) ; } //cout << t << endl ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != SEMICSYM) ; return ; } genMidCode(call, tempIdName, space, space) ; getsym() ; if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; _gramma << "it is a function call statement" << endl ; //cout << " it is a function call statement" << endl ; } else{ error(ASSIGNSTATUS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } } else if(symId == PRINTFSYM){ writeSta() ; if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; } else if(symId == SCANFSYM){ readSta() ; if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; } else if(symId == RETURNSYM){ returnSta() ; if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; } else if(symId == SEMICSYM){ getsym() ; } else{ //error(STATUS_ERROR,indexInFile) ; return ; }}/** * [compoundSta description]条件语句子程序 * <条件语句> ::= if ‘(’<条件>‘)’<语句>[else<语句>] */void conditionSta(){ char label1[256] ;//save if label char label2[256] ;//save else label char conditionValue[512] ; strcpy(label1, genLab()) ; strcpy(label2, genLab()) ; if(symId == IFSYM){ getsym() ; if(symId != LPARENSYM){ error(LPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != SEMICSYM) ; return ; } getsym() ; condition() ; strcpy(conditionValue, nowitem) ; genMidCode(jne, space, space, label1) ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != SEMICSYM) ; return ; } getsym() ; state() ; genMidCode(jmp, space, space, label2) ;//skip else genMidCode(lab, space, space, label1) ; if(symId == ELSESYM){ getsym() ; state() ; } genMidCode(lab, space, space, label2) ; _gramma << "it is a condition statement" << endl ; //cout << "it is a condition statement" << endl ; }}/** * [compoundSta description]条件子程序 * <条件> ::= <表达式><关系运算符><表达式>|<表达式> //表达式为0条件为假,否则为真 */void condition(){ char place1[128] ; char place2[128] ; strcpy(place1, space) ; strcpy(place2, space) ; expr() ; strcpy(place1, nowitem) ; if(symId == BIGTHSYM){ getsym() ; expr() ; strcpy(place2, nowitem) ; genMidCode(bt, place1, place2, space) ; } else if(symId == SMALLTHSYM){ getsym() ; expr() ; strcpy(place2, nowitem) ; genMidCode(st, place1, place2, space) ; } else if(symId == EQUSYM){ getsym() ; expr() ; strcpy(place2, nowitem) ; genMidCode(eql, place1, place2, space) ; } else if(symId == NOTBTHSYM){ getsym() ; expr() ; strcpy(place2, nowitem) ; genMidCode(nbt, place1, place2, space) ; } else if(symId == NOTSTHSYM){ getsym() ; expr() ; strcpy(place2, nowitem) ; genMidCode(nst, place1, place2, space) ; } else if(symId == NOTESYM){ getsym() ; expr() ; strcpy(place2, nowitem) ; genMidCode(neq, place1, place2, space) ; } else if(symId == RPARENSYM){ genMidCode(neq, place1, zero, space) ; } else if(isFor && symId == SEMICSYM){ genMidCode(neq, place1, zero, space) ; } else{ error(CONDITIONOP_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; }}/** * [compoundSta description]循环子程序 * <循环语句> ::= do<语句>while ‘(’<条件>‘)’ | * for‘(’<标识符>=<表达式>;<条件>;<标识符>=<标识符>(+|-)<步长>‘)’<语句> * */void loopSta(){ char place1[128] ; char place2[128] ; char label1[256] ; char label2[256] ; //for lop use char name1[128] ; char name2[128] ; char name3[128] ; strcpy(label1, genLab()) ; strcpy(label2, genLab()) ; if(symId == DOSYM){ genMidCode(lab, space, space, label1) ; getsym() ; state() ; if(symId != WHILESYM){ error(WHILESYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; if(symId != LPARENSYM){ error(LPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; condition() ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } genMidCode(jne, space, space, label2) ; genMidCode(jmp, space, space, label1) ; genMidCode(lab, space, space, label2) ; _gramma << "it is a do-while-loop statement" << endl ; //cout << "it is a do-while-loop statement" << endl ; //result << "it is a do-while-loop statement" << endl ; getsym() ; } else if(symId == FORSYM){ int s ; isFor = 1 ; getsym() ; if(symId != LPARENSYM){ error(LPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; if(symId != IDSYM){ error(IDSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } strcpy(name1, token) ; getsym() ; if(symId != ASSIGNSYM){ error(FORASSIGNMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } s = searchSymTab(name1, 0) ; if(s == -2){ error(VARTYPE_ERROR,indexInFile) ;//should not const } getsym() ; expr() ; genMidCode(ass, nowitem, space, name1) ; if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; genMidCode(lab, space, space, label1) ; condition() ; genMidCode(jne, space, space, label2) ; if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; if(symId != IDSYM){ error(IDSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } strcpy(name2, token) ; s = searchSymTab(name2, 0) ; if(s == -2){ error(VARTYPE_ERROR,indexInFile) ;//should not const } getsym() ; if(symId != ASSIGNSYM){ error(FORASSIGNMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; if(symId != IDSYM){ error(IDSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } strcpy(name3, token) ; s = searchSymTab(name3, 0) ; if(s == -2){ error(VARTYPE_ERROR,indexInFile) ;//should not const } getsym() ; if(symId != PLUSSYM && symId != MINUSSYM){ error(FOROPMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } char op[8] ; if(symId == PLUSSYM){ strcpy(op, add) ; } else if(symId == MINUSSYM){ strcpy(op, sub) ; } getsym() ; if(symId != DIGSYM){ error(FORDIGSYM_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } strcpy(place1, token) ; getsym() ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; state() ; strcpy(place2, genVar()) ; genMidCode(op, name3, place1, place2) ; genMidCode(ass, place2, space, name2) ; genMidCode(jmp, space, space, label1) ; genMidCode(lab, space, space, label2) ; isFor = 0 ; _gramma << "it is a for-loop statement" << endl ; //cout << "it is a for-loop statement" << endl ; }}/** * [compoundSta description]值参数子程序 * <值参数表> ::= <表达式>{,<表达式>}|<空> * 值参数表可能的开始字符包括:表达式相关 * <表达式> ::= [+|-]<项>{<加法运算符><项>} * 此句子中包含 + - 项 * <项> ::= <因子>{<乘法运算符><因子>} *<因子> ::= <标识符>|<标识符>‘[’<表达式>‘]’|<整数>|<字符>|<有返回值函数调用语句>|‘(’<表达式>‘)’ *此句中包含 标识符(IDSYM),整数(INTSYM),字符(CHARSYM),有返回值函数调用语句,以及左括号 *<有返回值函数调用语句> ::= <标识符>‘(’<值参数表>‘)’ */void valueOfPara(){ para = 0 ; vector<string> v; do{ if(symId == COMMASYM){ getsym() ; } if(symId == PLUSSYM || symId == MINUSSYM || symId == IDSYM || symId == DIGSYM || symId == CHARSYM || symId == LPARENSYM){ expr() ; v.push_back(nowitem) ; para++ ; } }while(symId == COMMASYM) ; char t[32] ; int l = v.size() ; for(int i = 0 ; i < l ; i++){ strcpy(t, v[i].c_str()) ; genMidCode(calpara, space, space, t) ; }}/** * [compoundSta description]参数子程序 * <参数> ::= <参数表> * <参数表> ::= <类型标识符><标识符>{,<类型标识符><标识符>}| <空> * 直接合并 */void paraTable(){ para = 0 ; int temp ; do{ if(symId == COMMASYM){ getsym() ; } if(symId == INTSYM || symId == CHARSYM){ temp = symId ; getsym() ; if(symId != IDSYM){ error(IDSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != RPARENSYM) ; return ; } strcpy(idName, token); value = -1 ; address++ ; insertSymTab(idName, 3, value, address, para + 1); if(temp == INTSYM){ genMidCode(paraop, ints, space, idName) ; } else if(temp == CHARSYM){ genMidCode(paraop, chars, space, idName) ; } para++ ; getsym() ; } }while(symId == COMMASYM) ; insertPara(para) ;}/** * [compoundSta description]语句列子程序 * <语句列> ::={<语句>} */void states(){ do{ state() ; }while(symId == IFSYM || symId == DOSYM || symId == FORSYM || symId == IDSYM || symId == RETURNSYM || symId == SCANFSYM || symId == PRINTFSYM || symId == LBPARENSYM || symId == SEMICSYM) ;}/** * [compoundSta description]读语句子程序 */void readSta(){ char name[32] ; int s ; if(symId == SCANFSYM){ getsym() ; if(symId == LPARENSYM){ do{ getsym() ; if(symId != IDSYM){ error(IDSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } strcpy(name, token) ; s = searchSymTab(name, 0) ; if(s == -2){ error(VARTYPE_ERROR,indexInFile) ; } if(isArr == 1){ error(READARRAY_ERROR,indexInFile) ; isArr = 0 ; } genMidCode(scf, space, factorType == INTSYM ? ints : chars , name) ; getsym() ; }while(symId == COMMASYM) ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } _gramma << "it is a read statement" << endl ; //cout << "it is a read statement" << endl ; } else{ error(LPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } } getsym() ;}/** * [compoundSta description]写语句子程序 */void writeSta(){ char place1[256] ; char place2[128] ; strcpy(place1, space) ; strcpy(place2, space) ; if(symId == PRINTFSYM){ getsym() ; if(symId != LPARENSYM){ error(LPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } getsym() ; if(symId == STRINGSYM){ strcpy(place1, token) ; getsym() ; if(symId == COMMASYM){ getsym() ; expr() ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } strcpy(place2, nowitem) ; } else if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } } else{ expr() ; strcpy(place2, nowitem) ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } } getsym() ; genMidCode(prtf, place1, place2, (factorType == CHARSYM ? chars : ints)) ; _gramma << "it is a write statement" << endl ; //cout << "it is a write statement" << endl ; }}/** * [compoundSta description]返回语句子程序 */void returnSta(){ char place[32] ; if(symId == RETURNSYM){ getsym() ; if(isVoid && symId != SEMICSYM){ error(UNEXCEPTRETURNVAL_ERROR, indexInFile); do{ getsym(); }while(symId != SEMICSYM) ; } if(symId == LPARENSYM){ hasRet = 1 ; getsym() ; expr() ; strcpy(place, nowitem) ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM) ; return ; } if(isMain){ genMidCode(exits, space, space, space) ; } else{ genMidCode(ret, space, space, place) ; } //num++ getsym() ; } else if(symId == SEMICSYM){ if(isMain){ genMidCode(exits, space, space, space) ; } else{ genMidCode(ret, space, space, space) ; } } else{ error(LPARENSYMMIS_ERROR, indexInFile) ; while(symId != SEMICSYM){ getsym() ; } return ; } if(symId != SEMICSYM){ error(SEMICSYMMIS_ERROR,indexInFile) ; while( symId != IFSYM && symId != FORSYM && symId != DOSYM && symId != LBPARENSYM && symId != IDSYM && symId != PRINTFSYM && symId != SCANFSYM && symId != SEMICSYM && symId != RETURNSYM && symId != RBPARENSYM){ getsym() ; } return ; } //genMidCode(ret, space, space, space) ; _gramma << "it is a return statement" << endl ; //cout << "it is a return statement" << endl ; }}void funcWithRetValDef(){ hasRet = 0 ; tempSym = symId ; declHead() ; if(symId != LPARENSYM){ error(LPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != RBPARENSYM) ; getsym() ; return ; } if(tempSym == INTSYM){ genMidCode(func, ints, space, procname) ; } else if(tempSym == CHARSYM){ genMidCode(func, chars, space, procname) ; } getsym() ; paraTable() ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != RBPARENSYM) ; getsym() ; return ; } getsym() ; if(symId != LBPARENSYM){ error(LPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != RBPARENSYM) ; getsym() ; return ; } getsym() ; compoundSta() ; if(symId != RBPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; while(symId != VOIDSYM && symId != INTSYM && symId != CHARSYM){ getsym() ; } return ; } if(hasRet == 0){ cout << indexInFile << " : " << "excepted return value missed" << endl ; } getsym() ; genMidCode(myend, space, space, procname) ; _gramma << "it is a valuable-function defination statement" << endl ; hasRet == 0 ; //cout << "it is a valuable-function defination statement" << endl ;}void funcWithNotRetValDef(){ int tempValue ; int tempAddr ; char tempIdName[max] ; isVoid = 1 ; if(symId != IDSYM){ error(IDSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != RBPARENSYM) ; return ; } strcpy(tempIdName, token) ; strcpy(idName, token) ; tempValue = -10 ; value = -10 ; tempAddr = 0 ; address = 0 ; insertSymTab(idName, 2, value, address, para) ; strcpy(procname, idName) ; genMidCode(func, vod, space, procname) ; getsym() ; if(symId != LPARENSYM){ error(LPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != RBPARENSYM) ; return ; } getsym() ; paraTable() ; insertPara(para) ; if(symId != RPARENSYM){ error(RPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != RBPARENSYM) ; return ; } getsym() ; if(symId != LBPARENSYM){ error(LBPARENSYMMIS_ERROR,indexInFile) ; do{ getsym() ; }while(symId != RBPARENSYM) ; return ; } getsym() ; if(symId != RBPARENSYM){ compoundSta() ; } if(symId != RBPARENSYM){ error(RBPARENSYMMIS_ERROR,indexInFile) ; while(symId != VOIDSYM && symId != CHARSYM && symId != INTSYM){ getsym() ; } return ; } getsym() ; genMidCode(ret, space, space, space) ; genMidCode(myend, space, space, procname) ; isVoid = 0 ; _gramma << "it is a void function-defination statement" << endl ; //cout << "it is a void function-defination statement" << endl ;}void program(){ if(symId == CONSTSYM){ constDecl() ; } while(symId == INTSYM || symId == CHARSYM){ preSymId = symId ; preCh = ch ; preIndex = indexInLine ; strcpy(preToken, token) ; getsym() ; if(symId != IDSYM){ error(IDSYMMIS_ERROR,indexInFile) ; } strcpy(idName, token) ; getsym() ; if(symId == COMMASYM || symId == LMPARENSYM){ symId = preSymId ; indexInLine = preIndex ; ch = preCh ; strcpy(token, preToken) ; varDef() ; getsym() ; } else if(symId == SEMICSYM){ value = preSymId ; address++ ; para = -1 ; insertSymTab(idName, 1, value, address, para); if(preSymId == INTSYM){ genMidCode(ints, space, space, idName) ; } else if(preSymId == CHARSYM){ genMidCode(chars, space, space, idName) ; } getsym() ; } else{ symId = preSymId ; //cout << symId << endl ;// debugger indexInLine = preIndex ; ch = preCh ; strcpy(token, preToken) ; break ; } } //function while(symId == INTSYM || symId == CHARSYM || symId == VOIDSYM){ if(symId == INTSYM || symId == CHARSYM){ funcWithRetValDef() ; } else if(symId == VOIDSYM){ preSymId = symId ; preCh = ch ; strcpy(preToken,token) ; preIndex = indexInLine ; getsym() ; if(symId == MAINSYM){ symId = preSymId ; ch = preCh ; //strcmp(token, preToken) ; indexInLine = preIndex ; break ; } else{ funcWithNotRetValDef() ; } } } //main function if(symId != VOIDSYM){ error(VOIDSYMMIS_ERROR,indexInFile) ; return ; } mainFunc() ;}void init(){ symTable.index = 0 ; symTable.indexOfPre[0] = 0 ; symTable.toltalPre = 1 ;}void stt(){ int i = symTable.index ; int k = 0 ; ofstream debug; debug.open("debug.txt", ios::out) ; debug << "------------------------------symbol table-------------------------------------" << endl ; debug << "--name-----------type----------value----------address---------para--" << endl ; for(int n = 0 ; n < i ; n++){ debug << symTable.element[n].name << "\t\t\t\t" << symTable.element[n].type << "\t\t\t\t" << symTable.element[n].value << "\t\t\t\t" << symTable.element[n].address << "\t\t\t\t" << symTable.element[n].para << endl ; if(n != 0 && n == symTable.indexOfPre[k]){ debug << "-----------------------------------------------------" << endl ; k++ ; } } debug.close() ;}
midcode.cpp
//midcode.cpp////author by jk @2016/11/22//#include <iostream>#include <string>#include <fstream>#include <sstream>#include <string.h>#include <vector>#include <stdlib.h>using namespace std ;#define maxmidcode 512typedef struct midcode{ char op[8] ; char num_a[128] ;//var1 char num_b[128] ;//var2 char rst[256] ;//var3}FOURVARCODE ;///////////////////////////////////////FOURVARCODE midecode[maxmidcode] ;/////////////////////////////////ofstream outputfile ;ofstream afteroutputfile ;/////////////////////////////////char consts[] = {'c','o','n','s','t','\0'} ;char ints[] = {'i','n','t',' ',' ','\0'} ;char chars[] = {'c','h','a','r',' ','\0'} ;char inta[] = {'i','n','t','a',' ','\0'} ;char chara[] = {'c','h','a','r','a','\0'} ;char myend[] = {'e','n','d',' ',' ','\0'} ;char add[] = {'+',' ',' ',' ',' ','\0'} ;char sub[] = {'-',' ',' ',' ',' ','\0'} ;char mul[] = {'*',' ',' ',' ',' ','\0'} ;char divs[] = {'/',' ',' ',' ',' ','\0'} ;char func[] = {'f','u','n','c',' ','\0'} ;char prtf[] = {'p','r','t','f',' ','\0'} ;char scf[] = {'s','c','f',' ',' ','\0'} ;char ret[] = {'r','e','t',' ',' ','\0'} ;char lab[] = {'l','a','b',':',' ','\0'} ;char paraop[] = {'p','a','r','a',' ','\0'} ;char calpara[] = {'c','p','a','r','a','\0'} ;char call[] = {'c','a','l','l',' ','\0'} ;char jne[] = {'j','n','e',' ',' ','\0'} ;char jmp[] = {'j','m','p',' ',' ','\0'} ;char ass[] = {'=',' ',' ',' ',' ','\0'} ;char bt[] = {'>',' ',' ',' ',' ','\0'} ;char st[] = {'<',' ',' ',' ',' ','\0'} ;char eql[] = {'=','=',' ',' ',' ','\0'} ;char neq[] = {'!','=',' ',' ',' ','\0'} ;char nbt[] = {'<','=',' ',' ',' ','\0'} ;char nst[] = {'>','=',' ',' ',' ','\0'} ;char assignA[] = {'[',']','=',' ',' ','\0'} ;char aAssign[] = {'a','A','s','s',' ','\0'} ;char exits[] = {'e','x','i','t','\0'} ;char vod[] = {'v','o','i','d',' ','\0'} ;char val[] = {'v','a','l','u','e','\0'} ;char space[] = {' ',' ',' ',' ',' ','\0'} ; ;char zero[] = {'0',' ',' ',' ',' ','\0'} ;////////////////////////////////int codeNum = 0 ;int labelNum = 0 ;int varNum = 0 ;vector<FOURVARCODE> midCodeList ;//////////////////////////////////////char* int2array(int i) ;void replace(char* result, char* a) ;char* genLab() ;char* genVar() ;char* int2array(int a){ char* temp = (char*)malloc(sizeof(char)*128) ; sprintf(temp, "%d" ,a); return temp ;}/*void genMidCode(char* op, int a, int b, char* result){ outputfile << "\t\t" << op << ", " << a << ", " << b << ", " << result << " " << endl ; strcpy(midecode[codeNum].op, op) ; strcpy(midecode[codeNum].num_a, strcmp(int2array(a), "-1") == 0 ? " " : int2array(a)) ; strcpy(midecode[codeNum].num_b, int2array(b)) ; strcpy(midecode[codeNum].rst, result) ; codeNum++ ;}*/void genMidCode(char* op, char* a, int b, char* result){ outputfile << "\t\t" << op << ", " << a << ", " << b << ", " << result << " " << endl ; strcpy(midecode[codeNum].op, op) ; strcpy(midecode[codeNum].num_a, a) ; strcpy(midecode[codeNum].num_b, int2array(b)) ; strcpy(midecode[codeNum].rst, result) ; midCodeList.push_back(midecode[codeNum]) ; codeNum++ ;}void genMidCode(char* op, char* a, char* b, char* result){ if(strcmp(op, func) == 0){ outputfile << endl << endl ; } if(strcmp(op, lab) == 0){ outputfile << "\t\t" << result << " :" << endl ; } outputfile << "\t\t" << op << ", " << a << ", " << b << ", " << result << " " << endl ; strcpy(midecode[codeNum].op, op) ; strcpy(midecode[codeNum].num_a, a) ; strcpy(midecode[codeNum].num_b, b) ; strcpy(midecode[codeNum].rst, result) ; codeNum++ ;}char* genLab(){ char* label = (char*)malloc(sizeof(char)*16) ; sprintf(label, "_LABEL_%d", labelNum) ; labelNum++ ; return label ;}char* genVar(){ char* var = (char*)malloc(sizeof(char)*16) ; sprintf(var, "$_%d", varNum) ; varNum++ ; return var ;}//you huaint isnumber(char* a, int len){ for(int i = 0 ; i < len ; ++i){ if(a[i] < '0' || a[i] > '9'){ return 0 ; } } return 1 ;}void combine(){ for(int i = 0 ; i < codeNum ; ++i){ if(strcmp(midecode[i].op, sub) == 0 && isnumber(midecode[i].num_a, strlen(midecode[i].num_a)) && isnumber(midecode[i].num_b, strlen(midecode[i].num_b))){ int a = atoi(midecode[i].num_a) - atoi(midecode[i].num_b) ; char b[512]; strcpy(b, midecode[i].rst) ; strcpy(midecode[i].op, space) ; strcpy(midecode[i].num_a, space) ; strcpy(midecode[i].num_b, space) ; strcpy(midecode[i].rst, space) ; replace(b, int2array(a)) ; } else if(strcmp(midecode[i].op, add) == 0 && isnumber(midecode[i].num_a, strlen(midecode[i].num_a)) && isnumber(midecode[i].num_b, strlen(midecode[i].num_b))){ int a = atoi(midecode[i].num_a) + atoi(midecode[i].num_b) ; char b[512]; strcpy(b, midecode[i].rst) ; strcpy(midecode[i].op, space) ; strcpy(midecode[i].num_a, space) ; strcpy(midecode[i].num_b, space) ; strcpy(midecode[i].rst, space) ; replace(b, int2array(a)) ; } else if(strcmp(midecode[i].op, mul) == 0 && isnumber(midecode[i].num_a, strlen(midecode[i].num_a)) && isnumber(midecode[i].num_b, strlen(midecode[i].num_b))){ int a = atoi(midecode[i].num_a) * atoi(midecode[i].num_b) ; char b[512]; strcpy(b, midecode[i].rst) ; strcpy(midecode[i].op, space) ; strcpy(midecode[i].num_a, space) ; strcpy(midecode[i].num_b, space) ; strcpy(midecode[i].rst, space) ; replace(b, int2array(a)) ; } else if(strcmp(midecode[i].op, divs) == 0 && isnumber(midecode[i].num_a, strlen(midecode[i].num_a)) && isnumber(midecode[i].num_b, strlen(midecode[i].num_b))){ int a = atoi(midecode[i].num_a) / atoi(midecode[i].num_b) ; char b[512]; strcpy(b, midecode[i].rst) ; strcpy(midecode[i].op, space) ; strcpy(midecode[i].num_a, space) ; strcpy(midecode[i].num_b, space) ; strcpy(midecode[i].rst, space) ; replace(b, int2array(a)) ; } if(strcmp(midecode[i].op, func) == 0){ afteroutputfile << endl << endl ; } if(strcmp(midecode[i].op, lab) == 0){ afteroutputfile << "\t\t" << midecode[i].rst << " :" << endl ; } if(strcmp(midecode[i].op, space) != 0){ afteroutputfile << "\t\t" << midecode[i].op << ", " << midecode[i].num_a << ", " << midecode[i].num_b << ", " << midecode[i].rst << " " << endl ; } }}void replace(char* result, char* a){ for(int i = 0 ; i < codeNum ; ++i){ if(strcmp(midecode[i].num_a, result) == 0){ strcpy(midecode[i].num_a, a) ; } if(strcmp(midecode[i].num_b, result) == 0){ strcpy(midecode[i].num_b, a) ; } if(strcmp(midecode[i].rst, result) == 0){ strcpy(midecode[i].rst, a) ; } }}
result.cpp
#include <iostream>#include <string>#include <vector>#include <fstream>#include <stack>#include "midcode.cpp"ofstream rstCode ;////////////////////////////////按照运行栈的设计,为每一次函数调用开辟新的栈区,用sp和fp进行栈区数据的访问int num = 0 ;//四元式处理的数目typedef struct statictype{ char name[512] ; char val[256] ; char kind[512] ;}static_type ;typedef struct datatype{ char name[512] ; int addr ; char kind[512] ; char val[256] ;}data_type ;typedef struct runstacktrupe{ static_type static_area[128] ;//for global is const,for func is para,for main is const data_type data_area[128] ; int level ; int static_num ; int data_num ; int sp ;//栈指针 int fp ;//帧指针 //int pre_abp ;}RUNSTACK ;//////////////////////////stack<RUNSTACK> run_stack ;int cnt = 0 ; //use to find current fpint paraNum = 0 ;int isglobal ;int isconst ;///////////////////////////int findaddr(char* name, int flag){ i = cnt + 1 ; while(symTable.element[i].type != 2){ if(strcmp(name, symTable.element[i].name) == 0){ if(symTable.element[i].type == 0){ isconst = 1 ; } return symTable.element[i].address ; } i++ ; } i = 0 ; while(i < symTable.indexOfPre[1]){ isglobal = 1 ; if(strcmp(name, symTable.element[i].name) == 0){ if(symTable.element[i].type == 0){ isconst = 1 ; } return symTable.element[i].address ; } i++ ; } return -1 ;}int findfunc(char* name){ int i = 0 ; while(i < symTable.toltalPre){ if(strcmp(symTable.element[symTable.indexOfPre[i]], name) == 0){ cnt = i ; paraNum = symTable.element[symTable.indexOfPre[i]].para ; return ; } } paraNum = 0 ; cnt = 0 ;}void insert_run_stack(){ while(strcmp(midecode[num].op, para) == 0 || strcmp(midecode[num].op, consts) == 0 || strcmp(midecode[num].op, ints) == 0 || strcmp(midecode[num].op, chars) == 0 || strcmp(midecode[num].op, chara) == 0 || strcmp(midecode[num].op, inta) == 0 || strcpy(midecode[num].op, func) == 0){ if(strcmp(midecode[num].op, consts) == 0){ strcpy(run_stack.top().static_area[run_stack.top().static_num].name, midecode[num].rst) ; strcpy(run_stack.top().static_area[run_stack.top().static_num].val, midecode[num].num_b) ; strcpy(run_stack.top().static_area[run_stack.top().static_num].kind, midecode[num].num_a) ; run_stack.top().static_num++ ; num++ ; sp++ ; } else if(strcmp(midecode[num].op, para) == 0){ strcpy(run_stack.top().static_area[run_stack.top().static_num].name, midecode[num].rst) ; strcpy(run_stack.top().static_area[run_stack.top().static_num].val, midecode[num].num_b) ; strcpy(run_stack.top().static_area[run_stack.top().static_num].kind, midecode[num].num_a) ; run_stack.top().static_num++ ; num++ ; sp++ ; } else if(strcmp(midecode[num].op, ints) == 0){ strcpy(run_stack.top().data_area[run_stack.top().data_num].name, midecode[num].rst) ; strcpy(run_stack.top().data_area[run_stack.top().data_num].val, midecode[num].num_b) ; strcpy(run_stack.top().data_area[run_stack.top().data_num].kind, midecode[num].num_a) ; run_stack.top().data_num++ ; num++ ; sp++ ; } else if(strcmp(midecode[num].op, chars) == 0){ strcpy(run_stack.top().data_area[run_stack.top().data_num].name, midecode[num].rst) ; strcpy(run_stack.top().data_area[run_stack.top().data_num].val, midecode[num].num_b) ; strcpy(run_stack.top().data_area[run_stack.top().data_num].kind, midecode[num].num_a) ; run_stack.top().data_num++ ; num++ ; sp++ ; } else if(strcmp(midecode[num].op, inta) == 0){ strcpy(run_stack.top().data_area[run_stack.top().data_num].name, midecode[num].rst) ; strcpy(run_stack.top().data_area[run_stack.top().data_num].val, midecode[num].num_b) ; strcpy(run_stack.top().data_area[run_stack.top().data_num].kind, midecode[num].num_a) ; run_stack.top().data_num++ ; num++ ; sp++ ; } else if(strcmp(midecode[num].op, chara) == 0){ strcpy(run_stack.top().data_area[run_stack.top().data_num].name, midecode[num].rst) ; strcpy(run_stack.top().data_area[run_stack.top().data_num].val, midecode[num].num_b) ; strcpy(run_stack.top().data_area[run_stack.top().data_num].kind, midecode[num].num_a) ; run_stack.top().data_num++ ; num++ ; sp++ ; } else if(strcmp(midecode[num].op, func) == 0){ RUNSTACK temp_run_stack ; temp_run_stack.level = run_stack.top().level + 1 ; temp_run_stack.fp = run_stack.top().sp ; temp_run_stack.sp = run_stack.top().sp ; temp_run_stack.static_num = 0 ; temp_run_stack.data_num = 0 ; } }}void init_run_stack(){ RUNSTACK temp_run_stack ; temp_run_stack.level = 0 ; temp_run_stack.sp = 0 ; //fp ? temp_run_stack.level = 0 ; temp_run_stack.static_num = 0 ; temp_run_stack.data_num = 0 ; temp_run_stack.pre_abp = 0 ; while(strcmp(midecode[num].op, func) != 0){ if(strcmp(midecode[num].op, consts) == 0){ strcpy(temp_run_stack.static_area[temp_run_stack.static_num].name, midecode[num].rst) ; strcpy(temp_run_stack.static_area[temp_run_stack.static_num].val, midecode[num].num_b) ; strcpy(temp_run_stack.static_area[temp_run_stack.static_num].kind, midecode[num].num_a) ; temp_run_stack.static_num++ ; } else if(strcpy(midecode[num].op, ints) == 0){ strcpy(temp_run_stack.data_area[temp_run_stack.data_num].name, midecode[num].rst) ; int addr ; addr = findaddr(midecode[num].rst) ; temp_run_stack.data_area[temp_run_stack.data_num].addr = addr ; strcpy(temp_run_stack.data_area[temp_run_stack.data_num].kind, ints) ; temp_run_stack.data_num++ ; } else if(strcpy(midecode[num].op, chars) == 0){ strcpy(temp_run_stack.data_area[temp_run_stack.data_num].name, midecode[num].rst) ; int addr ; addr = findaddr(midecode[num].rst) ; temp_run_stack.data_area[temp_run_stack.data_num].addr = addr ; strcpy(temp_run_stack.data_area[temp_run_stack.data_num].kind, chars) ; temp_run_stack.data_num++ ; } num++ ; temp_run_stack.sp++ ; } run_stack.push(temp_run_stack) ;}void pop_stack(){ run_stack.pop() ;}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int isNum(char a){ if(a >= '0' || a <= '9' ){ return 1 ; } return 0 ;}void func_mips(){ rstCode << "# ret fourvarcode" << endl ; rstCode << "\t\t#Save Register" << endl;// rstCode << "\t\tsw\t$fp\t($sp)" << endl;//保存上一个函数的$fp rstCode << "\t\tadd\t$fp\t$sp\t$0" << endl;//设置本函数$fp:$fp=$sp rstCode << "\t\tsubi\t$sp\t$sp\t4" << endl;//$sp-=4 rstCode << "\t\tsw\t$ra\t($sp)" << endl;//保存$ra rstCode << "\t\tsubi\t$sp\t$sp\t4" << endl;//$sp-=4 rstCode << "\t\t#Save Register Done!" << endl;// //get function para number}void myend_mips(){ rstCode << "#func end!!!!!!!!!" << endl ;}void ret_mips(){ rstCode << "# ret fourvarcode" << endl ; if(strcmp(midecode[num].rst, space) != 0){ if(midecode[num].rst[0] == '$'){ rstCode << "\t\tlw\t$v1\t($sp)" << endl ; } else{ int a = findaddr(midecode[num].rst, 1) ; rstCode << "\t\tlw\t$v1\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; isglobal = 0 ; } } rstCode << "\t\tjr" << endl ;}void ints_mips(){ int a = findaddr(midecode[num].rst) ; if(isglobal == 1){ isglobal = 0 ; return ; }}void chars_mips(){}void inta_mips(){}void chara_mips(){}void add_mips(){ int addr1 ; int addr2 ; int addr3 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << addr1 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << addr2 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << '\t\tadd\t$t0\t$t0\t$t1' << endl ; if(midecode[num].rst[0] == '$'){ rstCode << "\t\tsw\t$t0\t($sp)" << endl ; } else{ addr3 = findaddr(midecode[num].rst) ; rstCode << "\t\tsw\t$t0\t" << addr3 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; }}void sub_mips(){ int addr1 ; int addr2 ; int addr3 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << addr1 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << addr2 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << '\t\tsub\t$t0\t$t0\t$t1' << endl ; if(midecode[num].rst[0] == '$'){ rstCode << "\t\tsw\t$t0\t($sp)" << endl ; } else{ addr3 = findaddr(midecode[num].rst) ; rstCode << "\t\tsw\t$t0\t" << addr3 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; }}void mul_mips(){ int addr1 ; int addr2 ; int addr3 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << addr1 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << addr2 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << "\t\tmult\t$t0\t$t1" << endl ; rstCode << "\t\tmfhi\t$t0" << endl ; rstCode << "\t\tmflo\t$t1" << endl ; rstCode << "\t\tadd\t$t0\t$t0\t$t1" << endl ; if(midecode[num].rst[0] == '$'){ rstCode << "\t\tsw\t$t0\t($sp)" << endl ; } else{ addr3 = findaddr(midecode[num].rst) ; rstCode << "\t\tsw\t$t0\t" << addr3 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; }}void div_mips(){ int addr1 ; int addr2 ; int addr3 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << addr1 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << addr2 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << "\t\tdiv\t$t0\t$t1" << endl ; rstCode << "\t\tmfhi\t$t0" << endl ; rstCode << "\t\tmflo\t$t1" << endl ; rstCode << "\t\tadd\t$t0\t$t0\t$t1" << endl ; if(midecode[num].rst[0] == '$'){ rstCode << "\t\tsw\t$t0\t($sp)" << endl ; } else{ addr3 = findaddr(midecode[num].rst) ; rstCode << "\t\tsw\t$t0\t" << addr3 << isglobal == 1 ? "($t8)" : "($fp)" << endl ; }}void prtf_mips(){}void scf_mips(){}void lab_mips(){ rstCode << "\t" << midecode[num].rst << ":" << endl ;}void paraop_mips(){}void calpara_mips(){}void call_mips(){ rstCode << "\t\tjal\t" << midecode[num].num_a << endl; rstCode << "\t\tnop\n";}void jmp_mips(){ rstCode << "\t\tj\t" << midecode[num].rst << endl ;}void jne_mips(){ rstCode << midecode[num].rst << endl ;}void ass_mips(){ int addr1 ; int addr2 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } addr2 = findaddr(midecode[num].rst) ; rstCode << "\t\tsw\t$t0\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ;}void bt_mips(){//> int addr1 ; int addr2 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << "\t\tbgt\t$t0\t$t1\t" ;}void st_mips(){//< int addr1 ; int addr2 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << "\t\tblt\t$t0\t$t1\t" ;}void eql_mips(){//== int addr1 ; int addr2 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << "\t\tbeq\t$t0\t$t1\t" ;}void neq_mips(){//!= int addr1 ; int addr2 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << "\t\tbne\t$t0\t$t1\t" ;}void nbt_mips(){//<= int addr1 ; int addr2 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << "\t\tble\t$t0\t$t1\t" ;}void nst_mips(){//>= int addr1 ; int addr2 ; if(midecode[num].num_a[0] == '$'){ rstCode << "\t\tlw\t$t0\t($sp)" << endl ; } else if(isNum(midecode[num].num_a[0])){ rstCode << "\t\tli\t$t0\t" << midecode[num].num_a << endl ; } else{ addr1 = findaddr(midecode[num].num_a) ; rstCode << "\t\tlw\t$t0\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } if(midecode[num].num_b[0] == '$'){ rstCode << "\t\tlw\t$t1\t($sp)" << endl ; } else if(isNum(midecode[num].num_b[0])){ rstCode << "\t\tli\t$t1\t" << midecode[num].num_b << endl ; } else{ addr2 = findaddr(midecode[num].num_b) ; rstCode << "\t\tlw\t$t1\t" << a << isglobal == 1 ? "($t8)" : "($fp)" << endl ; } rstCode << "\t\tbge\t$t0\t$t1\t" ;}void assignA_mips(){//[] = }void aAssign_mips(){//aAss}
asm.cpp
#include <iostream>#include <string>#include <vector>#include <fstream>#include <sstream>#include <string.h>#include "gramma.cpp"using namespace std ;///////////////////////////////ofstream rstfile ;int stringCnt = 0 ;typedef struct constype{ char name[512] ; char value[512] ;}GlbConst ;GlbConst glbconst[512] ;int cntOfGlobal = 0 ;typedef struct areavar{ char name[512] ; int addr ;}AreaVar ;////////////////////AreaVar convar[512] ;int areanum ;//area variable donenum ;int paranum = 0 ;int calparanum = 0 ;int donenum = 0 ;//donenumber of fourvarcode which has been finishedint offset = 0 ;//realtive to fp////////////////////////////////////int findaddr(char* name){ int i = 0 ; while(i < areanum){ if(strcmp(name, convar[i].name) == 0){ return convar[i].addr ; } i++ ; } return -1 ;}void insertaddr(char* name){ strcpy(convar[areanum].name, name) ; convar[areanum].addr = offset ; rstfile << "\t\tsubi\t$sp\t$sp\t4" << endl ; offset += 4 ; areanum++ ;}void globalcondef(){ int i = 0 ; while(strcmp(midecode[i].op, consts) == 0){ strcpy(glbconst[cntOfGlobal].name, midecode[i].rst) ; strcpy(glbconst[cntOfGlobal].value, midecode[i].num_b) ; rstfile << midecode[i].rst << ":\t.word\t" << midecode[i].num_b << endl ; cntOfGlobal++ ; i++ ; }}void globalvardef(){ int i = cntOfGlobal ; while(strcmp(midecode[i].op, ints) == 0 || strcmp(midecode[i].op, chars) == 0 || strcmp(midecode[i].op, inta) == 0 || strcmp(midecode[i].op, chara) == 0){ if(strcmp(midecode[i].op, inta) == 0 || strcmp(midecode[i].op, chara) == 0){ strcpy(glbconst[cntOfGlobal].name, midecode[i].rst) ; strcpy(glbconst[cntOfGlobal].value, space) ; int step = atoi(midecode[i].num_b) ; rstfile << midecode[i].rst << ":\t.space\t" << step * 4 << endl ; cntOfGlobal++ ; i++ ; } else{ strcpy(glbconst[cntOfGlobal].name, midecode[i].rst) ; strcpy(glbconst[cntOfGlobal].value, midecode[i].num_b) ; rstfile << midecode[i].rst << ":\t.space\t" << "4" << endl ; cntOfGlobal++ ; i++ ; } } donenum = cntOfGlobal ;}void initasm(){ int i = 0 ; rstfile << ".data" << endl ; globalcondef() ; globalvardef() ; i = cntOfGlobal ; while(i < codeNum){ if(strcmp(midecode[i].op, prtf) == 0){ if(strcmp(midecode[i].num_a, space) != 0){ char temp[] = {'$','s','t','r','i','n','g','\0'} ; char* p = int2array(stringCnt) ; strcat(temp, p) ; strcpy(glbconst[cntOfGlobal].name, temp) ; strcpy(glbconst[cntOfGlobal].value, midecode[i].num_a) ; strcpy(midecode[i].num_a, temp) ; cout << temp << endl ; rstfile << temp << ":\t.asciiz\t" << "\"" << glbconst[cntOfGlobal].value << "\"" << endl ; cntOfGlobal++ ; stringCnt++ ; } } i++ ; } rstfile << ".text" << endl ; rstfile << ".globl main" << endl ; rstfile << "\t\tj\tmain" << endl ;}int isNum(char a){ if(a >= '0' && a <= '9' ){ return 1 ; } return 0 ;}void func_mips(){ paranum = 0 ; rstfile << "\t\t# func fourvarcode" << endl ; rstfile << "\t\t#Save Register" << endl;// rstfile << midecode[donenum].rst << ":" << endl ; rstfile << "\t\tsubi\t$sp\t$sp\t4" << endl;//$sp-=4 rstfile << "\t\tsubi\t$sp\t$sp\t" << calparanum * 4 << endl ; rstfile << "\t\t#func fourvarcode finished" << endl;// //get function para donenumber offset = 8 + calparanum * 4 ;}void myend_mips(){ areanum = 0 ;}void ret_mips(){ rstfile << "\t\t# ret fourvarcode" << endl ; if(strcmp(midecode[donenum].rst, space) != 0){ if(isNum(midecode[donenum].rst[0])){ rstfile << "\t\tli\t$v1\t" << midecode[donenum].rst << endl ; } else{ int addr1 = -1 * findaddr(midecode[donenum].rst) ; if(addr1 == 1){//isglobal rstfile << "\t\tla\t$t0\t" << midecode[donenum].rst << endl ; rstfile << "\t\tlw\t$v1\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$v1\t" << addr1 << "($fp)" << endl ; } } } rstfile << "\t\tmove\t$t0\t$ra" << endl ;//save $ra rstfile << "\t\tlw\t$ra\t-4($fp)" << endl ;//save pre $ra rstfile << "\t\tadd\t$sp\t$fp\t$zero" << endl ;//sp = fp rstfile << "\t\tlw\t$fp\t($fp)" << endl ;//fp = pre fp rstfile << "\t\tjr\t$t0" << endl ;}void ints_mips(){ //areanum strcpy(convar[areanum].name,midecode[donenum].rst) ; convar[areanum].addr = offset ; rstfile << "\t\tsubi\t$sp\t$sp\t4" << endl ; areanum++ ; offset += 4 ;}void chars_mips(){ strcpy(convar[areanum].name,midecode[donenum].rst) ; convar[areanum].addr = offset ; rstfile << "\t\tsubi\t$sp\t$sp\t4" << endl ; areanum++ ; offset += 4 ;}void inta_mips(){ strcpy(convar[areanum].name,midecode[donenum].rst) ; convar[areanum].addr = offset ; int step ; step = atoi(midecode[donenum].num_b) ; rstfile << "\t\tsubi\t$sp\t$sp\t" << step * 4 << endl ; offset += step * 4 ; areanum++ ;}void chara_mips(){ strcpy(convar[areanum].name,midecode[donenum].rst) ; convar[areanum].addr = offset ; int step ; step = atoi(midecode[donenum].num_b) ; rstfile << "\t\tsubi\t$sp\t$sp\t" << step * 4 << endl ; offset += step * 4 ; areanum++ ;}void add_mips(){ int addr1 ; int addr2 ; int addr3 ; if(isNum(midecode[donenum].num_a[0]) || midecode[donenum].num_a[0] == '-'){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){ rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0]) || midecode[donenum].num_b[0] == '-'){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){ rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } rstfile << "\t\tadd\t$t0\t$t0\t$t1" << endl ; if(midecode[donenum].rst[0] == '$'){ insertaddr(midecode[donenum].rst) ; addr3 = -1 * findaddr(midecode[donenum].rst) ; rstfile << "\t\tsw\t$t0\t" << addr3 << "($fp)" << endl ; } else{ addr3 = -1 * findaddr(midecode[donenum].rst) ; if(addr3 == 1){ rstfile << "\t\tla\t$t1\t" << midecode[donenum].rst << endl ; rstfile << "\t\tsw\t$t0\t($t1)" << endl ; } else{ rstfile << "\t\tsw\t$t0\t" << addr3 << "($fp)" << endl ; } }}void sub_mips(){ int addr1 ; int addr2 ; int addr3 ; if(isNum(midecode[donenum].num_a[0]) || midecode[donenum].num_a[0] == '-'){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){ rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0]) || midecode[donenum].num_b[0] == '-'){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){ rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } rstfile << "\t\tsub\t$t0\t$t0\t$t1" << endl ; if(midecode[donenum].rst[0] == '$'){ insertaddr(midecode[donenum].rst) ; addr3 = -1 * findaddr(midecode[donenum].rst) ; rstfile << "\t\tsw\t$t0\t" << addr3 << "($fp)" << endl ; } else{ addr3 = -1 * findaddr(midecode[donenum].rst) ; if(addr3 == 1){ rstfile << "\t\tla\t$t1\t" << midecode[donenum].rst << endl ; rstfile << "\t\tsw\t$t0\t($t1)" << endl ; } else{ rstfile << "\t\tsw\t$t0\t" << addr3 << "($fp)" << endl ; } }}void mul_mips(){ int addr1 ; int addr2 ; int addr3 ; if(isNum(midecode[donenum].num_a[0]) || midecode[donenum].num_a[0] == '-'){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){ rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0]) || midecode[donenum].num_b[0] == '-'){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){ rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } /*rstfile << "\t\tmult\t$t0\t$t1" << endl ; rstfile << "\t\tmfhi\t$t0" << endl ; rstfile << "\t\tmflo\t$t1" << endl ; rstfile << "\t\tadd\t$t0\t$t0\t$t1" << endl ;*/ rstfile << "\t\tmul\t$t0\t$t0\t$t1" << endl ; if(midecode[donenum].rst[0] == '$'){ insertaddr(midecode[donenum].rst) ; addr3 = -1 * findaddr(midecode[donenum].rst) ; rstfile << "\t\tsw\t$t0\t" << addr3 << "($fp)" << endl ; } else{ addr3 = -1 * findaddr(midecode[donenum].rst) ; if(addr3 == 1){ rstfile << "\t\tla\t$t1\t" << midecode[donenum].rst << endl ; rstfile << "\t\tsw\t$t0\t($t1)" << endl ; } else{ rstfile << "\t\tsw\t$t0\t" << addr3 << "($fp)" << endl ; } }}void div_mips(){ int addr1 ; int addr2 ; int addr3 ; if(isNum(midecode[donenum].num_a[0]) || midecode[donenum].num_a[0] == '-'){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){ rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0]) || midecode[donenum].num_b[0] == '-'){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){ rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } /*rstfile << "\t\tdiv\t$t0\t$t1" << endl ; rstfile << "\t\tmfhi\t$t0" << endl ; rstfile << "\t\tmflo\t$t1" << endl ; rstfile << "\t\tadd\t$t0\t$t0\t$t1" << endl ;*/ rstfile << "\t\tdiv\t$t0\t$t0\t$t1" << endl ; if(midecode[donenum].rst[0] == '$'){ insertaddr(midecode[donenum].rst) ; addr3 = -1 * findaddr(midecode[donenum].rst) ; rstfile << "\t\tsw\t$t0\t" << addr3 << "($fp)" << endl ; } else{ addr3 = -1 * findaddr(midecode[donenum].rst) ; if(addr3 == 1){ rstfile << "\t\tla\t$t1\t" << midecode[donenum].rst << endl ; rstfile << "\t\tsw\t$t0\t($t1)" << endl ; } else{ rstfile << "\t\tsw\t$t0\t" << addr3 << "($fp)" << endl ; } }}void prtf_mips(){ if(strcmp(midecode[donenum].num_a, space) != 0){ rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tmove\t$a0\t$t0" << endl ; rstfile << "\t\tli\t$v0\t4" << endl ; rstfile << "\t\tsyscall" << endl ; rstfile << "\t\tli\t$a0\t\'\\n\'" << endl ; rstfile << "\t\tli\t$v0\t11" << endl ; rstfile << "\t\tsyscall" << endl ; } if(strcmp(midecode[donenum].num_b, space) == 0){ return ; } int addr1 = -1 * findaddr(midecode[donenum].num_b) ; if(addr1 == 1){//not find, is global if(isNum(midecode[donenum].num_b[0]) || midecode[donenum].num_b[0] == '-'){ rstfile << "\t\tli\t$a0\t" << midecode[donenum].num_b << endl ; } else{ rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$a0\t($t0)" << endl ; } } else{ rstfile << "\t\tlw\t$a0\t" << addr1 << "($fp)" << endl ; } //rstfile << "\t\tlw\t$a0\t" << addr1 << "($fp)" << endl ; if(strcmp(midecode[donenum].rst, ints) == 0){ rstfile << "\t\tli\t$v0\t1" << endl ; } else if(strcmp(midecode[donenum].rst, chars) == 0){ rstfile << "\t\tli\t$v0\t11" << endl ; } rstfile << "\t\tsyscall" << endl ; rstfile << "\t\tli\t$a0\t\'\\n\'" << endl ; rstfile << "\t\tli\t$v0\t11" << endl ; rstfile << "\t\tsyscall" << endl ;}void scf_mips(){ int addr1 = -1 * findaddr(midecode[donenum].rst) ; if(strcmp(midecode[donenum].num_b, ints) == 0){ rstfile << "\t\tli\t$v0\t5" << endl ; } else if(strcmp(midecode[donenum].num_b, chars) == 0){ rstfile << "\t\tli\t$v0\t12" << endl ; } rstfile << "\t\tsyscall" << endl ; if(addr1 == 1){//not find, is global rstfile << "\t\tla\t$t0\t" << midecode[donenum].rst << endl ; rstfile << "\t\tsw\t$v0\t($t0)" << endl ; } else{ rstfile << "\t\tsw\t$v0\t" << addr1 << "($fp)" << endl ; } //rstfile << "\t\tsw\t$v0\t" << addr1 << "(fp)" << endl ;}void lab_mips(){ rstfile << midecode[donenum].rst << ":" << endl ;}void paraop_mips(){ if(paranum < 4){ switch(paranum){ case 0 : rstfile << "\t\tmove\t$t0\t$a0" << endl ; rstfile << "\t\tsw\t$t0\t" << -8 << "($fp)" << endl ; break ; case 1 : rstfile << "\t\tmove\t$t0\t$a1" << endl ; rstfile << "\t\tsw\t$t0\t" << -12 << "($fp)" << endl ; break ; case 2 : rstfile << "\t\tmove\t$t0\t$a2" << endl ; rstfile << "\t\tsw\t$t0\t" << -16 << "($fp)" << endl ; break ; case 3 : rstfile << "\t\tmove\t$t0\t$a3" << endl ; rstfile << "\t\tsw\t$t0\t" << -20 << "($fp)" << endl ; break ; } } insertaddr(midecode[donenum].rst) ; paranum++ ;}void calpara_mips(){ int addr1 = -1 * findaddr(midecode[donenum].rst) ; if(calparanum < 4){ switch(calparanum){ case 0 : if(addr1 == 1){//not find, is global if(isNum(midecode[donenum].rst[0]) || midecode[donenum].rst[0] == '-'){ rstfile << "\t\tli\t$a0\t" << midecode[donenum].rst << endl ; } else{ rstfile << "\t\tla\t$t0\t" << midecode[donenum].rst << endl ; rstfile << "\t\tlw\t$a0\t($t0)" << endl ; } } else{ rstfile << "\t\tlw\t$a0\t" << addr1 << "($fp)" << endl ; } //rstfile << "\t\tlw\t$a0\t" << addr1 << "($fp)" << endl ; break ; case 1 : if(addr1 == 1){//not find, is global if(isNum(midecode[donenum].rst[0]) || midecode[donenum].rst[0] == '-'){ rstfile << "\t\tli\t$a1\t" << midecode[donenum].rst << endl ; } else{ rstfile << "\t\tla\t$t0\t" << midecode[donenum].rst << endl ; rstfile << "\t\tlw\t$a1\t($t0)" << endl ; } } else{ rstfile << "\t\tlw\t$a1\t" << addr1 << "($fp)" << endl ; } //rstfile << "\t\tlw\t$a1\t" << addr1 << "($fp)" << endl ; break ; case 2 : if(addr1 == 1){//not find, is global if(isNum(midecode[donenum].rst[0]) || midecode[donenum].rst[0] == '-'){ rstfile << "\t\tli\t$a2\t" << midecode[donenum].rst << endl ; } else{ rstfile << "\t\tla\t$t0\t" << midecode[donenum].rst << endl ; rstfile << "\t\tlw\t$a2\t($t0)" << endl ; } } else{ rstfile << "\t\tlw\t$a2\t" << addr1 << "($fp)" << endl ; } //rstfile << "\t\tlw\t$a2\t" << addr1 << "($fp)" << endl ; break ; case 3 : if(addr1 == 1){//not find, is global if(isNum(midecode[donenum].rst[0]) || midecode[donenum].rst[0] == '-'){ rstfile << "\t\tli\t$a3\t" << midecode[donenum].rst << endl ; } else{ rstfile << "\t\tla\t$t0\t" << midecode[donenum].rst << endl ; rstfile << "\t\tlw\t$a3\t($t0)" << endl ; } } else{ rstfile << "\t\tlw\t$a3\t" << addr1 << "($fp)" << endl ; } //rstfile << "\t\tlw\t$a3\t" << addr1 << "($fp)" << endl ; break ; } } else{//not only 4 paraments if(addr1 == 1){//not find, is global if(isNum(midecode[donenum].rst[0]) || midecode[donenum].rst[0] == '-'){ rstfile << "\t\tli\t$t8\t" << midecode[donenum].rst << endl ; } else{ rstfile << "\t\tla\t$t0\t" << midecode[donenum].rst << endl ; rstfile << "\t\tlw\t$t8\t($t0)" << endl ; } } else{ rstfile << "\t\tlw\t$t8\t" << addr1 <<"($fp)" << endl ; } rstfile << "\t\tsw\t$t8\t" << -1 * ((calparanum - 4)*4 + 24) << "($sp)" << endl ; } calparanum++ ;}void call_mips(){ calparanum = 0 ; //rstfile << "\t\taddi\t$ra\t$pc\t4" << endl ; rstfile << "\t\tsw\t$fp\t($sp)" << endl;//保存上一个函数的$fp rstfile << "\t\tadd\t$fp\t$sp\t$0" << endl;//设置本函数$fp:$fp=$sp rstfile << "\t\tsubi\t$sp\t$sp\t4" << endl;//$sp-=4 rstfile << "\t\tsw\t$ra\t($sp)" << endl;//保存$ra rstfile << "\t\tjal\t" << midecode[donenum].num_a << endl; rstfile << "\t\tnop\n"; if(strcmp(midecode[donenum].rst, space) != 0){ insertaddr(midecode[donenum].rst) ; int addr1 = -1 * findaddr(midecode[donenum].rst) ; rstfile << "\t\tsw\t$v1\t" << addr1 << "($fp)" << endl ; }}void jmp_mips(){ rstfile << "\t\tj\t" << midecode[donenum].rst << endl ;}void jne_mips(){ rstfile << midecode[donenum].rst << endl ;}void ass_mips(){ int addr1 ; int addr2 ; if(isNum(midecode[donenum].num_a[0]) || midecode[donenum].num_a[0] == '-'){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){//not find, is global rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } addr2 = -1 * findaddr(midecode[donenum].rst) ; if(addr2 == 1){//not find, is global rstfile << "\t\tla\t$t1\t" << midecode[donenum].rst << endl ; rstfile << "\t\tsw\t$t0\t($t1)" << endl ; } else{ rstfile << "\t\tsw\t$t0\t" << addr2 << "($fp)" << endl ; }}void bt_mips(){//> int addr1 ; int addr2 ; if(isNum(midecode[donenum].num_a[0])){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){//not find, is global rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0])){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){//not find, is global rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } rstfile << "\t\tble\t$t0\t$t1\t" ;}void st_mips(){//< int addr1 ; int addr2 ; if(isNum(midecode[donenum].num_a[0])){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){//not find, is global rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0])){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){//not find, is global rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } rstfile << "\t\tbge\t$t0\t$t1\t" ;}void eql_mips(){//== int addr1 ; int addr2 ; if(isNum(midecode[donenum].num_a[0])){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){//not find, is global rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0])){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else if(strcmp(midecode[donenum].num_b, space) == 0){ rstfile << "\t\tli\t$t1\t1" << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){//not find, is global rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } rstfile << "\t\tbne\t$t0\t$t1\t" ;}void neq_mips(){//!= int addr1 ; int addr2 ; if(isNum(midecode[donenum].num_a[0])){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){//not find, is global rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0])){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){//not find, is global rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } rstfile << "\t\tbeq\t$t0\t$t1\t" ;}void nbt_mips(){//<= int addr1 ; int addr2 ; if(isNum(midecode[donenum].num_a[0])){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){//not find, is global rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0])){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){//not find, is global rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } rstfile << "\t\tbgt\t$t0\t$t1\t" ;}void nst_mips(){//>= int addr1 ; int addr2 ; if(isNum(midecode[donenum].num_a[0])){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ addr1 = -1 * findaddr(midecode[donenum].num_a) ; if(addr1 == 1){//not find, is global rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } } if(isNum(midecode[donenum].num_b[0])){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ addr2 = -1 * findaddr(midecode[donenum].num_b) ; if(addr2 == 1){//not find, is global rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; } } rstfile << "\t\tblt\t$t0\t$t1\t" ;}void assignA_mips(){//[] = int addr1 = -1 * findaddr(midecode[donenum].num_a) ;//值 int addr2 = -1 * findaddr(midecode[donenum].num_b) ;//标识符地址偏移 int addr3 = -1 * findaddr(midecode[donenum].rst) ;//数组地址偏移 if(addr1 == 1){//not find, is global if(isNum(midecode[donenum].num_a[0])){ rstfile << "\t\tli\t$t0\t" << midecode[donenum].num_a << endl ; } else{ rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; //准备数据的值 } } else{ rstfile << "\t\tlw\t$t0\t" << addr1 << "($fp)" << endl ; } if(addr2 == 1){//not find, is global if(isNum(midecode[donenum].num_b[0])){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ;//【】中标识符的的偏移量 } rstfile << "\t\tmul\t$t1\t$t1\t-4" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; rstfile << "\t\tmul\t$t1\t$t1\t-4" << endl ; } if(addr3 == 1){//not find, is global rstfile << "\t\tla\t$t2\t" << midecode[donenum].rst << endl ; rstfile << "\t\tadd\t$t1\t$t1\t$t2" << endl ; rstfile << "\t\tsw\t$t0\t($t1)" << endl ; } else{ rstfile << "\t\tli\t$t2\t" << addr3 << endl ; rstfile << "\t\tadd\t$t1\t$t2\t$t1" << endl ; rstfile << "\t\tadd\t$t1\t$t1\t$fp" << endl ; rstfile << "\t\tsw\t$t0\t($t1)" << endl ; }}void aAssign_mips(){//aAss int addr1 = -1 * findaddr(midecode[donenum].num_a) ;//数组变量的地址偏移 int addr2 = -1 * findaddr(midecode[donenum].num_b) ;//[]中标识符的偏移量 //rst is always a $ if(addr1 == 1){//not find, is global rstfile << "\t\tla\t$t0\t" << midecode[donenum].num_a << endl ; //rstfile << "\t\tlw\t$t0\t($t0)" << endl ; } else{ rstfile << "\t\tli\t$t0\t" << addr1 << endl ; rstfile << "\t\tadd\t$t0\t$t0\t$fp" << endl ; } if(addr2 == 1){//not find, is global if(isNum(midecode[donenum].num_b[0])){ rstfile << "\t\tli\t$t1\t" << midecode[donenum].num_b << endl ; } else{ rstfile << "\t\tla\t$t1\t" << midecode[donenum].num_b << endl ; rstfile << "\t\tlw\t$t1\t($t1)" << endl ; } rstfile << "\t\tmul\t$t1\t$t1\t-4" << endl ; } else{ rstfile << "\t\tlw\t$t1\t" << addr2 << "($fp)" << endl ; rstfile << "\t\tmul\t$t1\t$t1\t-4" << endl ; } rstfile << "\t\tadd\t$t0\t$t0\t$t1" << endl ; //rstfile << "\t\tadd\t$t0\t$t0\t$fp" << endl ; rstfile << "\t\tlw\t$t0\t($t0)" << endl ; insertaddr(midecode[donenum].rst) ; int addr3 = -1 * findaddr(midecode[donenum].rst) ; rstfile << "\t\tsw\t$t0\t" << addr3 << "($fp)" << endl ;}void exit_mips(){ rstfile << "\t\tli\t$v0\t10" << endl ; rstfile << "\t\tsyscall" << endl ;}void run(){ initasm() ; while(donenum < codeNum){ //rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; if(strcmp(midecode[donenum].op, func) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; func_mips() ; } else if(strcmp(midecode[donenum].op, ints) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; ints_mips() ; } else if(strcmp(midecode[donenum].op, chars) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; chars_mips() ; } else if(strcmp(midecode[donenum].op, inta) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; inta_mips() ; } else if(strcmp(midecode[donenum].op, chara) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; chara_mips() ; } else if(strcmp(midecode[donenum].op, add) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; add_mips() ; } else if(strcmp(midecode[donenum].op, sub) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; sub_mips() ; } else if(strcmp(midecode[donenum].op, mul) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; mul_mips() ; } else if(strcmp(midecode[donenum].op, divs) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; div_mips() ; } else if(strcmp(midecode[donenum].op, prtf) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; prtf_mips() ; } else if(strcmp(midecode[donenum].op, scf) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; scf_mips() ; } else if(strcmp(midecode[donenum].op, ret) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; ret_mips() ; } else if(strcmp(midecode[donenum].op, lab) == 0){ lab_mips() ; } else if(strcmp(midecode[donenum].op, paraop) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; paraop_mips() ; } else if(strcmp(midecode[donenum].op, calpara) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; calpara_mips() ; } else if(strcmp(midecode[donenum].op, call) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; call_mips() ; } else if(strcmp(midecode[donenum].op, jne) == 0){ jne_mips() ; } else if(strcmp(midecode[donenum].op, jmp) == 0){ jmp_mips() ; } else if(strcmp(midecode[donenum].op, ass) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; ass_mips() ; } else if(strcmp(midecode[donenum].op, bt) == 0){ bt_mips() ; } else if(strcmp(midecode[donenum].op, st) == 0){ st_mips() ; } else if(strcmp(midecode[donenum].op, eql) == 0){ eql_mips() ; } else if(strcmp(midecode[donenum].op, neq) == 0){ neq_mips() ; } else if(strcmp(midecode[donenum].op, nbt) == 0){ nbt_mips() ; } else if(strcmp(midecode[donenum].op, nst) == 0){ nst_mips() ; } else if(strcmp(midecode[donenum].op, assignA) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; assignA_mips() ; } else if(strcmp(midecode[donenum].op, aAssign) == 0){ rstfile << "#" << midecode[donenum].op << " " << midecode[donenum].num_a << " " << midecode[donenum].num_b << " " << midecode[donenum].rst << endl ; aAssign_mips() ; } else if(strcmp(midecode[donenum].op, exits) == 0){ exit_mips() ; } else if(strcmp(midecode[donenum].op, myend) == 0){ myend_mips() ; } donenum++ ; }}
error.cpp
#include <iostream>#include <string.h>#include <fstream>#include <sstream>#include <stdlib.h>//#include "lex.cpp"using namespace std ;#define FILEOPEN_ERROR -1 //file open failed#define ZEROSTART_ERROR 0 //#define UNDEFFUNC_ERROR 1#define UNDEFCHAR_ERROR 2 //undefined IDEN#define UNMATCHSQ_ERROR 3 //unmatched singal quoto#define UNMATCHDQ_ERROR 4 // unmatched double quoto#define OUTOFTABINDEXX_ERROR 5 // out of table max length#define FUNCNAMECOMPLICT_ERROR 6 // function name conplict#define VARNAMECOMPLICT_ERROR 7 //variable name complict#define NAMECOMPLICTGLOBAL_ERROR 8 //name can not complict with global#define DELHEAD_IDMIS_ERROR 9 // id missed in delcare head part#define AFTERASS_NOTIDEN_ERROR 10 // after a assign symbol should be a dientifier symbol#define CONSTDEF_ASSMIS_ERROR 11 // in a const defination assign symbol missed#define CONSTDEF_TYPE_ERROR 12 // const defination have only two type#define SEMICSYMMIS_ERROR 13 // ; missed#define VARDEF_ARRAYINDEX_ERROR 14 //an array index should be number in variable defination#define VARDEF_TYPE_ERROR 15 // in a vardefine, identifier type error#define MAINSYM_ERROR 16 // in a main function, name must be "#define LPARENSYMMIS_ERROR 17 // main ( missed#define RPARENSYMMIS_ERROR 18 // main ) missed#define LBPARENSYMMIS_ERROR 19 // mian {#define RBPARENSYMMIS_ERROR 20 // main }#define RMPARENSYMMIS_ERROR 21 // ] missed#define AFTEROP_NUMMIS_ERROR 22 // -56 ok, -b not accepted#define FACTOR_ERROR 23 // factor type error#define ASSIGNSTATUS_ERROR 24 // assign status error#define STATUS_ERROR 25 // status error#define CONDITIONOP_ERROR 26 // condition status error#define WHILESYMMIS_ERROR 27 // while symbol missed#define IDSYMMIS_ERROR 28 // in a for loop, identifier missed in initial#define FORASSIGNMIS_ERROR 29 // int a for loop initial, assign symbol must appeare#define VARTYPE_ERROR 30 // in a for loop, loop variable should not be a const#define FOROPMIS_ERROR 31 // in for loop step part, op(+/-) missed#define FORDIGSYM_ERROR 32 // in for loop step part, digital missed#define VOIDSYMMIS_ERROR 33 // in main function, void symbol missed#define PARANUM_ERROR 34 // paramenter number error#define UNEXCEPTRETURNVAL_ERROR 35 // void function return value#define READARRAY_ERROR 36 // read an array namechar WARNING[] = {'W','a','r','n','i','n','g',':',' ','\0'} ;char ERROR[] = {'E','r','r','o','r',':',' ','\0'} ;char LINE[] = {'i','n',' ','l','i','n','e',' ','\0'} ;void error(int errorcode, int indexInFile){ switch(errorcode){ case -1 : cout << "file open failed!" << endl ; exit(0) ; break ; case 0 ://warning cout << LINE << indexInFile << "\t" << WARNING << "a num should not start with 0 " << endl ; break ; case 1 : cout << LINE << indexInFile << "\t" << ERROR << "undefined function name " << endl ; break ; case 2 : cout << LINE << indexInFile << "\t" << ERROR << "undefined identifier name " << endl ; break ; case 3 : cout << LINE << indexInFile << "\t" << ERROR << "unmatched singal quotes " << endl ; break ; case 4 : cout << LINE << indexInFile << "\t" << ERROR << "unmatched double quotes " << endl ; break ; case 5 : cout << LINE << indexInFile << "\t" << ERROR << "to much defination " << endl ; exit(0) ; break ; case 6 : cout << LINE << indexInFile << "\t" << ERROR << "function name complicted " << endl ; break ; case 7 : cout << LINE << indexInFile << "\t" << ERROR << "variable name complicted " << endl ; break ; case 8 : cout << LINE << indexInFile << "\t" << ERROR << "variable name complicted with global " << endl ; break ; case 9 : cout << LINE << indexInFile << "\t" << ERROR << "function name missed " << endl ; break ; case 10 : cout << LINE << indexInFile << "\t" << ERROR << "const defination without value " << endl ; break ; case 11 : cout << LINE << indexInFile << "\t" << ERROR << "const defination without assign symbol " << endl ; break ; case 12 : cout << LINE << indexInFile << "\t" << ERROR << "undefined variable type in const defination" << endl ; break ; case 13 : cout << LINE << indexInFile << "\t" << ERROR << "\';\'\tmissed " << endl ; break ; case 14 : cout << LINE << indexInFile << "\t" << ERROR << "unaccepted array index in array defination " << endl ; break ; case 15 : cout << LINE << indexInFile << "\t" << ERROR << "undefined type in variable defination " << endl ; break ; case 16 : cout << LINE << indexInFile << "\t" << ERROR << "false function name in main " << endl ; break ; case 17 : cout << LINE << indexInFile << "\t" << ERROR << "\'(\'\tmissed in main function " << endl ; break ; case 18 : cout << LINE << indexInFile << "\t" << ERROR << "\')\'\tmissed in main function " << endl ; break ; case 19 : cout << LINE << indexInFile << "\t" << ERROR << "\'{\'\tmissed in main function " << endl ; break ; case 20 : cout << LINE << indexInFile << "\t" << ERROR << "\'}\'\tmissed in main function " << endl ; break ; case 21 : cout << LINE << indexInFile << "\t" << ERROR << "\']\'\tmissed " << endl ; break ; case 22 : cout << LINE << indexInFile << "\t" << ERROR << "\'-\'' can only appeared before a number " << endl ; break ; case 23 : cout << LINE << indexInFile << "\t" << ERROR << "unidentified factor " << endl ; break ; case 24 : cout << LINE << indexInFile << "\t" << ERROR << "unidentified identifier in assign status " << endl ; break ; case 25 : cout << LINE << indexInFile << "\t" << ERROR << "unidentified states " << endl ; break ; case 26 : cout << LINE << indexInFile << "\t" << ERROR << "unidentified condition symbol " << endl ; break ; case 27 : cout << LINE << indexInFile << "\t" << ERROR << "\'while\' symbol missed " << endl ; break ; case 28 : cout << LINE << indexInFile << "\t" << ERROR << "identifier lack in for loop " << endl ; break ; case 29 : cout << LINE << indexInFile << "\t" << ERROR << "assign symbol lack in for loop " << endl ; break ; case 30 : cout << LINE << indexInFile << "\t" << ERROR << "loop variable should not be const in for loop " << endl ; break ; case 31 : cout << LINE << indexInFile << "\t" << ERROR << "+/- missed in loop step part " << endl ; break ; case 32 : cout << LINE << indexInFile << "\t" << ERROR << "step digital missed in for loop " << endl ; break ; case 33 : cout << LINE << indexInFile << "\t" << ERROR << "\'void\'\tmissed in main function " << endl ; break ; case 34 : cout << LINE << indexInFile << "\t" << ERROR << "paramenter number unmatched " << endl ; break ; case 35 : cout << LINE << indexInFile << "\t" << ERROR << "void function return a value " << endl ; break ; case 36 : cout << LINE << indexInFile << "\t" << ERROR << "read a array name !" << endl ; break ; }}
0 0
- 基于扩展C0文法的编译器设计(Part3)
- 基于扩展C0文法的编译器设计(Part1)
- 基于扩展C0文法的编译器设计(Part2)
- 编译器学习--文法的类型
- 编译器设计:文法与LL(1)
- 编译器之简单的类C文法
- 一个基于LL(1)文法的语法分析程序
- 基于LL(1)文法实现的简单计算器
- PL/0编译器设计扩展
- 编译器_文法分类
- 编译器的三个扩展
- 基于Predictive Parsing的ABNF语法分析器(十一)——AbnfParser文法解析器之重复文法(repetition)
- UTF-8 C0 控制与基本的 Latin(拉丁字母)
- 浅谈基于常用设计模式的扩展 。
- 扩展欧几里得--part3
- 基于文法分析的简单计算器实现
- 自己动手开发编译器(六)上下文无关语言和文法
- SPIR-V 研究:编译器基本原理(三) - Chomsky文法分类
- 移动端web问题汇总
- 473. Matchsticks to Square(dfs+回溯) / 416. Partition Equal Subset Sum 动归
- 进程与线程的区别
- ST已发布基于PC端的ST MCU选型工具
- java实现定时任务的三种方法(很好理解)
- 基于扩展C0文法的编译器设计(Part3)
- Leetcode 18
- 八张Gif动图形象地为你介绍 flexbox 是如何工作的
- CocoaPods版本升级
- 频谱仪的RBW带宽和VBW带宽
- 《剑指offer》—2、替换空格
- 复杂链表的复制练习
- JS编写input搜索框,类似下拉搜索框
- 移动端web css适配