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

📄 parse.cpp

📁 该程序是一个MiniPascal语言的编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				if(lookahead==EOF)
				{
					error(32,line);
					cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
					exit(0);
				}
	}

	}
}
//<if语句>:
void if_sent(){//<if语句> -> if<表达式>then <语句)[eIse <语句>]
	int vartype;
	int oldp1,oldp2,newp,offs;
	streampos VarPt1,VarPt2,temp;
	match(If);
	int lineno=LINE;
	express(vartype);//<表达式> vartype获得变量类型
	if(vartype!=Boolean){
		error(6,lineno);
	//	return;
	}
	match(Then);
    oldp1=pfollow;//
//	outfile<<"dox";
	outfile<<5<<' ';
	VarPt1=outfile.tellp();
	
	pfollow+=2;
	outfile<<"                    "<<endl;
	sentence();//<语句>
	if(lookahead==Else){
		match(Else);
		oldp2=pfollow;
//		outfile<<"gotox";
		outfile<<12<<' ';
		VarPt2=outfile.tellp();
		
		pfollow+=2;
		outfile<<"                    "<<endl;
		//backpatch
		newp=pfollow;
		offs=newp-oldp1;
		temp=outfile.tellp();
		outfile.seekp(VarPt1);
//		outfile<<"("<<offs<<");";
		outfile<<offs;
		outfile.seekp(temp);
		sentence();//<语句2>
		newp=pfollow;
		offs=newp-oldp2;
		temp=outfile.tellp();
		outfile.seekp(VarPt2);
		outfile<<offs;
//		outfile<<"("<<offs<<");";
		outfile.seekp(temp);
	}
	else{
        newp=pfollow;
		offs=newp-oldp1;
		temp=outfile.tellp();
		outfile.seekp(VarPt1);
		outfile<<offs;
//		outfile<<"("<<offs<<");";
		outfile.seekp(temp);
	}
}
//<while语句>:
void while_sent(){//<while<语句> -> while<表达式> do<语句>
	int vartype;
	int oldp1,oldp2,offs;
	streampos VarPt,temp;
	match(While);//
	int lineno=LINE;
    oldp1=pfollow;
	express(vartype);
	if(vartype!=Boolean){
		error(6,lineno);
	}
	match(Do);   //
	oldp2=pfollow;
	outfile<<5<<' ';//	outfile<<"dox";
	pfollow+=2;
	VarPt=outfile.tellp();//
	outfile<<"                    "<<endl;
	sentence();//<语句2>
	offs=oldp1-pfollow;//
	outfile<<12<<' '<<offs<<endl;//	outfile<<"gotox("<<offs<<");"<<endl;
	pfollow+=2;
	offs=pfollow-oldp2;
	temp=outfile.tellp();
	outfile.seekp(VarPt);
	outfile<<offs;//backpatch "dox"
	outfile.seekp(temp);
}

//<复合语句>:

void com_sent(){//<复合语句> -> begin <语句>{;<语句>}end
	match(Begin);
	sentence();
	while(lookahead==semicolon){//一个或多个
		match(semicolon);
		sentence();
	}
	match(End);
}


//------------------------- read  -------------------------
//------------------------- read  -------------------------
//<读变量>
void readvar(){
	int vartype;
	int lineno=LINE;
	varaccess(vartype,1);
	if(vartype==Boolean){
		error(7,lineno);//不能读入到bool类型变量
	//	return;
	}
	outfile<<26<<endl;//	outfile<<"readx;"<<endl;
	pfollow++;
}
//------------------------- write  -------------------------
//<写变量>
void writevar(){
	int vartype;
	express(vartype);
	if(vartype==Boolean)
		outfile<<32<<endl;	//	outfile<<"writebooleanx;"<<endl;
	else 
		outfile<<31<<endl;		//	outfile<<"writeintx;"<<endl;
	pfollow++;

}

//<表达式>:
void express(int& VarType){	//<表达式>-> <简单表达式>[<关系算符><简单表达式>]
	int opcode;
	int vartype1,vartype2;
	simple_expr(vartype1);
	VarType=vartype1;//2:bool;3:int 
	int lineno=LINE;
	if(isrelational_op(lookahead))
	{
			opcode=lookahead;
			match(lookahead);//向前走一步
	    	simple_expr(vartype2);//
			if(vartype1!=vartype2)
			{
				error(16,lineno);//
				return;
			}
	    	switch(opcode)
			{
	    	case relop_LT://<
//				outfile<<"less;"<<endl;
				outfile<<14<<endl;
				break;
			case relop_LE://<=
			//	outfile<<"notgreater;"<<endl;
				outfile<<19<<endl;
				break;
			case relop_EQ://=
//				outfile<<"equal;"<<endl;
				outfile<<9<<endl;
				break;
			case relop_NE://<>
//				outfile<<"notequal;"<<endl;
				outfile<<18<<endl;
				break;
			case relop_GT://>
//				outfile<<"greater;"<<endl;
				outfile<<11<<endl;
				break;
			case relop_GE://>=
//				outfile<<"notless;"<<endl;
				outfile<<20<<endl;
			}//switch
			pfollow++;
			VarType=Boolean;
		}//if
}

