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

📄 parse.cpp

📁 该程序是一个MiniPascal语言的编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	lineno[0]=LINE;
    strcpy(varname[Varcount++],token);//假设正确
	if(lookahead==End)
	{//记录类型的最后一条语句不能以';'结束
		error(29,LINE-1);//注意此时end已经在下一行了
		return;
	}
	match(id);
	while(lookahead==comma)
	{//一个或多个
		match(comma);
		lineno[Varcount]=LINE;
		strcpy(varname[Varcount++],token);//假设正确
		match(id);
	}
	match(colon);
	VarType=searchtype(token);//判断类型
	if(VarType<0)
		error(5,LINE);
	lookahead=nexttoken();//需要加吗?

	//match(lookahead);
	for(i=0;i<Varcount;i++)
	{
		if(field_rename(varname[i]))
		{//重名
			strcpy(errortype,varname[i]);
			error(0,lineno[i]);
			break;
		}
		//在域表和typelist中添加新表项
		strcpy(field->name,varname[i]);
		field->type=VarType;
		typelist[typecount].bandwidth+=typelist[VarType].bandwidth;
		field->next=new field_table;
		field=field->next;
		field->offset=typelist[typecount].bandwidth;
	}
		//match(lookahead);
}
//************************************************************************************************
//<变量定义部分>:
void var_define(){//<变量定义部份> -> var<变量定义>{<变量定义>}
	match(Var);
	do{//一个或多个
		vardef();
	}while(lookahead==id);
}
//<变量定义>:
void vardef()
{//<变量定义> -> <变量组>;
	varlist(0);//varlist:变量访问;0:变量定义,1:传值,2:引用
	match(semicolon);
}

