⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 micro( ok 07.6.27基本完成).cpp

📁 微小语言编辑器的代码 虽然简单但是LINUX都是由MINIX来的 这也算是启发之源了
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			Expr();
			if(flag!=8)//在 Expr()中已读入单词 
				Error(8);
			Match(6,15);
		}
		else if(flag==9)//read
		{
			Match(7,9);
			Match(3,10);
			Match(8,11);
			Match(6,15);
		}
		else if(flag==3)//变量名
		{
			Match(12,12);//赋值语句左部不是\":=\"
			Expr();
			if(flag!=6)//在 Expr()中已读入单词 
				Error(15);
		} 
		else
			Error(13);//语句头单词错
		
		Scanner();
		
		if(flag==0)//不存在end时的终止判断
		{
			Error(14);//程序结束符错
			Error(15);
			return;
		}
		
	}while(flag!=11);//end  
	Match(13,14);//stop
	cout<<"语法分析结束"<<endl;//debug
	
}

void MicroComPile::disvarForm()//仅调试使用
{
	
	int i,j;
	
	for( i=0;varForm[i].varName[0];i++)
	{
		for(j=0;varForm[i].varName[j];j++)
			cout<<varForm[i].varName[j];
		
		cout<<"<----->";
		
		for( j=0;varForm[i].varType[j];j++)	
			cout<<varForm[i].varType[j];
		cout<<endl;
		
	}
	
}	

void  MicroComPile::Semantic()//语义分析及中间代码生成
{ 
	bool s;
	for(int i=0;i<20;i++)
		for(int j=0;j<10;j++)
		{
			varForm[i].varName[j]='\0';
			varForm[i].varType[j]='\0';
		}
		
		
		Scanner();//读掉begin
			Scanner();//var
		do
		{
			s=0;
		
			Scanner();//读变量
			int j;
			for( j=0;varForm[j].varName[0];j++)
				if(strcmp(varForm[j].varName,thisWord)==0)
				{
					s=1;//置标志为1
					ErrOfSemantic(1);
					//"错误:变量重复定义+
					break;
				}
				
				
				if(s==0)//s==0 说明变量不重复
				{
					strcpy(varForm[j].varName,thisWord);
					//将变量名写入符号表
					Scanner();//读掉‘:’
					Scanner();//读变量类型
					strcpy(varForm[j].varType,thisWord);
					
				}
				else
				{	
					Scanner();//读掉‘:’
					Scanner();//读变量类型
				}

				Scanner();//读掉‘;’
			Scanner();//var
				
				
		}while(flag==2);
		
		do
		{//刚开时循环时的thisWord为不符合上一个while条件时退出的词
			if(flag==10)//write
			{
				Scanner();//读掉‘(’
				ExprSemantic();//递归调用,退出时已读掉了‘)’
			
				cout<<"#WRITE  "<<ProduceMiddleP()<<endl;
				Scanner();//读掉‘;’
			    
			}
			else if(flag==9)//read
			{
				
				Scanner();//读掉‘(’
				Scanner();
				int j=varTest();//此处read(x)中的x只能为变量不能为常数
				cout<<"#READ  "<<varForm[j].varName<<endl;
				Scanner();//读掉‘)’
				Scanner();//读掉‘;’
				
			}
			else//一定是变量名
			{
				int j=varTest();//直接检测从Scanner()中读到的变量
               
				Scanner();//读掉':='
				ExprSemantic();//递归调用,退出时已读掉了‘;’
				//ProduceMiddleP();
				cout<<"ASSIC  "<<varForm[j].varName<<"  "<<ProduceMiddleP()<<endl;
			}
			Scanner();//曾经因丢了这句而调试了好长时间07.5.12
			
		}while(flag!=11);//end  
		cout<<"语义分析结束"<<endl;//debug
}
///////////////////////////////////////////////////////////////

void MicroComPile::disbiao()//仅测试用
{
	
	int i,j;
	
	for( i=0;i<Ecount;i++)
	{
		for( j=0;express[i].N_Str[j];j++)
			cout<<express[i].N_Str[j];
		cout<<"--";
		for( j=0;express[i].C_Str[j];j++)
			cout<<express[i].C_Str[j];
		cout<<"--";
		cout<<express[i].R_Num<<"--";
		cout<<express[i].Z_Num<<"\n";
		
	}
	cout<<endl;	cout<<endl;
	
	
	for( i=0;i<Ecount;i++)
	{
		for( j=0;express[i].N_Str[j];j++)
			cout<<express[i].N_Str[j];
		cout<<"--";
		
	}
	cout<<endl;
}
/////////////////////////////////////////////////

char* MicroComPile::ProduceMiddleP()
{
	int mm=0;//产生临时变量的种子值
	int i,j;
	int u=0;
	char temp[6];//临时变量名 
	char stack2[20][10];//改改
    if(strcmp(express[0].C_Str,"integer")==0)//l类型检查准备
		//todo
	
			//todo


	
	for(  i=0;i<20;i++)
		for( j=0;j<10;j++)
		stack2[i][j]='\0';	
		
		for(  i=0;i<Ecount;i++)
		{
			if(express[i].N_Str[0]!='*'&&express[i].N_Str[0]!='+')
			{
				
				strcpy(stack2[u],express[i].N_Str);
				u++;
			}
			else
			{
				
				strcpy(temp,newadress(mm));
				mm++;
				
				if(express[i].N_Str[0]=='*')
				{
					cout<<"MUL  "<<stack2[u-2]<<"  "<<stack2[u-1]<<" "<<temp<<"\n";
					u=u-2;
					strcpy(stack2[u],temp);
					
					u++;
				}
				else
				{
					cout<<"ADD  "<<stack2[u-2]<<"  "<<stack2[u-1]<<" "<<temp<<"\n";
					u=u-2;
					strcpy(stack2[u],temp);
					
					u++;
				}
				
			}//end else
		

		}//end for
	
			return stack2[0];	
}