//<简单表达式>:

void simple_expr(int& VarType){//<简单表达式> -> [+|-]<项>{<加法算符><项>}
	int not=0,opcode;
	int vartype1,vartype2;
	if(lookahead==plus_op){//+
        not=-1;
		match(plus_op);
	}
	if(lookahead==minus_op)
	{
		not=1;
		match(minus_op);}
		
	
	/*
	if(lookahead==minus_op){//-
		not=1;
		//	outfile<<"constant(0);"<<endl;
    	outfile<<3<<' '<<0<<endl;
    	pfollow+=2;
		match(minus_op);
	}*/
	
	int lineno=LINE;
	term(vartype1);
	if(not==1)
	{
		outfile<<15<<endl;//outfile<<minus()<<endl;
		pfollow++;
		
	}
	//项
//	if(not==1){//negtive:取反
//	outfile<<"subtract;"<<endl;
  //  	outfile<<27<<endl;
    //	pfollow++;
	//}
	VarType=vartype1;//如果出错,就按照第一个变量的类型继续
	if(vartype1==Boolean){//bool
		if(not!=0){
			error(11,lineno);
		//	return;
		}
		while(lookahead==Or){//可能有多个
			match(Or);
			term(vartype2);//<项>
			if(vartype2!=Boolean){
				error(13,lineno);//or只能对bool类型变量进行运算
			//	return;
			}
//			outfile<<"orx;"<<endl;
			outfile<<22<<endl;
			pfollow++;
		}
		if((lookahead==plus_op)||(lookahead==minus_op)){
			error(12,LINE);
			match(lookahead);
			express(vartype2);
		}
		return;
	}
	//integer
    while((lookahead==plus_op)||(lookahead==minus_op)){//<加法算符> ->+|-|or
	    opcode=lookahead;
		match(lookahead);
		term(vartype2);
		if(vartype2!=Integer){
			error(12,lineno);//加法算符两边必须都为整型
		//	return;
		}
	//	VarType=Integer;
		switch(opcode){
		case minus_op://-
//			outfile<<"subtract;"<<endl;
			outfile<<27<<endl;
			break;
		case plus_op://+
//            outfile<<"add;"<<endl;
			outfile<<0<<endl;
		}
		
		pfollow++;
	}//while
	if(lookahead==Or){
		error(13,LINE);
		match(Or);
		express(vartype2);
	}
}
//<项>:
void term(int& VarType){// <项> -> <因子>{<乘法算符><因子>}
	int opcode;
	int vartype1,vartype2;
	int lineno=LINE;
	gene(vartype1);//因子
	VarType=vartype1;
	if(vartype1==2){//bool , const of bool
		while(lookahead==And){
			match(And);
			gene(vartype2);//<因子>
			if(vartype2!=2){
				error(13,lineno);//bool运算不匹配
		//		return;
			}
//			outfile<<"andx;"<<endl;
			outfile<<1<<endl;
			pfollow++;
		}
		VarType=Boolean;
     	if((lookahead==multi_op)||(lookahead==Div)||(lookahead==Mod))
		{// <乘法算将> -> *|div|mod
			error(14,LINE);
			match(lookahead);
			express(vartype2);
		}
		return;
	}
	while((lookahead==multi_op)||(lookahead==Div)||(lookahead==Mod))
	{// <乘法算将> -> *|div|mod|and
		opcode=lookahead;
		match(lookahead);
		gene(vartype2);
		if(vartype2!=vartype1){
			error(14,lineno);//乘法算符两边应该类型相等
	//		return;
		}
		switch(opcode){
		case multi_op:
//			outfile<<"multiply;"<<endl;
			outfile<<17<<endl;
			break;
		case Div:
			outfile<<4<<endl;
//            outfile<<"divide;"<<endl;
			break;
		case Mod:
		//	outfile<<"modulo;"<<endl;
			outfile<<16<<endl;
		}
		VarType=vartype1;
		
		pfollow++;
	}//while
	if(lookahead==And){
		error(13,LINE);
		match(And);
        express(vartype2);
	}
}
//<因子>:
void gene(int& VarType){ // <因子> -> <常数>|<变量访问>|(<表达式>)|not<因子>
	int consttype;
	int lineno;
    if(lookahead==Not){
		match(Not);
		lineno=LINE;
		gene(VarType);//<因子>
		if(VarType!=2){
			error(13,lineno);//not应该针对bool对象运算
			return;
		}
//		outfile<<"notx;"<<endl;
		outfile<<21<<endl;
		pfollow++;
	}
	else if(lookahead==lpar){
		match(lpar);
		express(VarType);//<表达式>
		match(rpar);
	}
	else if(isconst(consttype)){//<常数>
		//push ConstVal:the Const or Number to Stack
		VarType=consttype+2;//1:(int) const
//		outfile<<"constant("<<ConstVal<<");"<<endl;
		outfile<<3<<' '<<ConstVal<<endl;
		
		pfollow+=2;
	}
	else{
		varaccess(VarType,1);//1:不允许访问新类型

	//	outfile<<"value("<<typelist[VarType].bandwidth<<");"<<endl;
//		outfile<<"value(1);"<<endl;
		outfile<<28<<' '<<1<<endl;
		pfollow+=2;
	}
}
//<变量访问>:
void varaccess(int& VisitType,int property)
{//取变量于栈顶操作在search中完成,把匹配的变量名都match
	//property=0:只访问新类型;1:只访问bool,integer;
	int level,offs,mark,type;
	var_list* var=new var_list;
	proc_list* proc=new proc_list;
	type_list* mother=new type_list;
	field_table* child=new field_table;
	//检查token类型 0:procedure,1:变量
	if(search(token,proc,var)!=1){//不是变量
		error(8,LINE);
		match(lookahead);
		return;
	}
	int lineno=LINE;
	match(lookahead);//

	VisitType=var->type;
	level=(cur_proc->level)-(proc->level);
	offs=var->offset;
	//if offs<0:parameter
	type=var->type;
    mark=type;
	//property=1:不允许新类型

	if(type>3){//新类型
		mother=&typelist[type];//
		type=typelist[mark].type;//访问变量的类型:const\int\bool\new type
	//	VisitType=type;
		if((offs<0)&&(var->ConstVal==2))//parameter,引用
			outfile<<30<<' '<<level<<' '<<offs<<endl;//outfile<<"Varparam("<<level<<","<<offs<<");"<<endl;
		else
			outfile<<29<<' '<<level<<' '<<offs<<endl;	//outfile<<"Variable("<<level<<","<<offs<<");"<<endl;//
     	pfollow+=3;
		
	}

    while(1){
	switch(type){
	case Const://type=1
		error(15,lineno);//非法使用常量
		return;
	case Integer://type=2,3
	case Boolean:
		if(property==0){//只能访问新类型
			error(16,lineno);
			return;
		}
		if((offs<0)&&(var->ConstVal==2))//parameter,引用
			outfile<<30<<' '<<level<<' '<<offs<<endl;
//			outfile<<"Varparam("<<level<<","<<offs<<");"<<endl;
		else
			outfile<<29<<' '<<level<<' '<<offs<<endl;
//	    	outfile<<"Variable("<<level<<","<<offs<<");"<<endl;
		
		pfollow+=3;
		return;
    case Array:
		if(lookahead!=lbracket){
			if(property==1){//错误访问新类型
	        	error(16,lineno);
			}
			return;//变量访问完毕!
		}
		match(lbracket);//数组访问
        express(VisitType);//把value push
				//然后需要做value*数组元素的字节长度,求出offs
				//......
		if(VisitType==Boolean){//下标不能为boolean类型
			error(22,LINE);
		//	return;
		}
//		outfile<<"Index("<<typelist[mark].lower<<","<<typelist[mark].upper<<","<<typelist[mark].bandwidthOfelement<<","<<LINE<<");"<<endl;
		outfile<<13<<' '<<typelist[mark].lower<<' '<<typelist[mark].upper<<' '<<typelist[mark].bandwidthOfelement<<' '<<LINE<<endl;
		pfollow+=5;
		match(rbracket);
		VisitType=typelist[mark].typeofelement;//
		if((VisitType>=1)&&(VisitType<=3)){//在循环中,不会再进入到前面的分支中。在此处已经返回
			return;
		}
		mark=VisitType;//int,bool,or newtype在typelist中的序号,在这目标,visittype&mark一直相等
		type=typelist[mark].type;//元素的类型
		mother=&typelist[mark];//下一个元素所在的表项
		break;
	case Record:
		if(lookahead!=dot){
			if((property==1)&&(VisitType>3)){//错误访问新类型
	        	error(16,lineno);
	        	return;
			}
		    return;
		}
		match(dot);
		if(!searchfield(token,mother,child)){//type_list* mother
			error(17,lineno);
			match(id);
			return;
		}
		match(id);
//		outfile<<"field("<<child->offset<<");"<<endl;
		outfile<<10<<' '<<child->offset<<endl;
		pfollow+=2;
		VisitType=child->type;//访问变量的类型
		if((VisitType>=1)&&(VisitType<=3)){
			return;
		}
		mark=child->type;
		type=typelist[mark].type;//元素的类型
		mother=&typelist[mark];  //下一个元素所在的表项
		break;
	default:
		error(-1,LINE);//undefined error
	}//switch
	}//while
}



⌨️ 快捷键说明

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