//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//                             变量组的语义分析函数
//-------------------------------------------------------------------------------------
//-----------------------
void varlist(int property)
{  //<变量组> -> <变量名>{,<变量名>}:<类型名>
	//property=0:变量定义1:参数定义(值传)2:引用
	int VarType;//类型编号
	int Varcount=0,i;
	char varname[SIZE][SIZE];//变量名数组
	int lineno[SIZE];
	lineno[Varcount]=LINE;
    strcpy(varname[Varcount++],token);//假设正确
	match(id);
	while(lookahead==comma)
	{//一个或多个
		match(comma);
		lineno[Varcount]=LINE;
        strcpy(varname[Varcount++],token);//假设正确
	    match(id);	
	}
	match(colon);
	VarType=searchtype(token);//bool.int.new.unknown(-1)
    if(VarType<=0)
	{
		error(5,LINE);//类型错误
		match(lookahead);
		return;
	}
    for(i=0;i<Varcount;i++)
	{
		if(var_rename(varname[i]))
		{//若同一过程变量同名
            strcpy(errortype,varname[i]);
			error(0,lineno[i]);
			break;
		}
		//在变量表中添加新表项
		strcpy(cur_varlist->name,varname[i]);
		cur_varlist->type=VarType;
		switch(property)
		{
			case 1://传值
				cur_proc->numofparam++;//参数个数++
				cur_varlist->offset=off;
				off=off-typelist[VarType].bandwidth;//off=0;initial
				cur_varlist->ConstVal=1;
				break;		
			case 2://引用
				cur_proc->numofparam++;//参数个数++
				cur_varlist->offset=off;
				off--;
				cur_varlist->ConstVal=2;
				break;
			default://=0变量定义
        		cur_varlist->offset=off;
	    		off=off+typelist[VarType].bandwidth;
			}
		cur_varlist->next=new var_list;
		cur_varlist=cur_varlist->next;
	}
	match(lookahead);
}
//<过程定义>:
void proc_define()
{//	<过程定义> -> Procedure <过程名><过程块>;& <过程块> -> [(<形参表>)];<块体>
	match(Procedure);    

	int lev=cur_proc->level;
	int numofchild=cur_proc->numofchild;//old
	cur_proc->numofchild++;//子过程数++
	cur_proc->child[numofchild]=new proc_list;
	proc_list* tmp=new proc_list;
	tmp=cur_proc;
    cur_proc=cur_proc->child[numofchild];
	cur_proc->father=tmp;//
	
	//在过程表中添加新表项
	for(int i=0;i<SIZE;i++)
		cur_proc->NewType[i]=-1;
	cur_proc->numofnewtype=0;
	cur_proc->numofchild=0;
	cur_proc->ParamLength=0;
	cur_proc->numofparam=0;
       cur_proc->VarLength=0;
	cur_proc->next=new var_list;
	cur_proc->next=cur_varlist;
	cur_proc->level=lev+1;
	off=3;

	if(proc_rename(token))
	{//重名
		strcpy(errortype,token);
		error(0,LINE);
	}
//------------------------目标代码生成------------------------------------
	streampos VarPt,temp;
	int offs,LineNo,oldp,newp;
	cur_proc->offset=pfollow;  //address of procedure starting
//	outfile<<"ProcedureX";
	outfile<<24<<' ';
	//keep
    LineNo=LINE;
    VarPt=outfile.tellp();
	oldp=pfollow;//cur_proc->offset
	//refresh
	outfile<<"                         "<<endl;	
	pfollow+=5;
	strcpy(cur_proc->name,token);//
    match(id);
	if(lookahead==lpar)
	{
		match(lpar);
		fparam_list();//<形参表>
		if(lookahead!=rpar)
		{
			error(23,LINE);
			exit(0);//这里连续报错好像有点困难

		}
		match(rpar);
	
	}
	match(semicolon);
	block(newp);//<块体>
	//-----------------------------目标代码生成---------------------------------------------//
	outfile<<8<<' '<<cur_proc->ParamLength<<endl;//end of proc

	
	pfollow+=2;
    offs=newp-oldp;
    temp=outfile.tellp();
	outfile.seekp(VarPt);
	outfile<<cur_proc->VarLength<<' '<<cur_proc->VarLength*3<<' '<<offs<<' '<<LineNo;
    outfile.seekp(temp);
	match(semicolon);
	cur_proc=cur_proc->father;//回到父过程
}
//<形参表>:
void fparam_list()
{//<形参表> -> <参数定义>{;<参数定义>}
	//match(lpar);//在proc_define()中并没有match'('
	off=0;//方便形式参数的offset
	param_define();//<参数定义>
    while(lookahead==semicolon)
	{//一个或多个
		match(semicolon);//此处错误处理有些困难
		param_define();
	}
	/*if(lookahead!=rpar)
	{
		error(23,LINE);
		while(lookahead!=rpar)
			match(lookahead);
	}*/
	//match(rpar);

	/*if(lookahead!=rpar)
	{
		if(lookahead==10||lookahead==id)
			error(23,LINE);
		//match(lookahead);
		//while(lookahead!=rpar)
		//	match(lookahead);
		//return;
		else error(28,LINE);
		//lookahead=nexttoken();
	}
	match(rpar);*/
	cur_proc->ParamLength=-off;//
	off=3;//
	var_list* temp=new var_list;
	temp=cur_proc->next;
	for(int i=0;i<cur_proc->numofparam;i++,temp=temp->next)
		temp->offset=-(cur_proc->ParamLength)-(temp->offset);
}
//<参数定义>:
void param_define(){  //<参数定义>
	int ifvalue=1;
	if(lookahead==Var)
	{//以var开头,传引用
		ifvalue=2;
		match(Var);
	}
    varlist(ifvalue);//变量组0:变量定义1:参数定义(值传)2:引用
}
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//
//                             语句
//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
void sentence()
{//<语句> -> <赋值语句>|<过程语句>|<if语句>|<while语句>|<复合语句>|emPty
	switch(lookahead){
	case semicolon:
		break;
	case If:    //<if语句> -> if<表达式>then <语句)[eIse <语句>]
		if_sent();break;
	case While: //<while语句> -> while<表达式> do<语句>
        while_sent();break;
	case Begin:com_sent();break;//<复合语句> -> begin <语句>{;<语句>}end
	case End:break;         //empty
	case Read://<read语句>-〉read (<读变量>{,<读变量>})
		match(Read);
		match(lpar);
		readvar();
		while(lookahead==comma)
		{
			match(comma);
			readvar();//<读变量>
		}
		match(rpar);
		break;
	case Write://<write语句>-> write(<写变量>{,<写变量>})
		match(Write);
		match(lpar);
        writevar();//<写变量>
		while(lookahead==comma){
			match(comma);
			writevar();
		}
		match(rpar);
		break;
    default:
		switch(search(token,proc,var)){
		case 0://过程语句
			proc_sent();break;
		case 1://赋值语句
            assign_sent();break;
		default://找不到
			error(8,LINE);
            while((lookahead!=semicolon)&&(lookahead!=End))
				match(lookahead);
		}
	}//switch
}



