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

📄 fenxi.cpp

📁 编译原理课程设计,语法分析.学校的课程设计,好象还有点用吧
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "Share.h"

int iCodeLine=0;  //三地址代码行数
int iAddress=DATAADDRESS; //当前数据地址
extern char strFile[256]; //文件名
extern Symbol_table table;
extern ifstream infile;
extern int irow;

KeyWord key_table[23]=
{
	{"program",'p'},{"var",'v'},{"array",'a'},{"of",'o'},{"integer",'n'},{"real",'r'},
	{"function",'f'},{"procedure",'c'},{"begin",'b'},{"end",'e'},{"if",'i'},{"then",'t'},
	{"else",'s'},{"while",'w'},{"do",'d'},{"not",'!'},{"div",'g'},{"mod",'m'},{"and",'&'},
	{"or",'|'},{"record",'z'},{"read",'x'},{"write",'y'}
};

void SetTokenProperty(int iPointer,int iType,int iAddress,int iDomain)
{
	table.setAddress(iPointer,iAddress);
	table.setDimension(iPointer,iDomain);
	table.setType(iPointer,iType);
}

int GetType(int iPointer)
{
	return table.getType(iPointer);
}

int Insert(int iType,int iWidth) //插入指定类型的变量
{
	int pos=table.insert("");
	SetTokenProperty(pos,iType,iAddress,0);
	iAddress+=iWidth;
	return pos;
}

bool Program() //语法分析主程序 O -> program id ( idB ) ;CDE
{
	TOKEN token;
	int address=DATAADDRESS;  //变量起始地址
	char buffer[10240]={0};
	irow=0;
	infile.open(strFile,ios::binary);
	//程序头,若程序头不出错,直接记录出错信息后返回
	token=accidence(infile,irow,1);   //获取第一个记号Program
	if(token.iType!=KEYWORD ||token.dProperty!='p') //主程序关键字不对
	{
		WriteError("非法的程序头,应以program开始",token.iPosition);
		return false;
	}

	token=accidence(infile,irow,1);   //获取下一个记号id
	if(token.iType!=DESIGNATOR) 
	{
		WriteError("非法的程序头,无程序名",token.iPosition);
		return false;
	}

	token=accidence(infile,irow,1);   //获取下一个记号 (
	if(token.dProperty!='(') //主程序关键字不对
	{
		WriteError("非法的程序头,缺少'('",token.iPosition);
		return false;
	}

	token=accidence(infile,irow,1);  //读取标识符id
	if(token.iType!=DESIGNATOR)
	{
		WriteError("非法的参数表",token.iPosition);
		return false;
	}
	if(!IdentifierList()) //程序头参数类表
	{
		return false;
	}
	token=accidence(infile,irow,1); //获取下一个记号 )
	if(token.dProperty!=')') 
	{
		WriteError("非法的程序头,缺少')'",token.iPosition);
		return false;
	}
	token=accidence(infile,irow,1); //获取下一个记号 ;
	if(token.dProperty!=';')   
	{
		WriteError("非法的程序头,缺少';'",token.iPosition);
		return false;
	}


	if(!Declations())  //声明
	{
		return false;
	}
	if(!SubprogramDeclarations()) //子程序声明
	{
		return false;

	}
    if(!CompoundStatement(buffer))   //复合语句
	{
		return false;
	}

	WriteCode(buffer);
	return true;
}

bool IdentifierList()     //标识符列表 B
{
	TOKEN token;

	token=accidence(infile,irow,0);  //读取下一记号, 或)
	if(token.iType!=KEYWORD)
	{
		WriteError("非法的参数表",token.iPosition);
		return false;
	}

	if(token.dProperty==')') //B->空
	{
		return true;
	}
	else if(token.dProperty==',')  //B->, idB
	{
		token=accidence(infile,irow,1);//读取下一记号,
		token=accidence(infile,irow,1);//读取下一记号id
		if(token.iType!=DESIGNATOR)
		{
			WriteError("非法的参数表",token.iPosition);
			return false;
		}
		return IdentifierList();
	}
	
	WriteError("无效的关键字",token.iPosition);
	return false;
}

