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

📄 statement.cpp

📁 用VC写的扩充的pl0文法编译器
💻 CPP
字号:

#include "Global.h"

using namespace std;

void PL0::Factor(SYMSET fsys,ITEM &x,int lev)
{
	int i;
	x.typ=notyp;
	x.ref=0;
	Test(facbegsys,fsys,"因子必须以标志符,常量或'('开始");
	while(facbegsys.find(sym)!=facbegsys.end())
	{
		if(sym==IDENT)
		{
			i=Position(id,lev);
			Getsym();
			if(i==0)
				Error("变量不存在或不可引用",linecount);
			switch(table[i].kind)
			{
			case CONSTANT:
				x.typ=table[i].type;
				x.ref=0;
				//if(x.typ==reals)
				Gen(Lit,(float)(lev-table[i].level),(float)table[i].val);
				break;
			case VARIABLE:
				x.typ=table[i].type;
				x.ref=0;
				Gen(Lod,lev-table[i].level,table[i].adr);
				break;
			case PROCEDURE:
				Error("过程名不能成为因子",linecount);
				break;
			case FUNCTION:
				x.typ=table[i].type;
				ret=true;
				Call(fsys,i,lev);
			}
		}
		else
			if(sym==INUM||sym==RNUM||sym==CNUM)
			{
				if(sym==RNUM)
				{
					x.typ=reals;
					Gen(Lit,0,num);
					Getsym();
				}
				else
				{
					x.typ=ints;
					Gen(Lit,0,num);
					Getsym();
				}
				x.ref=0;
			}
			else 
				if(sym==LPAREN)
				{
					Getsym();
					SYMSET temp;
		            temp=fsys;
					temp.insert(RPAREN);
					Expression(temp,x,lev);
					if(sym==RPAREN)
						Getsym();
					else
						Error("缺少右括号",linecount);
				}
				Test(fsys,facbegsys,"因子后不可为此符号");
	}
}

void PL0::Call(SYMSET fsys,int i,int lev)
{
	ITEM x;
	x.typ=notyp;
	x.ref=-1;
	int lastp,cp,k;
	lastp=btab[table[i].ref].lastpar;
	cp=i;
	
	if(sym==LPAREN)
	{
		
		do
		{
			Getsym();
			if(cp>=lastp)
				Error("实参个数与形参个数不等",linecount);
			else
			{
				cp++;
				SYMSET temp;
				temp=fsys;
				temp.insert(COMMA);
				temp.insert(COLON);
				temp.insert(RPAREN);
				Expression(temp,x,lev);
				if(x.typ<table[cp].type)
					Warning("形参实参类型不符,运算可能导致精度损失",linecount);
				Gen(Stof,0,table[cp].adr);
			}
			SYMSET temp;
			temp.insert(COMMA);
			temp.insert(RPAREN);
			Test(temp,fsys,"编译将跳一些非法符号符号");
		}while(sym==COMMA);
		//Getsym();
		if(sym==RPAREN)
			Getsym();
		else Error("缺少右括号",linecount);
	}
	Gen(Cal,0,table[i].adr);
	if(ret)
		Gen(Opr,0,16);
}

void PL0::Term(SYMSET fsys,ITEM &x,int lev)
{
	ITEM y;
	SYMBOL op;
    SYMSET temp1;
	temp1=fsys;
	temp1.insert(TIMES);
	temp1.insert(SLASH);

	Factor(temp1,x,lev);

	while(sym==TIMES||sym==SLASH)
	{
		op=sym;
		Getsym();
		//SYMSET temp2;
		//temp2=temp1;
		//temp2.insert(TIMES);
		//temp2.insert(SLASH);
		Factor(temp1,y,lev);
		if(op==TIMES)
		{
			x.typ=Resulttype(x.typ,y.typ);
			if(x.typ==reals)
				Gen(Opr,0,4);
			else
				Gen(Opr,0,6);
		}
		else
			if(op==SLASH)
			{
				x.typ=Resulttype(x.typ,y.typ);
				if(x.typ==reals)
					Gen(Opr,0,5);
				else
					Gen(Opr,0,7);
			}
	}
}