//    赋值语句
//
/*varaccess(int&VarType1,int)将得到[:=]左边变量的类型;
再执行express(int&VarType2)得到右边变量的类型;
将VarType1,VarType2相比较,相等则赋值成功,
否则类型不符,错误。
*/
void assign_sent()
{//<赋值语句>-> <变量访问>:=<表达式>
	//来到这个分支前,已经在search里做出判断是变量.
	int VarType1,VarType2;
	varaccess(VarType1,-1);
	int lineno=LINE;
	match(assign_op);
	if(VarType1>3){
		varaccess(VarType2,0);//只允许访问新类型
		if(VarType1!=VarType2){
			rightvar=VarType2;
			leftvar=VarType1;
			error(9,lineno);
			return;
		}
//			outfile<<"Value("<<typelist[VarType1].bandwidth<<");"<<endl;
			outfile<<28<<' '<<typelist[VarType1].bandwidth<<endl;
			pfollow+=2;
//			outfile<<"assign_sent("<<typelist[VarType1].bandwidth<<");"<<endl;
			outfile<<2<<' '<<typelist[VarType1].bandwidth<<endl;
			pfollow+=2;
			return;
	}
	//int/bool
	express(VarType2);
	if(VarType1!=VarType2){
		rightvar=VarType2;
		leftvar=VarType1;
		error(9,lineno);
		return;
	}
//	outfile<<"assign_sent(1);"<<endl;
	outfile<<2<<' '<<1<<endl;
	pfollow+=2;
}
//<过程语句>:
void proc_sent(){//<过程语句> -> <过程名>[(实参表)]
	//关于过程调用的层数问题:level有没有限制(如书中pascal)
	int level,offs;
	match(id);
	if(proc->numofparam!=0){
		match(lpar);
		rparam_list();//
		match(rpar);
	}
	//if 0
	else{
		if(lookahead==lpar){
			error(10,LINE);
			while((lookahead!=semicolon)&&(lookahead!=End))
				match(lookahead);
		}
	}
	level=cur_proc->level-proc->level+1;
	offs=proc->offset-pfollow;
//	outfile<<"proccall("<<level<<","<<offs<<");"<<endl;
	outfile<<23<<' '<<level<<' '<<offs<<endl;
	pfollow+=3;
}
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//
//                             实参表
//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
/*此时全局变量proc保存了被调用的过程的节点。
	int numofparam=proc->numofparam;
	得到该过程的形参个数
	param=proc->next;
	得到该过程的第一个形参的指针
	for(j=0;j<numofparam;j++,param=param->next){//循环判断
	if(param->ConstVal==1){// :传值
        如果param是新类型,则varaccess()返回实际参数的类型
     	比较是否相等;
    	如果不是,则express()返回实际参数的类型,
    	比较是否相等;
	}
	if(param->ConstVal==2){//:传引用
     	varaccess()返回实际参数的类型,
     	比较是否相等
	}
	}

*/
void rparam_list(){//<实参表> -> <实参>{,<实参>}
	int i=1,vartype;
	var_list* param=new var_list;
	proc_list* pro=new proc_list;
	var_list* var=new var_list;
	param=proc->next;//当前过程定义的变量表
	int numofparam=proc->numofparam;
    int j;
	int lineno;
	for(j=0;j<numofparam;j++,param=param->next){
	/*	if(j>numofparam){
			error(10,LINE);
			do{
				if(lookahead==lpar)numoflpar++;
				if(lookahead==rpar)numoflpar--;
				if(numoflpar==0){
					if(lookahead!=comma)
						match(lookahead);
				}
				else{
					if((lookahead!=comma)&&(lookahead!=rpar))
						match(lookahead);

				}
			}while(numoflpar>=0);

		}*/
		lineno=LINE;
		parameterth=j+1;//第j+1个
		if(param->ConstVal==1)
		{//value
			if(param->type>3)
			{//new type
				varaccess(vartype,0);//0:只访问新变量,vartype获得变量类型
				if(vartype!=param->type){
					rightvar=vartype;
					leftvar=param->type;
					error(9,lineno);//the (j+1)'th error real parameters
	//				return;
				}
//				outfile<<"value("<<typelist[vartype].bandwidth<<");"<<endl;
				outfile<<28<<' '<<typelist[vartype].bandwidth<<endl;
				pfollow+=2;
			}
			else{//不是新类型,bool/int
				express(vartype);//获得变量类型
				if(vartype!=param->type){
					rightvar=vartype;
					leftvar=param->type;
					error(9,lineno);//
				//	return;
				}
			}
		}
		else if(param->ConstVal==2){//address,only var's visit
			if((search(token,pro,var)!=1)||(var->type==Const)){//不是变量,或者是常数
				error(24,LINE);
				match(lookahead);
			}
			else{
		    	varaccess(vartype,-1);//-1:任意类型
                if(vartype!=param->type){
			    	rightvar=vartype;
			    	leftvar=param->type;
			    	error(9,lineno);//parameters error!
			     //	return;
				}
			}
		}
		if(lookahead==comma)match(comma);
		else break;
	}//for
    if(j<numofparam-1){//not enough parameters!
		error(10,LINE);
		//------------------------------连续报错----------------------------
		int line1=LINE;
		while(lookahead!=rpar)
		{
			match(lookahead);//
			if(lookahead==Begin)
				{
					error(32,line1);
					return;
				}
				if(lookahead==EOF)
				{
					error(32,line1);
					cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
					exit(0);
				}
	}

		//return;
	}
	if(j>numofparam-1){//more than enough
		error(34,LINE);
		int line=LINE;
		while(lookahead!=rpar)
		{
			match(lookahead);//
			if(lookahead==Begin)
				{
					error(32,line);
					return;
				}

⌨️ 快捷键说明

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