bool Declations()  //变量声明 C
{
	TOKEN token;
	int num;

	token=accidence(infile,irow,0);  //读取Var说明
	if(token.iType!=KEYWORD)
	{
		WriteError("缺少关键字",token.iPosition);
		return false;
	}

	if(token.dProperty=='c' || token.dProperty=='f' ||token.dProperty=='b')//C->空
	{//没有变量声明
		return true;
	}
	else if(token.dProperty=='v') //C -> var G;H
	{//变量声明
		int place=-1;
		token=accidence(infile,irow,1); //指针移至Var之后
		if(!Declation(place,&num))
		{
			return false;
		}

		token=accidence(infile,irow,1); //读取;
		if(token.iType!=KEYWORD || token.dProperty!=';')
		{
			WriteError("缺少分号';'",token.iPosition);
			return false;
		}

		if(!Declation1(&num))
		{
			return false;
		}
		return true;
	}

	WriteError("无效的关键字",token.iPosition);
	return false;
}

//address为新定义的变量的起始地址
bool Declation(int iPlace,int *num)  //处理变量声明 G→id H'
{
	TOKEN token;
	int  iType=0,iTypelen=4,iDomain=0;
	token=accidence(infile,irow,1); //读取id
	if(token.iType!=DESIGNATOR)
	{
		WriteError("非法的变量声明",token.iPosition);
		return false;
	}
	if(iPlace>=0)
	{
		table.setParam(iPlace,token.dProperty);
	}
	(*num)++;
	if(!Declation2(iPlace,&iType,&iTypelen,&iDomain,num))
	{
		return false;
	}

	//更新符号表中变量的信息
	SetTokenProperty(token.dProperty,iType,iAddress,iDomain);

	//更新变量起始地址
	iAddress+=iTypelen;

//	WriteError("错误的变量声明",token.iPosition);
	return true;
}

//处理变量声明 
//address为新定义的变量的起始地址
bool Declation1(int *num)  //H
{
	TOKEN token;
	
	token=accidence(infile,irow,0);
	if(token.iType==DESIGNATOR) //H->G;H
	{	
		int place=-1;
		if(!Declation(place,num))
		{
			return false;
		}
		token=accidence(infile,irow,1); //读取;
		if(token.iType!=KEYWORD ||token.dProperty!=';')
		{
			WriteError("缺少分号';'",token.iPosition);
		}
		return Declation1(num);
	}
	else if(token.iType==KEYWORD && (token.dProperty=='b'||token.dProperty=='f'||token.dProperty=='c'))
	{ //H->空
		return true;
	}

	WriteError("错误的变量声明",token.iPosition);
	return false;
}

//处理变量声明,涉及到了数据类型和地址分配 
//type返回数据类型,INTEGER为integer,REAL为real
//address为新定义的变量的起始地址
bool Declation2(int iPlace,int *iType,int *iTypelen,int *iDomain,int *num)  //H'
{
	TOKEN token;

	token=accidence(infile,irow,1);
	if(token.iType!=KEYWORD)
	{
		WriteError("错误的变量声明",token.iPosition);
		return false;
	}

	if(token.dProperty==':') //H'->:I
	{
		if(!Type(iType,iTypelen,iDomain))
		{
			return false;
		}
		return true;
	}
	else if(token.dProperty==',')// H'→,id H'
	{
		token=accidence(infile,irow,1); //读取id
		if(token.iType!=DESIGNATOR)
		{
			WriteError("错误的变量声明",token.iPosition);
			return false;
		}

		if(iPlace>=0)
		{
			table.setParam(iPlace,token.dProperty);
		}
		(*num)++;
		if(!Declation2(iPlace,iType,iTypelen,iDomain,num))
		{
			return false;
		}

		//更新符号表中变量信息
		SetTokenProperty(token.dProperty,*iType,iAddress,*iDomain);
		//更新变量起始地址
		iAddress+=*iTypelen;
		return true;
	}

	WriteError("错误的变量声明",token.iPosition);
	return false;
}