////////////////////////////////////
char* MicroComPile::newadress(int n)
{//理论上最多可产生26个临时变量,应该够了
	char ch='A';
	ch=(int)ch+n;
	char T[6]="Temp";
	T[4]=ch;
	//cout<<T<<endl;
	return T;
}
/////////////////////////////
void MicroComPile::ExprSemantic()
{
	////////////////////////////////////////////////////////////////////
	//表达式处理要决:1。中缀式——>后缀式,2。将后缀式依次转化为中间代
	//码,关于以上细节,可在任何一本“数据结构”书的“堆栈应用章节中看到
	////////////////////////////////////////////////////////////////////
	int i;
	int Scount=-1;
	Ecount=0;//类成员变量
	char stack[10];//运算符栈
	
	for(i=0;i<10;i++)
		stack[i]='\0';
	
	
	
	for(  i=0;i<10;i++)
	{
		for(int j=0;j<10;j++)
		{
			express[i].N_Str[j]='\0';
			express[i].C_Str[j]='\0';
		}
		
		
        express[i].R_Num=0;
		express[i].Z_Num=0;
	}
	
	////////////////////////以上为变量 的申明及初始化/////////////////////////

	do{
		Scanner();
		if(flag==3)//ID
		{
			int add=varTest();//检测变量是否有声明
            if(add!=-1)
			{//检测正确的时候将变量名及类型写入后缀式表
				strcpy(express[Ecount].N_Str,thisWord);
				strcpy(express[Ecount].C_Str,varForm[add].varType);
				Ecount++;
            }
            
		}
		else if(flag==7)//(
		{   
			Scount++;
			stack[Scount]='(';
			
			ExprSemantic();//递归调用
			
			Scanner();//读到的一定是')'
			
			while(stack[Scount]!='(')
			{//将'('内的符号依次退栈
				express[Ecount].N_Str[0]=stack[Scount];
                Ecount++;
				Scount--;
			}
			Scount--;//将'('亦退栈
		}
		else if(flag==16 )// flag==16 为int型
		{//整型常数及类型写入后缀式表
			strcpy(express[Ecount].N_Str,thisWord);
			strcpy(express[Ecount].C_Str,"integer");		
			express[Ecount].Z_Num=atoi(thisWord);
            Ecount++;
		}
		else if(flag==17) // flag==17 为float型
		{  //实型常数及类型写入后缀式表  
			strcpy(express[Ecount].N_Str,thisWord);
			strcpy(express[Ecount].C_Str,"real");		
			express[Ecount].R_Num=atof(thisWord);
			Ecount++;
		}
		else;//说明原代码有错,这应该在语法分析阶段已查处;
		
		Scanner();//读运算符*或+	
		
		if(flag==14)//*
		{
			while(Scount>=0&&stack[Scount]=='*')
			{
				
				express[Ecount].N_Str[0]=stack[Scount];
                Ecount++;
				Scount--;
			}
			Scount++;	
			stack[Scount]='*';
		}
		else if(flag==15)//+
		{  
			while(Scount>=0&&stack[Scount]!='(')
			{	
				express[Ecount].N_Str[0]=stack[Scount];
				
                Ecount++;
				Scount--;
			}
			Scount++;
			stack[Scount]='+';
			
			
		}
		/*/////////////////////////////////////
		
		  else//;or)
		  {
		  if(flag==8)
		  Scanner();//读掉‘;’
		  else;
		  }
		///////////////////////////*/
		else;//赋值语句时读到的是';'write语句时读到的是')'
		
		
	}while(flag==14||flag==15);	//+or*时while 
	////////////////////////////////////////////////////////////////
	while(Scount>=0)
	{//将符号栈中剩余的符号写到后缀表中
		express[Ecount].N_Str[0]=stack[Scount];
		
		Ecount++;
		Scount--;
	}
	
}//函数结束



///////////////////////////////////////////////////////////////////
int  MicroComPile::varTest()//功能:检测变量是否有声明
{
	bool ss=0;
	
	for(int j=0;varForm[j].varName[0];j++)
		
		if(strcmp(thisWord,varForm[j].varName)==0)
		{
			ss=1;//若找到定义的变量则置标志为1
           	
			break;
		}	
		
		//cout<<ss;
		if(ss==0)//s==0 说明变量未声明
		{
			ErrOfSemantic(2);	//错误:变量未声明
			return -1;
		}
		else 
			return j;
		
}
void  MicroComPile::ErrOfSemantic(int n)
{
	err++;
	cout<<"第"<<numOfEnter<<"行 第"<<numOfLine<<"个字符处: ";
	switch(n)
	{
	case 1:cout<<"变量重复声明"<<endl;break;
	case 2:cout<<"变量未声明"<<endl;break;
	case 3:cout<<"左右类型不匹配"<<endl;break;
	default:cout<<"程序内部错误号调用出现错误!!!"<<endl;
	}
}

//////////////////////////////////////////////////////////////
void main()
{
	MicroComPile mySemantic("input.txt");//
	//mySemantic.Parser();
	mySemantic.Semantic();
	//mySemantic.disbiao();
	
	//mySemantic.disvarForm();
	//	mySemantic.DisplayResult();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -