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->idid语句 
{   
 	   
 	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<<"* ,"<