bool Type(int *iType,int *iTypelen,int *iDomain) //获取类型 I
{
	TOKEN token;
	unsigned int start,end;  //数组定义的起始
	token=accidence(infile,irow,0);
	if(token.iType!=KEYWORD)
	{
		WriteError("错误的变量声明",token.iPosition);
		return false;
	}

	if(token.dProperty=='a')//I→array [ digits .. digits ] of  J
	{
		token=accidence(infile,irow,1); //移动指针至array以后

		token=accidence(infile,irow,1); //读取[
		if(token.iType!=KEYWORD ||token.dProperty!='[')
		{
			WriteError("数组类型定义错误",token.iPosition);
			return false;
		}

		token=accidence(infile,irow,1); //digits
		if(token.iType!=NUM)
		{
			WriteError("数组类型定义错误",token.iPosition);
			return false;
		}
		start=token.dProperty;

		token=accidence(infile,irow,1);
		if(token.iType!=KEYWORD ||token.dProperty!='.')//..
		{
			WriteError("数组类型定义错误",token.iPosition);
			return false;
		}

		token=accidence(infile,irow,1); //digits
		if(token.iType!=NUM)
		{
			WriteError("数组类型定义错误",token.iPosition);
			return false;
		}
		if(token.dProperty<start)
		{
			WriteError("数组上界小于下界",token.iPosition);
		}
		end=token.dProperty;

		token=accidence(infile,irow,1);
		if(token.iType!=KEYWORD ||token.dProperty!=']')//]
		{
			WriteError("数组类型定义错误",token.iPosition);
			return false;
		}

		token=accidence(infile,irow,1);
		if(token.iType!=KEYWORD ||token.dProperty!='o')//of
		{
			WriteError("数组类型定义错误",token.iPosition);
			return false;
		}
		if(!Type1(iType,iTypelen,iDomain))
		{
			return false;
		}

		*iType+=2; //转换为数组类型
		*iTypelen=(*iTypelen)*(end-start+1);
		*iDomain=start;  //数组类型的维数保存下界

		return true;
	}
	else if(token.dProperty=='r' ||token.dProperty=='n')//I→ J
	{
		if(!Type1(iType,iTypelen,iDomain))
		{
			return false;
		}
		return true;
	}

	WriteError("非法的数据类型",token.iPosition);
	return false;
}

bool Type1(int *iType,int *iTypelen,int *iDomain) //获取类型 J
{
	TOKEN token;
	token=accidence(infile,irow,1);
	if(token.iType!=KEYWORD)
	{
		WriteError("非法的数据类型",token.iPosition);
		return false;
	}
	
	if(token.dProperty=='n')
	{
		*iType=INTEGER;
		*iTypelen=INTWIDTH;
		*iDomain=0;
		return true;
	}
	if(token.dProperty=='r')
	{
		*iType=REAL;
		*iTypelen=REALWIDTH;
		*iDomain=0;
		return true;
	}

	WriteError("非法的数据类型",token.iPosition);
	return false;
}

bool SubprogramDeclarations() //子程序声明 D
{
	TOKEN token;

	token=accidence(infile,irow,0);
	if(token.iType!=KEYWORD)
	{
		WriteError("缺少关键字",token.iPosition);
		return false;
	}

	if(token.dProperty=='b') //D->空
	{
		return true;
	}
	else if(token.dProperty=='f' ||token.dProperty=='c')//D →K ;D
	{
		if(!SubprogramDeclaration())
		{
			return false;
		}

		token=accidence(infile,irow,1);
		if(token.iType!=KEYWORD ||token.dProperty!=';')
		{
			WriteError("缺少分号",token.iPosition);
			return false;
		}

		return SubprogramDeclarations();
	}

	WriteError("错误的关键字",token.iPosition);
	return false;
}