void PL0::Expression(SYMSET fsys,ITEM &x,int lev)
{
	ITEM y;
	SYMBOL op;
	SYMSET temp;
	temp=fsys;
	temp.insert(PLUS);
	temp.insert(MINUS);

	if(sym==PLUS||sym==MINUS)
	{
		op=sym;
		Getsym();
		Term(temp,x,lev);
		if(op==MINUS)
		{
			Gen(Opr,0,1);//生成一条1号操作指令:取反运算
		}
	}
	else
	{
		Term(temp,x,lev);
	}
	while(sym==PLUS||sym==MINUS)
	{
		op=sym;
		Getsym();
		Term(temp,y,lev);
		x.typ=Resulttype(x.typ,y.typ);
		
			if(op==PLUS)
			{
				if(x.typ==reals)
					Gen(Opr,0,2);
				else
					Gen(Opr,0,8);
			}
			else
			{
				if(x.typ==reals)
					Gen(Opr,0,3);
				else
					Gen(Opr,0,9);

			}
	}

}
void PL0:: Condition(SYMSET fsys,ITEM &x,int lev)
{
	ITEM y;
	SYMBOL relop;
	SYMSET temp1,temp2;
	temp1.insert(EQL),temp1.insert(NEQ),temp1.insert(LSS),temp1.insert(GTR),temp1.insert(LEQ),temp1.insert(GEQ);
	temp2=temp1;
	for(SYMSET::iterator it=fsys.begin();it!=fsys.end();it++)
		temp1.insert(*it);
	if(sym==ODDSYM)
	{
		Getsym();
		Expression(fsys,x,lev);
		Gen(Opr,0,6);
	}
	else
	{
		//Getsym();
		Expression(temp1,x,lev);
		if(temp2.find(sym)==temp2.end())
		{
			Error("应为关系运算符",linecount);
		}
		else
		{
			relop=sym;
			Getsym();
			Expression(fsys,y,lev);
			//cout<<"if语句中左边表达式类型为......."<<x.typ<<endl;
			//cout<<"if语句中右边表达式类型为......."<<y.typ<<endl;
			switch(relop)
			{
			case EQL:
				Gen(Opr,0,10);
				break;
			case NEQ:
				Gen(Opr,0,11);
				break;
			case LSS://小于等于
				Gen(Opr,0,14);
				break;
			case GEQ://大于
				Gen(Opr,0,13);
				break;
			case GTR://大于等于
				Gen(Opr,0,15);
				break;
			case LEQ://小于
				Gen(Opr,0,12);
				break;
			}
		}

	}
}
void PL0::Listcode()
{
	for(int i=0;i<cx;i++)
		cout<<i<<setw(5)<<fctmap[code[i].f]<<setw(5)<<code[i].l<<setw(5)<<code[i].a<<endl;
}

TYP PL0::Resulttype(TYP a,TYP b)
{
	if(a==chars)
	{
		return b;
	}
	if(a==ints)
	{
		if(b==reals)
			return b;
		else
			return ints;
	}
	if(a==reals)
		return a;
}
void PL0::Assignment(SYMSET fsys,int lv,int ad,int i)
{
	ITEM x,y;
	int f;
	x.typ=table[i].type;
	x.ref=table[i].ref;
	y.typ=notyp;
	y.ref=-1;
	if(sym==BECOMES)
		Getsym();
	else
	{
		Warning("应该为赋值号:':='",linecount);
		if(sym==EQL)
			Getsym();
	}
	Expression(fsys,y,lv);
	//cout<<y.typ<<"********************"<<y.ref<<endl;
	
		switch(table[i].kind)
		{
		case FUNCTION:
			Gen(Fun,0,3);
			break;
		case VARIABLE:
			{
				if(x.typ>=y.typ)
					Gen(Sto,lv-table[i].level,table[i].adr);
				else
				{
						Warning("赋值可能会导致精度丢失",linecount);
						if(y.typ==reals)
							Gen(Stoi,lv-table[i].level,table[i].adr);
						else
							Gen(Sto,lv-table[i].level,table[i].adr);
				}
			}
			break;
		}
}

