www.pudn.com > for_diguixiajiang.rar > for.cpp
#include#include #include #include #define $other 19 #define $mul 20 #define $div 21 #define $add 22 #define $sub 23 #define $fen 24 #define $equal 25 #define $for 26 #define $step 27 #define $until 28 #define $do 33 #define $big 29 #define $small 30 #define $id 31 #define $num 32 #define $zizeng 34 #define $zijian 35 ///////////////////////////////////////////////////////////// typedef struct Token { int type; //字符类别 char ch; //字符属性 }Token; //定义输入串的结构 typedef enum{JUMP,JG,JL,equal,END,add,mul,sub,div,zizeng,zijian}OpKind; //操作符枚举 typedef struct { int label;//标号 OpKind op;//操作符 char par1,par2; //操作数 union{ char result; //结果 int address; // 地址 }; }Quad; //初始化各全局变量 ///////////////////////////////////////////////////////////// #define MAX_TOKEN 256 //Token表大小 词法分析 #define MAX_QUAD 256 //三地址数组大小 Token tokentable[MAX_TOKEN]; //建立词法表 Quad quad[MAX_QUAD]; //建立三地址表 int nbln=0; //第几条三地址 int n=0; //nbl1中当前包含几个字符 int j=0; int m=0; int token_index;//token表索引 int total_len;//token表有效长度 int quad_len;//三地址表有效长度 int quad_index;//三地址索引 Token cur; Token queue[10]; //定义token队列 int label,k,one; //标记接口 ifstream ins; int trueadd,falseadd,end; //申明函数 bool init(char filename[255]); //打开文件函数 bool cifa(); //词法分析函数 void print(); //词法输出函数 void backpath(int,int); //回填地址 void ERROR(); //错误函数 void S(); char M_addsub(); char F_addsub(char); char P_muldiv(char); char T_muldiv(); char B_number(); void E1(); void E2(); void E3(); bool nexttoken(); int newlabel(); char newchar(); void push(); void yuyi(); //语义分析函数 void printQuad(); //输出三地址表 void AD_ADDRESS(int nlabel,OpKind nop,char npar1,char npar2,int naddress); void AD_RESULT(int nlabel,OpKind nop,char npar1,char npar2, char nresult); /////////////////////////////////////////////////////////////// void main() { cout<<"文法结构:"< for E1 step E2 until E3 do S|id=M"< id=digit "< id < id | id >id "< ++id|--id|id++|id--"< TF|T"< +TF |-TF|ε"< BP|B"< *BP|/BP|ε"< id|digit"< >fname; if(!init(fname)) //打开文件 return ; if(!cifa()) //调用cifa()函数进行词法分析 return ; char ch; while(1) { if(ins.eof()) break; ins>>ch; } cout<<"词法分析结果:"< >ch; if(ins.fail()) break; while(ch==' ') { ins>>ch;} if(ch=='f') //对输入串进行扫描 { ins>>buf; if(strcmp(buf,"or")==0) //扫描到for tokentable[total_len++].type=$for; //就将for关键字存入表中 } else if(ch=='s') { ins>>buf; if(strcmp(buf,"tep")==0) tokentable[total_len++].type=$step; //将step关键字存入表中 }else if(ch=='u') { ins>>buf; if(strcmp(buf,"ntil")==0) tokentable[total_len++].type=$until; //将until关键字存入表中 } else if(ch=='d') { ins>>buf; if(strcmp(buf,"o")==0) tokentable[total_len++].type=$do; //将do关键字存入表中 } else if(ch=='>') //以下将其他字符或数字存入表中 { tokentable[total_len++].type=$big; } else if(ch=='<') { tokentable[total_len++].type=$small; } else if(ch=='=') { tokentable[total_len++].type=$equal; } else if((ch>='A'&& ch<='Z' )|| (ch>='a' && ch<='z')) { tokentable[total_len].type=$id; tokentable[total_len++].ch=ch; } else if(ch>='0' && ch<='9') { tokentable[total_len].type=$num; tokentable[total_len++].ch =ch; } else switch (ch) //将扫描到的操作符存入表中 {case '+' : tokentable[total_len].type=$add; tokentable[total_len++].ch =ch; break; case '-' : tokentable[total_len].type=$sub; tokentable[total_len++].ch =ch; break; case '/' : tokentable[total_len].type=$div; tokentable[total_len++].ch =ch; break; case '*' : tokentable[total_len].type=$mul; tokentable[total_len++].ch =ch; break; case ';' : tokentable[total_len].type=$fen; tokentable[total_len++].ch =ch; case '++' : tokentable[total_len].type=$zizeng; tokentable[total_len++].ch =ch; case '--' : tokentable[total_len].type=$zijian; tokentable[total_len++].ch =ch; break; default:cout<<"!"< =total_len) return false; if(tokentable[token_index].type==$fen) token_index++; //略过分号 cur.type=tokentable[token_index].type; cur.ch=tokentable[token_index].ch; token_index++; return true; } //进队列 void push() { while(tokentable[token_index].type!=$fen) { queue[one].type=tokentable[token_index].type; queue[one].ch=tokentable[token_index].ch; token_index++; one++; } } //队列下一个字符 void next() { one--; //后进先出 cur.type=queue[one].type; cur.ch =queue[one].ch ; } //错误处理 void ERROR(char str[20]) { label++; cout< id=M | for E1 step E2 until E3 do S语句 { char rtn; char c; if(!nexttoken()) ERROR("s(0)"); if(cur.type==$id) { c=cur.ch; if(!nexttoken()) ERROR("S(0)"); if(cur.type!=$equal) ERROR("S(0)"); push(); //id= 入栈 rtn=M_addsub(); //调用M_addsub()函数分析M AD_RESULT(quad_len,equal,rtn,0,c); //分析同时产生三地址 nexttoken(); //加入三地址表中 while(cur.type==$id) { c=cur.ch; if(!nexttoken()) ERROR("S(0)"); if(cur.type!=$equal) ERROR("S(equal)"); push(); rtn=M_addsub(); AD_RESULT(quad_len,equal,rtn,0,c); nexttoken(); } } else if(cur.type==$for) //当当前字符为for时 { E1(); //判断表达式E真值,调用E()函数 if(!nexttoken()) ERROR("S(0)"); if(cur.type==$step) E2(); if(cur.type==$until) E3(); if(cur.type==$do) // { S(); } else { ERROR("S(do)"); } } else ERROR("S(for)"); } void E1() // 处理E1->id =B语句 { char a,b; int c; if(!nexttoken()) ERROR("E(0)"); if(cur.type==$id) { a=cur.ch; if(!nexttoken()) ERROR("E(0)"); if(cur.type==$equal) { c=cur.type ; if(!nexttoken()) ERROR("E(0)"); if(cur.type==$num) b=cur.ch; else ERROR("E(id/num)"); if(c==$big) { trueadd=quad_len; falseadd=quad_len+1; AD_ADDRESS(quad_len,JG,a,b,trueadd); //语法分析同时产生三地址 AD_ADDRESS(quad_len,JUMP,0,0,falseadd); //并加入三地址表中 } else { trueadd=quad_len; falseadd=quad_len+1; AD_ADDRESS(quad_len,JL,a,b,trueadd); AD_ADDRESS(quad_len,JUMP,0,0,falseadd); } } else ERROR("E(id/num)"); } else ERROR("E(big/small)"); } void E2() // 处理E2->id id语句 { char a,b; int c; if(!nexttoken()) ERROR("E(0)"); if(cur.type==$id||cur.type==$num) { a=cur.ch; if(!nexttoken()) ERROR("E(0)"); if(cur.type==$big||cur.type==$small) { c=cur.type ; if(!nexttoken()) ERROR("E(0)"); if(cur.type==$id||cur.type==$num) b=cur.ch; else ERROR("E(id/num)"); if(c==$big) { trueadd=quad_len; falseadd=quad_len+1; AD_ADDRESS(quad_len,JG,a,b,trueadd); //语法分析同时产生三地址 AD_ADDRESS(quad_len,JUMP,0,0,falseadd); //并加入三地址表中 } else { trueadd=quad_len; falseadd=quad_len+1; AD_ADDRESS(quad_len,JL,a,b,trueadd); AD_ADDRESS(quad_len,JUMP,0,0,falseadd); } } else ERROR("E(id/num)"); } else ERROR("E(big/small)"); } void E3() // 处理E3->++id|--id|id++|id--语句 { char a,b; int c,d; if(!nexttoken()) ERROR("E(0)"); if(cur.type==$id) { a=cur.ch; if(!nexttoken()) ERROR("E(0)"); if(cur.type==$zizeng||cur.type==$zijian) { c=cur.type ; if(!nexttoken()) ERROR("E(0)"); } else if(cur.type==$zizeng||cur.type==$zijian) { d=cur.type ; if(!nexttoken()) ERROR("E(0)"); if(cur.type==$id) { b=cur.ch; if(!nexttoken()) ERROR("E(0)"); } } } else ERROR("E(big/small)"); }//处理M->TF|T 规则对应句子 char M_addsub() { char rtn,t; rtn=T_muldiv(); //调用T_muldiv()函数分析乘除法 t=rtn; rtn=F_addsub(t); //调用F_addsub(t)函数分析加减法 return rtn; } //处理乘除法,处理P->*BP|/BP|ε 规则对应句子 char P_muldiv(char a) { char t,b; next(); if(cur.type==$mul||cur.type==$div) { int op=cur.type; b=B_number(); t=newchar(); if(op==$mul) AD_RESULT(quad_len,mul,a,b,t); //分析同时产生三地址 else //加入三地址表中 AD_RESULT(quad_len,div,a,b,t); } else t=a; return t; } //处理加减法,处理F-> +TF |-TF|ε 规则对应句子 char F_addsub(char a) { char t,b; if(cur.type==$add||cur.type==$sub) {int op=cur.type ; b=T_muldiv(); t=newchar(); if(op==$add) AD_RESULT(quad_len,add,a,b,t); //分析同时产生三地址 else AD_RESULT(quad_len,sub,a,b,t); } else t=a; return t; } //处理T->BP|B 规则对应句子 char T_muldiv() { char t; char rtn; rtn=B_number(); t=rtn; rtn=P_muldiv(t); return rtn; } //处理B->id|digit 规则对应句子 char B_number() { char rtn; next(); if(cur.type==$num||cur.type==$id) rtn=cur.ch ; else cout<<"error:B()"< '; if(tokentable[token_index].type==$small) cout< -1) cout<<"L"< ,"< ='0' && quad[i].result<='9') cout<<"+ ,"< ='0' && quad[i].result<='9') cout<<"- ,"< ='0' && quad[i].result<='9') cout<<"/ ,"< ='0' && quad[i].result<='9') cout<<"* ,"<