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

📄 sentence.cpp

📁 编译原理中的语法分析和语义分析
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "sentence.h"
#include "fstream.h"
#include "iostream.h"
#include "stdlib.h"
#include "string.h"
#include "keyword.h"
#include "stdio.h"
#include "conio.h"
/*词法分析结果文件中的非法信息在语法分析中,在给出错误信息后,自动跳过,继续进行分析*/

sentence::sentence()//构造函数初始化各个变量
{
	ErrorFile.open("error.txt",ios::nocreate|ios::out);
	if(ErrorFile.fail())
	{
		cout<<"程序初始化失败!程序将退出!"<<endl;
		exit(0);
	}
	ResultFile.open("result.txt",ios::nocreate|ios::in);
	if(ResultFile.fail())
	{
		cout<<"程序初始化失败!程序将退出!"<<endl;
		ErrorFile.close();
		exit(0);
	}
	CodeFile.open("code.txt",ios::nocreate|ios::out);
	if(CodeFile.fail())
	{
		cout<<"程序初始化失败,程序将退出!"<<endl;
		ErrorFile.close();
		ResultFile.close();
		exit(0);
	}
	line=1;
	errornum=0;
	depth=0;
	varnum=0;
	constnum=0;
	dspnum=1;
	varlength=constlength=100;
	dpstack[0].depth=0;
	dpstack[0].varstart=0;
	dpstack[0].varend=0;
	dpstack[0].conststart=0;
	dpstack[0].constend=0;
	codenum=0;
	ErrorFile<<"                        "<<endl;
	varptr=(varnode *)malloc(sizeof(varnode)*100);
	if(varptr==NULL)
	{
		cout<<"初始化失败,程序将退出!"<<endl;
		exit(0);
	}
	constptr=(constnode *)malloc(sizeof(constnode)*100);
	if(constptr==NULL)
	{
		free(varptr);
		cout<<"初始化失败,程序将退出!"<<endl;
		exit(0);
	}
	update_data.head=(back_info *)malloc(sizeof(back_info)*100);
	if(update_data.head==NULL)
	{
		free(varptr);
		free(constptr);
		cout<<"初始化失败,程序将退出!"<<endl;
		exit(0);
	}
	update_data.sum=0;
	update_data.length=100;
}
sentence::~sentence()//析构函数释放变量和常量占用的存储空间
{
//	cout<<depth<<endl;getch();
	ErrorFile.seekp(0L,ios::beg);
	ErrorFile<<"程序有"<<errornum<<"个错误!";
	ErrorFile.close();
	ResultFile.close();
	CodeFile.close();
	free(varptr);    //释放变量表存储空间
	free(constptr);   //释放常量表存储空间
	if(errornum==0)
	{
		cout<<"\n您的程序没有错误,语法分析通过!"<<endl;
		cout<<"\n下面将进行信息回填,请稍等............"<<endl;
		UpdateFile();
		cout<<"\n本程序虚拟机指令共有 "<<codenum<<" 条,详细信息见 code.txt"<<endl;
	}
	else
	{
		cout<<"\n您输入的程序有"<<errornum<<"个错误,详细信息见 error.txt !"<<endl;
	}
	free(update_data.head); //释放回填表占用的内存
}
int sentence::Insert(int index,int number,int endnum,char * data)//向回填表中插入一个回填信息
//index表示要插入的回填信息在回填表中的位置,number表示回填信息的代码编号
//endnum表示回填信息要跳转到的代码的编号,data回填的其他信息
{
	if(update_data.sum>=update_data.length)
	{
		update_data.length=update_data.sum+50;
		update_data.head=(back_info *)realloc(update_data.head,sizeof(back_info)*update_data.length);
		if(update_data.head==NULL)
		{
			cout<<"内存不足,将退出程序!"<<endl;
			free(varptr);
			free(constptr);
		}
	}
	update_data.head[index].number=number;
	update_data.head[index].endnum=endnum;
	strcpy(update_data.head[index].data,data);
	return 1;
}
int NumberLen(int number)
//返回数字的长度
{
	int i=0;
	do
	{
		i++;
		number/=10;
	}while(number);
	return i;
}
void sentence::UpdateFile()
{
	char code[300];
	int  i,num,j;
	if(update_data.sum==0)
	{
		cout<<"\n代码回填成功!"<<endl;
		return ;
	}
	CodeFile.open("code.txt",ios::in|ios::out|ios::nocreate);
	if(CodeFile.fail())
	{
		cout<<"代码回填失败,程序分析失败!"<<endl;
		return;
	}
	for(i=0,j=0;i<update_data.head[update_data.sum-1].number;i++)
	{
		CodeFile.getline(code,299,'\n');
		if(i==update_data.head[j].number-1)
		{			
			CodeFile.seekp(-strlen(code)-1,ios::cur);
			CodeFile<<"code"<<update_data.head[j].number<<update_data.head[j].data<<update_data.head[j].endnum;
		   	CodeFile.seekp(strlen(code)-12-NumberLen(update_data.head[j].number)-NumberLen(update_data.head[j].endnum)+1,ios::cur);
			j++;
		}
	}
	CodeFile.close();
	cout<<"\n信息回填成功!"<<endl;
}
int sentence::GetWord()
//从文件中读取一个单词及其标号,单词的组成保存在 name,单词的编号保存number中
{
	if(!ResultFile.eof())
	{
		name[0]='\0';
		ResultFile.getline(name,10,' ');
		if(ResultFile.eof())
			return 0;
		ResultFile>>number;
		ResultFile.get();
		if(number==ENTER)
		{
			line++;
//			cout<<endl;//////////////
			return GetWord();
		}
		else if(number==ERROR)
		{
			errornum++;
			ErrorFile<<"行:"<<line<<"\t错误"<<errornum<<":标识符 "<<name<<" 定义非法!"<<endl;
			return GetWord();
		}
//		cout<<" "<<name;///////////
//		getch();
		return 1;
	}
	else
		return 0;
}
void sentence::BackWord()
//使读指针回退一个单位
{
	int length=0,number=this->number;
	while(number)
	{
		number/=10;
		length++;
	}
	length+=strlen(name)+3;
	ResultFile.seekg(-length,ios::cur);
}
void sentence::Error()
//基础错误处理, 向下读单词知道遇到关键字或者专用符号为止
{
	int type;
	errornum++;
	if(number>=PROGRAM&&number<=ODD)
	{
		BackWord();
		return;
	}
	while(1)
	{
    	type=GetWord();
		if(type==0||number==29||number==35)
			break;
		else if(number>=PROGRAM&&number<=ODD)
		{
		//	BackWord();
			break;
		}
	}
}
int sentence::Insert(char *name)
//插入一个变量结点
{
	int index,i;
	index=varnum;
	if(varnum==varlength)
	{
		varlength+=100;
		varptr=(varnode *)realloc(varptr,sizeof(varnode)*(varlength));
		if(varptr==0)
		{
			cout<<"内存不足,程序将退出!"<<endl;
			exit(1);
		}
	}
	varnum++;
    for(i=dpstack[dspnum-1].varstart;i<index;i++)
	{
		if(strcmp(name,varptr[i].name)==0)
		{
			errornum++;
			ErrorFile<<"行:"<<line<<"\t错误"<<errornum<<":标识符 "<<name<<" 在变量中重复定义!"<<endl;
			return 0;
		}
	}
	for(i=dpstack[dspnum-1].conststart;i<constnum;i++)
	{
		if(strcmp(name,constptr[i].name)==0)
		{
			errornum++;
			ErrorFile<<"行:"<<line<<"\t错误"<<errornum<<":标识符 "<<name<<" 已经在常量中定义!"<<endl;
			return 0;
		}
	}
	dpstack[dspnum-1].varend=varnum;
	strcpy(varptr[index].name,name);
	cout<<"Insert var   "<<name<<endl;/////////////////////////
	return 1;
}
int sentence::IsVar(char *name)
//判断一个标识符是否为变量,若不是变量返回-1,否则返回单词的层次,其他信息存储在var_con_info中
{
	int i,j;
	for(i=varnum-1;i>-1;i--)
	{
		if(strcmp(name,varptr[i].name)==0)
			break;
	}
//	cout<<i<<' '<<name<<' '<<varnum<<endl;getch();
	if(i==-1)
		return -1;
	else
	{
		for(j=dspnum-1;j>-1;j--)
		{
			if(i>=dpstack[j].varstart)
				break;
		}
		var_con_info.level=j;
		var_con_info.address=i-dpstack[j].varstart;
		return j;
	}
}
int sentence::Insert(char *name,char *value)
//插入一个常量结点
{
	int index,i;
	index=constnum;
	if(constnum==constlength)
	{
		constlength+=100;
		constptr=(constnode *)realloc(constptr,sizeof(constnode)*constlength);
		if(constptr==NULL)
		{
			cout<<"内存不足,程序将退出!"<<endl;
			exit(0);
		}
	}
	constnum++;
	for(i=dpstack[dspnum-1].conststart;i<index;i++)
	{
		if(strcmp(name,constptr[i].name)==0)
		{
	    	errornum++;
			ErrorFile<<"行:"<<line<<"\t错误"<<errornum<<":标识符 "<<name<<" 在常量中重复定义!"<<endl;
			return 0;
		}
	}
	dpstack[dspnum-1].constend=constnum-1;
	strcpy(constptr[index].name,name);
	strcpy(constptr[index].value,value);
	cout<<"Insert const   "<<name<<"  value:"<<value<<endl;/////////////////////////*/
	return 1;
}
int sentence::IsConst(char *name)
//判断一个标识符是否为常量,返回值同IsVar
{
	int i,j;
	for(i=constnum-1;i>-1;i--)
	{
		if(strcmp(name,constptr[i].name)==0)
			break;
	}
	if(i==-1)
		return -1;
	else
	{
		for(j=dspnum-1;j>-1;j--)
		{
			if(i>=dpstack[j].conststart)
				break;
		}
		var_con_info.level=j;
		var_con_info.address=i;
		return j;
	}
}
int sentence::constanalyse()//常量分析
{
	int type,tag=0;
	char constname[10];
	while(1)
	{
		type=GetWord();
		if(type==0)
		{
			ConstError(4);
			errornum++;
			break;
		}		
		switch(tag)
		{
		case 0:if(number==ID)
			   {
				   strcpy(constname,name);
				   tag=1;
			   }
			   else
			   {
				   ConstError(0);
				   Error();//error
				   cout<<"const finish error"<<endl;///////////////////
				   return 0;
			   }
			   break;
		case 1:if(number==16)
				   tag=2;
			   else
			   {
				   ConstError(1);
				   Error();//error
				   cout<<"const finish error"<<endl;////////////////////////
				//   cout<<name<<"  "<<number<<endl;
				   return 0;
			   }
			   break;
		case 2:if(number==NUMBER)
			   {
				   Insert(constname,name);
				   tag=3;
			   }
			   else
			   {
				   ConstError(3);
				   Error();//error
				   cout<<"const finish error"<<endl;//////////////////
				   return 0;
			   }
			   break;
		case 3:if(number==29)
			   {
				   cout<<"const finish"<<endl;/////////////
				   return 1;
			   }
			   else if(number==30)
				   tag=0;
			   else
			   {
				   ConstError(3);
				   Error();//error
				   cout<<"const finish error"<<endl;////////////////////////////
				   return 0;
			   }
		}
	}
	cout<<"const finish"<<endl;
	return 1;
}
void sentence::ConstError(int tag)
{
	switch(tag)
	{
	case 0:
	case 2:
	case 3:ErrorFile<<"行:"<<line<<"\t错误"<<errornum+1<<":标识符 "<<name<<" 在常量定义中非法!"<<endl;
		   break;
	case 4:ErrorFile<<"行:"<<line<<"\t错误"<<errornum+1<<":常量定义缺少符号 ; "<<endl;
		   break;
	case 1:ErrorFile<<"行:"<<line<<"\t错误"<<errornum+1<<":标识符 "<<name<<" 前缺少 = 在常量定义中!"<<endl;
		   break;
	
	}
}
int sentence::varanalyse()//变量分析
{
	int type,tag=0;
	while(1)
	{
    	type=GetWord();
		if(type==0)
			break;
		else
		{
			switch(tag)
			{
			case 0:if(number==ID)
				   {
					   Insert(name);
					   tag=1;
				   }
				   else
				   {
					   VarError(0);
					   Error();  
					   return 0;
				   }
				   break;
			case 1:if(number==29)
				   {
					   cout<<"var finish"<<endl;///////////////////////////
					   return 1;
				   }
				   else if(number==30)
					   tag=0;
				   else
				   {
					   VarError(1);
					   Error(); 
					   cout<<"var finish error"<<endl;///////////////////
					   return 0;
				   }
			}
		}
	}
	return 1;
}
void sentence::VarError(int tag)//变量定义错误处理
{
	if(tag==0)
	{
		ErrorFile<<"行:"<<line<<"\t错误"<<errornum+1<<":标识符 "<<name<<" 在变量定义中非法!"<<endl;
	}
	else
	{
		ErrorFile<<"行:"<<line<<"\t错误"<<errornum+1<<":变量定义结束符号';'未在正确位置!"<<endl;
	}
}
int sentence::Proganalyse()
{
	int tag=0,type;
	while(1)
	{
		type=GetWord();
		if(type==0)
		{
			if(tag!=4)
			{
				errornum++;
				ErrorFile<<"行:"<<line<<"\t错误"<<errornum<<":编辑的程序缺少文件尾!"<<endl;
			}
			return 0;
		}
		if(tag==4)
		{
			ProgError(0);
			GetWord();
			continue;
		}
		switch(number)
		{
		case PROGRAM:if(tag==0)
					 {
						 tag=1;
					 }
			         else
					 {
						 ProgError(0);//error
					 }
					 break;
		case ID:if(tag==0)
				{
					ProgError(PROGRAM);//error
					tag=2;
				}
			    else if(tag==1)
				{
					tag=2;
				}
				else
				{
					ProgError(0);//error
				}
				break;
		case 29:if(tag==0)
				{
					ProgError(PROGRAM);//error
					tag=3;
				}
			    else if(tag==1)
				{
					ProgError(ID);//error
					tag=3;
				}
				else if(tag==2)
				{
					tag=3;
					Blockanalyse();
					if(number==35)
					{
						tag=4;
						cout<<"prog finish"<<endl;
						return 1;
					}
				}
				else
				{
					ProgError(0);//error
				}
				break;
		case 35:tag=4;
			    break;
		default:ProgError(0);
		}
	}
	cout<<"prog finish"<<endl;
	return 1;
}
void sentence::ProgError(int tag)
{
	errornum++;
	switch(tag)
	{
	case PROGRAM:ErrorFile<<"行:"<<line<<"\t错误"<<errornum<<":程序缺少一个程序开始标识符 program!"<<endl;
		         break;
	case ID:ErrorFile<<"行:"<<line<<"\t错误"<<errornum<<":程序未进行命名!"<<endl;
		    break;
	case 29:ErrorFile<<"行:"<<line<<"\t错误"<<errornum<<":程序名后缺少符号 ; "<<endl;
		    break;
	default:ErrorFile<<"行:"<<line<<"\t错误"<<errornum<<":标识符 "<<name<<" 在该处使用非法!"<<endl;
	}
}
int sentence::Blockanalyse()//block部分分析
{
	int tag=0,type=0,success;
	type=GetWord();
	while(1)
	{
		if(type==0||number==35)
    		return 0;
    	switch(number)
		{
     	case CONST:if(tag==0)
				   {
		     		   tag=1;
			    	   success=constanalyse();
					   if(success==1)
					   {
						   type=GetWord();
					///	   cout<<number<<endl;
					   }
				   }
		          else
				  {
		    		   BlockError(CONST);//error
		    		   Error();
				  }
		    	   break;
    	case VAR:if(tag<2)
				 {
	     			 tag=2;
	    			 success=varanalyse();
					 if(success==1)
					 {
						 type=GetWord();
					 }
	    		//	 cout<<"var"<<endl;/////////////
				 }
	    	     else
				 {
		    		 BlockError(VAR);
		    		 Error();//error
				 }
	    		 break;
    	case PROCEDURE:if(tag<3)
					   {
	    				   tag=3;
						   success=procanalyse();
						   if(success==0)
						   {
							   type=GetWord();
						   }
		    			   ;//proanalyse
					   }
		               else
					   {
		    			   BlockError(PROCEDURE);//error
						   GetWord();
						   GetWord();
						  
					//	   Error();//error
					   }
		    		   break;
    	case BEGIN:return bodyanalyse();
    	default:GetWord();break;
		}
	}
	return 1;
}
void sentence::BlockError(int tag)//block分析出错处理
{
	switch(tag)
	{
	case CONST:ErrorFile<<"行:"<<line<<"\t错误"<<errornum+1<<":进行常量定义的位置非法!"<<endl;
		   break;
	case VAR:ErrorFile<<"行:"<<line<<"\t错误"<<errornum+1<<":进行变量定义的位置非法!"<<endl;
		   break;
	case PROCEDURE:ErrorFile<<"行:"<<line<<"\t错误"<<++errornum<<":过程定义的位置非法!"<<endl;
		           break;
	}
}
int sentence::procanalyse()//新过程分析
{
	int value,type,tag=0;
	depth++;
	dpstack[dspnum].varstart=dpstack[dspnum-1].varend;
	dpstack[dspnum].conststart=dpstack[dspnum-1].constend;
	dspnum++;
	while(tag!=5)
	{
		type=GetWord();
		if(type==0)
			return 0;
		switch(tag)
		{
		case 0:if(number==ID)
			   {
				   tag=1;
			   }
			   else
			   {
				   ProcError(ID);//error
			   }
			   break;
		case 1:if(number==27)//符号 (
			   {
				   tag=2;
			   }
			   else
			   {
				   ProcError(27);//error
			   }
			   break;
		case 2:if(number==ID)
			   {
				   tag=3;
				   Insert(name);//插入形参变量
			   }
			   else
			   {
				   if(number==28)
					   tag=4;
				   else if(number==29)
					   tag=5;
				   ProcError(ID+1);//error
			   }
			   break;
		case 3:if(number==30)//符号 ,
			   {
				   tag=2;
			   }
			   else if(number==28)// 符号 )
			   {
				   tag=4;
			   }
			   else
			   {
				   if(number==29)
					   tag=5;
				   ProcError(29);//error
			   }
			   break;
		case 4:if(number==29)//符号 ;

⌨️ 快捷键说明

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