bool SubprogramDeclaration()//子程序声明K
{
	char temp[4096]={0};
	char buffer[100]={0};
	int place;
	if(!SubprogramHead(&place))
	{
		return false;
	}
	
	sprintf(buffer,"proc %d\r\n",place);
	iCodeLine++;
	if(!Declations())
	{
		return false;
	}
	if(!CompoundStatement(temp))
	{
		return false;
	}

	WriteCode(buffer);
	WriteCode(temp);
	sprintf(buffer,"endp %d\r\n",place);
	WriteCode(buffer);
	iCodeLine+=1;
	return true;
}

bool SubprogramHead(int *iPlace)//L
{
	TOKEN token;
	int num=0;
	int iType,iTypelen,iDomain;

	token=accidence(infile,irow,1);
	if(token.iType==KEYWORD)
	{
		if(token.dProperty=='f') //L->function  id  M  :  J ;
		{

			token=accidence(infile,irow,1);
			if(token.iType!=DESIGNATOR)
			{
				WriteError("缺少函数名",token.iPosition);
				return false;
			}
			if(!Arguments(token.dProperty,&num))
			{
				return false;
			}
			
			*iPlace=token.dProperty;
			token=accidence(infile,irow,1);
			if(token.iType!=KEYWORD ||token.dProperty!=':')
			{
				WriteError("错误的函数声明",token.iPosition);
				return false;
			}
			if(!Type(&iType,&iTypelen,&iDomain))
			{
				return false; 
			}
			SetTokenProperty(*iPlace,iType,0,num);

			token=accidence(infile,irow,1);
			if(token.iType!=KEYWORD ||token.dProperty!=';')
			{
				WriteError("缺少分号",token.iPosition);
				//return false;
			}
			return true;
		}
		else if(token.dProperty=='c') //L->procedure  id  M ;
		{
			token=accidence(infile,irow,1);
			if(token.iType!=DESIGNATOR)
			{
				WriteError("缺少过程名",token.iPosition);
				return false;
			}
			if(!Arguments(token.dProperty,&num))
			{
				return false;
			}
			
			*iPlace=token.dProperty;
			token=accidence(infile,irow,1);
			if(token.iType!=KEYWORD ||token.dProperty!=';')
			{
				WriteError("缺少分号",token.iPosition);
			//	return false;
			}
			SetTokenProperty(*iPlace,PROC,0,num);
			return true;
		}
	}

	WriteError("缺少函数或过程声明关键字",token.iPosition);
	return false;
}

bool Arguments(int iPlace,int *num)//M
{
	TOKEN token;
	
	token=accidence(infile,irow,0);
	if(token.iType==KEYWORD) 
	{
		token=accidence(infile,irow,1);
		if(token.dProperty=='(')//M->(GG')
		{
			if(!Declation(iPlace,num))
			{
				return false;
			}
			if(!Arguments1(iPlace,num))
			{
				return false;
			}
			token=accidence(infile,irow,1);
			if(token.iType!=KEYWORD ||token.dProperty!=')')
			{
				WriteError("错误的参数列表",token.iPosition);
				return false;
			}
			return true;
		}
	}
	WriteError("错误的参数列表",token.iPosition);
	return false;

}

bool Arguments1(int iPlace,int *num)//G' 
{
	TOKEN token;

	token=accidence(infile,irow,0);
	if(token.iType==KEYWORD) //G->空
	{
		if(token.dProperty==')')
		{
			return true;
		}
		else if(token.dProperty==';')
		{
			token=accidence(infile,irow,1);

			if(!Declation(iPlace,num))
			{
				return false;
			}
			if(!Arguments1(iPlace,num))
			{
				return false;
			}
			return true;
		}
	}

	return true;

}

bool CompoundStatement(char* buffer)   //复合语句E

⌨️ 快捷键说明

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