void PL0::Compoundstatement(SYMSET fsys,int lev)
{
	Getsym();
	SYMSET temp;
	temp=fsys;
	temp.insert(ENDSYM);
	temp.insert(SEMICOLON);

	Statement(temp,lev);
	
	SYMSET temp1;
	temp1=statbegsys;
	temp1.insert(SEMICOLON);
	while(temp1.find(sym)!=temp1.end())
	{
		if(sym==SEMICOLON)
			Getsym();
		else
			Error("缺少分号:';'",linecount);
		
		Statement(temp,lev);
	}
	if(sym==ENDSYM)
		Getsym();
	else
		Error("缺少关键字:'end'",linecount);
}

void PL0::Statement(SYMSET fsys,int lev)
{
	int i;
	float value;
	ITEM x;
	x.typ=notyp;
	x.ref=0;
	SYMSET temp;
	temp=statbegsys;
	temp.insert(IDENT);
	if(temp.find(sym)!=temp.end())
	{
		switch(sym)
		{
		case IDENT:
			i=Position(id,lev);
			Getsym();
			if(i!=0)
			{
				switch(table[i].kind)
				{
				case CONSTANT:
					Error("应是变量,过程/函数名",linecount);
					break;
				case VARIABLE:
					//Assignment(fsys,table[i].level,table[i].adr,i);
					Assignment(fsys,lev,table[i].adr,i);
					break;
				//case PARAMETER:
					//Assignment(fsys,lev,table[i].adr,i);
					//break;
				case PROCEDURE:
					if(table[i].level!=0)
						Call(fsys,i,lev);
					else
						Error("函数名定义有错误,请检查",linecount);
					break;
				case FUNCTION:
					if(table[i].ref==DISPLAY[lev])
						Assignment(fsys,table[i].level+1,0,i);
					else
					Error("应是变量,过程/函数名",linecount);
					break;
				}
			}
			else
				Error("变量不存在或不可引用",linecount);
			break;
		case BEGINSYM:
			Compoundstatement(fsys,lev);
			break;
		case IFSYM:
			{
				int lc1,lc2;
				ITEM x;
				x.typ=notyp;
				x.ref=-1;
				SYMSET temp,temp1;
				temp=fsys;
				temp.insert(THENSYM);
				//temp.insert(DOSYM);
				Getsym();
				Condition(temp,x,lev);
				if(x.typ==notyp)
					Error("if语句中的判断表达式错误",linecount);
				if(sym==THENSYM)
					Getsym();
				else
				{	
					Error("缺少关键字:then",linecount);
				}
				lc1=cx,Gen(Jpc,0,0);
				cout<<"then语句处理前cx="<<lc1<<endl;
				temp1=fsys;
				temp1.insert(ELSESYM);
				Statement(temp1,lev);
				
				Getsym();
				//code[lc1].a=cx;
				if(sym==ELSESYM)
				{
					Getsym();
					lc2=cx;
					cout<<"else语句处理前cx="<<lc2<<endl;
					Gen(Jmp,0,0);
					code[lc1].a=cx;
					
					Statement(fsys,lev);
					
					code[lc2].a=cx;
				}
				else
					code[lc1].a=cx;
			}
			break;
		case WHILESYM:
			{
				ITEM x;
				x.typ=notyp;
				x.ref=-1;
				int lc1,lc2;
				SYMSET temp;
				Getsym();
				lc1=cx;
				temp=fsys;
				temp.insert(DOSYM);
				Condition(temp,x,lev);
				lc2=cx;
				Gen(Jpc,0,0);
				if(sym==DOSYM)
					Getsym();
				else
					Error("缺少关键字:do",linecount);
				Statement(fsys,lev);
				Gen(Jmp,0,lc1);
				code[lc2].a=cx;
				
			}
			break;
		case FORSYM:
			{
				TYP tp;
				FCT f;
				ITEM x;
				x.typ=notyp;
				x.ref=-1;
				int i,lc1,lc2;
				Getsym();
				if(sym==IDENT)
				{
					i=Position(id,lev);
					Getsym();
					if(i==0)
						Error("变量不存在,或不可引用",linecount);
					else if(table[i].kind==VARIABLE)
					{
						tp=table[i].type;
						Gen(Loda,lev-table[i].level,table[i].adr);
					}
					else
						Error("标识符类型错误",linecount);

				}
				else
				{
					Error("for语句中应为标识符",linecount);
					SYMSET temp=fsys;
					temp.insert(BECOMES),temp.insert(TOSYM),temp.insert(DOWNTOSYM),temp.insert(DOSYM);
					while(temp.find(sym)==temp.end())
						Getsym();
				}
				if(sym==BECOMES)
				{
					SYMSET temp=fsys;
					temp.insert(TOSYM),temp.insert(DOWNTOSYM),temp.insert(DOSYM);
					Getsym();
					Expression(temp,x,lev);
					if(x.typ!=tp)
						Warning("赋值可能会导致精度丢失",linecount);
				}
				else
				{
					Error("应为赋值符号:':='",linecount);
					SYMSET temp=fsys;
					temp.insert(TOSYM),temp.insert(DOWNTOSYM),temp.insert(DOSYM);
					while(temp.find(sym)==temp.end())
						Getsym();
				}
				f=F1U;//增量步长型for循环体入口测试
				if(sym==TOSYM||sym==DOWNTOSYM)
				{
					if(sym==DOWNTOSYM)
						f=F1D;//减量步长型for循环体入口测试
					Getsym();
					SYMSET temp=fsys;
					temp.insert(DOSYM);
					Expression(temp,x,lev);
					if(x.typ!=tp)
						Warning("赋值可能会导致精度丢失",linecount);
				}
				else
				{
					Error("应为:to或是downto",linecount);
					SYMSET temp=fsys;
					temp.insert(DOSYM);
					while(temp.find(sym)==temp.end())
						Getsym();
				}
				lc1=cx;
				Gen(F1U,0,0);
				if(sym==DOSYM)
					Getsym();
				else
					Error("缺少关键字:do",linecount);
				lc2=cx;
				Statement(fsys,lev);
				if(f==F1U)
					Gen(F2U,0,lc2);
				else 
					Gen(F2D,0,lc2);
				code[lc1].a=cx;
				
			}
			break;
		case READSYM:
			{
				Getsym();
				if(sym==LPAREN)
				{
					do
					{
						Getsym();
						if(sym!=IDENT)
							Error("应该是变量标志符",linecount);
						i=Position(id,lev);
						if(i!=0)
						{
							if(table[i].kind==VARIABLE)
							{
								x.typ=table[i].type;
								x.ref=table[i].ref;
								//Gen(Loda,lev-table[i].level,table[i].adr);
								Gen(Red,lev-table[i].level,table[i].adr);
								Getsym();
							}
							else
								Error("应该是变量",linecount);

						}
						else
							Error("变量不存在或不可引用",linecount);

					}while(sym==COMMA);
					if(sym==RPAREN)
						Getsym();
					else
						Error("缺少右括号:')'",linecount);
				}
				else
				{
					Error("缺少左括号:'('",linecount);
				}
			}
			break;
		case REPEAT:
		{
			ITEM x;
			int lc1;
			SYMSET temp1,temp2;
			temp1=fsys,temp1.insert(SEMICOLON),temp1.insert(UNTIL);
			x.typ=notyp,x.ref=0,lc1=cx;
			Getsym();
			Statement(temp1,lev);
			temp2=statbegsys;
			temp2.insert(SEMICOLON);
			while(temp2.find(sym)!=temp2.end())
			{
				if(sym==SEMICOLON)
					Getsym();
				else 
					Error("缺少分号",linecount);
				Statement(temp1,lev);
			}
			if(sym==UNTIL)
			{
				Getsym();
				Condition(fsys,x,lev);
				Gen(Jpc,0,lc1);
			}
			else
				Error("缺少关键字:until",linecount);

		}
		break;
		case WRITESYM:
			{
				Getsym();
				if(sym==LPAREN)
				{
					do
					{
						Getsym();
						if(sym==STRING)
						{
							Gen(Wrts,sentry,sleng);
							sentry=sleng+sentry;
							Getsym();
						}
						else
						{
							SYMSET temp;
							temp=fsys;
							temp.insert(RPAREN);
							Expression(temp,x,lev);
							Gen(Wrt,0.0f,0.0f);
						}
					}while(sym==COMMA);
					if(sym!=RPAREN)
						Error("write后缺少右括号:')'",linecount);
					Getsym();
				}
				else
				{
					Error("write后缺少左括号:'('",linecount);
					Getsym();
				}
			}
			break;
		}
	}
	SYMSET kong;
	Test(fsys,kong,"应该是分号:';'");
}

⌨️ 快捷键说明

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