gramanalyze.cpp

来自「pl0文法编译器」· C++ 代码 · 共 1,130 行 · 第 1/2 页

CPP
1,130
字号
}

Symbol GramAnalyze::expression(SymSet set1)
{
	bool sflag=false;
	Symbol fuhao;
	Symbol type = cha;
	Symbol temp1,temp2;
	SymSet tempSet1; tempSet1=set1; tempSet1+=minussy; tempSet1+=plussy; 
	
	if(token.first==plussy || token.first==minussy)
	{
		fuhao = token.first;
		getSymbol();
		temp1 = term(tempSet1);
		if(temp1>type)	type = temp1;
		if(fuhao==minussy)
			pl0Compiler->ccode->gen(REV,0,0);
	}
	else
	{		
		temp1 = term(tempSet1);
		if(temp1 > type) type = temp1;
	}
	while(token.first==plussy || token.first==minussy)
	{
		fuhao = token.first;
		getSymbol();

		if(token.first!=ident && token.first!=rnum && token.first!=inum && token.first!= cha )
			break;
		if(token.first==ident)
		{
			int i = pl0Compiler->symbolTable->position(token.second);
			if(i < 0)
				pl0Compiler->errors->addError(21);
			else
			{
				table_type tbl = pl0Compiler->symbolTable->getTable(i);
				if(tbl.kind == procedure)
					break;
			}
		}

		temp2 = term(tempSet1);
		if(temp2 > type)		type = temp2;
		if((temp1==chastring || temp2==chastring) && !sflag)
		{
			pl0Compiler->errors->addError(41);
			sflag = true;
		}
		if(fuhao==plussy)
		{
			pl0Compiler->ccode->gen(ADD,0,0);
		}
		else
		{
			pl0Compiler->ccode->gen(MIN,0,0);
		}
	}
	return type;
}

void GramAnalyze::compStament(SymSet set12)
{
	set12+=semicolonsy; set12+=endsy;
	stament(set12);
	SymSet set1;
	set1+=semicolonsy; set1+=beginsy; set1+=ifsy; set1+=whilesy; set1+=forsy;
	while(set1.inSet(token.first))
	{
		if(token.first==semicolonsy)	getSymbol();
		else	pl0Compiler->errors->addError(14);
		stament(set12);
	}
	if(token.first==endsy)	getSymbol();
	else	pl0Compiler->errors->addError(23);
}

void GramAnalyze::stament(SymSet set1)
{
	switch(token.first)
	{
	case readsy:	getSymbol(); readFunc(set1); break;
	case writesy:	getSymbol(); writeFunc(set1); break;
	case ident:		identForStatment(set1);	break;
	case beginsy:	getSymbol(); compStament(set1);	break;
	case ifsy:		getSymbol(); ifFunc(set1);	break;
	case forsy:		getSymbol(); forFunc(set1);	break;
	case whilesy:	getSymbol(); whileFunc(set1);	break;
	case semicolonsy: case endsy:	break;
	default: pl0Compiler->errors->addError(35);
	}
	SymSet set2; 
	test(set1,set2,35);
}

Symbol GramAnalyze::term(SymSet set1)
{
	set1+=timesy;
	set1+=divisy;
	bool sflag=false;
	Symbol fuhao;
	Symbol type = cha;
	Symbol temp1,temp2;
	temp1 = factor(set1);
	if(temp1>type) type = temp1;
	while(token.first==timesy || token.first==divisy)
	{
		fuhao = token.first;
		getSymbol();

		if(token.first!=ident && token.first!=rnum && token.first!=inum && token.first!= cha && token.first!=lparsy)
			break;
		if(token.first==ident)
		{
			table_type tbl;
			int i = pl0Compiler->symbolTable->position(token.second);
			if(i > 0)
			{
				tbl = pl0Compiler->symbolTable->getTable(i);
				if(tbl.kind == procedure)
					break;
			}
		}
		
		temp2 = factor(set1);
		if((temp1==chastring || temp2==chastring) && !sflag)
		{
			pl0Compiler->errors->addError(41);
			sflag = true;
		}
		if(temp2>type)	type = temp2;
		if(fuhao==timesy)
		{
			pl0Compiler->ccode->gen(TIM,0,0);
		}
		else if(temp1<=inum && temp2<=inum)
		{
			pl0Compiler->ccode->gen(DIVI,0,0);
		}
		else
		{
			pl0Compiler->ccode->gen(DIV,0,0);
		}
	}
	return type;
}

Symbol GramAnalyze::factor(SymSet set1)
{
	test(facBegSys,set1,27);
	Symbol type = cha;
	while(facBegSys.inSet(token.first))
	{
		if(token.first==ident)
		{
			int i = pl0Compiler->symbolTable->position(token.second);
			if(i<0)	
				pl0Compiler->errors->addError(21);//未声明标示符
			else
			{
				table_type tbl = pl0Compiler->symbolTable->getTable(i);
				switch(tbl.kind)
				{
				case variable:	case para:
					switch(tbl.type)
					{
					case inum:	pl0Compiler->ccode->gen(LODI,lev-tbl.level,tbl.address); break;
					case rnum:	pl0Compiler->ccode->gen(LODR,lev-tbl.level,tbl.address); break;
					case cha:	pl0Compiler->ccode->gen(LODCH,lev-tbl.level,tbl.address); break;
					default: break;
					}
					if(tbl.type>type)	type = tbl.type;
					getSymbol();
					break;
				case constent:
					switch (tbl.type)
					{
					case inum: pl0Compiler->ccode->gen(LITI,0,tbl.Val); break;
					case rnum: pl0Compiler->ccode->gen(LITR,0,tbl.Val); break;
					case cha:  pl0Compiler->ccode->gen(LITCH,0,tbl.Val); break;
					}
					if(tbl.type>type)	type = tbl.type;
					getSymbol();
					break;
				case func:
					{
						if(tbl.type>type)	type = tbl.type;
						SymSet tempSet1 = set1; set1+=minussy; set1+=plussy; set1+=divisy; set1+=timesy;
						funcCall(tempSet1);
						break;
					}
				default: pl0Compiler->errors->addError(28);
				}
			}
		}
		if(token.first==inum||token.first==rnum||token.first==cha)
		{
			if(token.first>type)	type = token.first;
			if(token.first==cha)
			{
				pl0Compiler->ccode->gen(LITCH,0,token.second.at(0));
			}
			else
			{
				switch (token.first)
				{
				case inum: pl0Compiler->ccode->gen(LITI,0,atof(token.second.c_str())); break;
				case rnum: pl0Compiler->ccode->gen(LITR,0,atof(token.second.c_str())); break;
				}
			}
			getSymbol();
		}
		if(token.first==lparsy)
		{
			getSymbol();
			SymSet tempSet1; tempSet1=set1; tempSet1+=rparsy;
			Symbol temp = expression(tempSet1);
			if(temp>type)	type = temp;
			if(token.first==rparsy)
				getSymbol();
			else
				pl0Compiler->errors->addError(17);
		}
		SymSet set2; set2+=endsy;
		test(set1,set2,29);
	}
	return type;
}

void GramAnalyze::funcCall(SymSet set1)
{
	int i = pl0Compiler->symbolTable->funcproNameCheck(token.second, func);
	if( i < 0)
	{
		pl0Compiler->errors->addError(33);
	}
	else
	{
		int numOfPara = pl0Compiler->symbolTable->noOfPara(token.second,func);
		int n = numOfPara;
		//pl0Compiler->ccode->gen(ALOC,lev-pl0Compiler->symbolTable->getTable(i).level,pl0Compiler->symbolTable->getTable(i).numOfBlock);
		getSymbol();
		if(n>0)
		{
			if(token.first!=lparsy)
				pl0Compiler->errors->addError(19);
			else
			{
				getSymbol();			
				actualPara(set1, i+1,n);
			}
		}
		
		pl0Compiler->ccode->gen(CALL,lev-pl0Compiler->symbolTable->getTable(i).level,pl0Compiler->symbolTable->getTable(i).address);
	}
}

void GramAnalyze::procCall(SymSet set1)
{
	int i = pl0Compiler->symbolTable->funcproNameCheck(token.second,procedure);
	if( i < 0)
	{
		pl0Compiler->errors->addError(34);
	}
	else
	{
		int numOfPara = pl0Compiler->symbolTable->noOfPara(token.second,procedure);
		int n = numOfPara;
		//pl0Compiler->ccode->gen(ALOC,lev-pl0Compiler->symbolTable->getTable(i).level,pl0Compiler->symbolTable->getTable(i).numOfBlock);
		getSymbol();
		if(n>0)
		{
			if(token.first!=lparsy)
				pl0Compiler->errors->addError(19);
			else
			{
				getSymbol();			
				actualPara(set1, i+1,n);
			}
		}
		pl0Compiler->ccode->gen(CALL,lev-pl0Compiler->symbolTable->getTable(i).level,pl0Compiler->symbolTable->getTable(i).address);
	}
}

void GramAnalyze::actualPara(SymSet set1, int i, int &numOfPara)
{
	set1+=rparsy; set1+=commasy;
	
	table_type tbl = pl0Compiler->symbolTable->getTable(i);
	Symbol type = expression(set1);
	if(type > tbl.type) 
	{
		if(type!=inum)
			pl0Compiler->errors->addError(52);
	}	

	numOfPara--;	

	while(token.first==commasy)
	{
		getSymbol();
		numOfPara--;	i++;
		if(numOfPara < 0) 
		{
			pl0Compiler->errors->addError(32);
			break;
		}
		table_type tbl = pl0Compiler->symbolTable->getTable(i);
		Symbol type = expression(set1);
		if(type > tbl.type)
		{
			if(type==inum)
				break;
			pl0Compiler->errors->addError(52);
		}	
	}
	if(numOfPara>0)	
		pl0Compiler->errors->addError(32);
	if(token.first==rparsy)
		getSymbol();
	else
		pl0Compiler->errors->addError(17);
}

void GramAnalyze::identForStatment(SymSet set1)
{
	int i = pl0Compiler->symbolTable->position(token.second);
	if(i < 0)
		pl0Compiler->errors->addError(21);
	else
	{
		table_type tbl = pl0Compiler->symbolTable->getTable(i);
		int l = tbl.level;
		int a = tbl.address;
		Symbol type = tbl.type;
		Symbol temptype = cha;
		if(tbl.kind==variable||tbl.kind==para)
		{
			getSymbol();
			if(token.first==assignsy || token.first==equsy)
			{
				if(token.first==equsy)	pl0Compiler->errors->addError(51);
				getSymbol();
				temptype = expression(set1);
				if(temptype>type) 
				{
					if(temptype!=inum)
						pl0Compiler->errors->addError(52);
				}	
				
				pl0Compiler->ccode->gen(STO, lev-l,a);
			}
			else
				pl0Compiler->errors->addError(12);
		}
		else if(tbl.kind == func)
		{
			int funcLev = tbl.level;
			getSymbol();
			if(token.first==assignsy || token.first==equsy)
			{
				getSymbol();
				if(token.first==equsy)	pl0Compiler->errors->addError(51);
				temptype = expression(set1);
				if(temptype>type) 
				{
					if(temptype!=inum)
						pl0Compiler->errors->addError(52);
				}	
				pl0Compiler->ccode->gen(STO, lev-funcLev-1,3);
			}
			else
				pl0Compiler->errors->addError(12);
		}
		else if(tbl.kind == procedure)
		{
			procCall(set1);
		}
		else
			pl0Compiler->errors->addError(35);
	}
}

void GramAnalyze::condition(SymSet set1)
{
	SymSet conditionSet;
	conditionSet+=equsy; conditionSet+=nequsy; conditionSet+=lesssy; conditionSet+=leseqsy; conditionSet+=grtsy; conditionSet+=grteqsy;
	SymSet tempSet = set1;	tempSet+=conditionSet;
	expression(tempSet);
	
	if(conditionSet.inSet(token.first))
	{
		Symbol conSy = token.first;
		getSymbol();
		set1+=conditionSet;
		expression(set1);
		switch(conSy)
		{
		case equsy:		pl0Compiler->ccode->gen(EQU, 0,0);		break;
		case nequsy:	pl0Compiler->ccode->gen(NEQU, 0,0);		break;
		case lesssy:	pl0Compiler->ccode->gen(LES, 0,0);		break;
		case leseqsy:	pl0Compiler->ccode->gen(LESEQ, 0,0);	break;
		case grtsy:		pl0Compiler->ccode->gen(GRT, 0,0);		break;
		case grteqsy:	pl0Compiler->ccode->gen(GRTEQ, 0,0);	break;
		default:	break;
		}
	}
	else
		pl0Compiler->errors->addError(36);
}

void GramAnalyze::whileFunc(SymSet set1)
{
	int cx1 = pl0Compiler->ccode->getTopIndex()+1;
	set1+=dosy;
	condition(set1);
	set1-=dosy;

	pl0Compiler->ccode->gen(JPC,0,0);
	int cx2 = pl0Compiler->ccode->getTopIndex();
	if(token.first==dosy)
	{
		set1+=endsy; set1+=semicolonsy;
		getSymbol();
	}
	else
	{
		pl0Compiler->errors->addError(39);
	}
	set1+=endsy; set1+=semicolonsy;
	stament(set1);
	pl0Compiler->ccode->gen(JMP, 0, cx1);
	pl0Compiler->ccode->setAdr(cx2,pl0Compiler->ccode->getTopIndex()+1);
	
}

void GramAnalyze::forFunc(SymSet set1)
{
	if(token.first==ident )
	{
		int i = pl0Compiler->symbolTable->position(token.second);
		if(i < 0 )
		{
			pl0Compiler->errors->addError(21);
		}
		else
		{
			table_type tbl = pl0Compiler->symbolTable->getTable(i);
			if((tbl.kind!=variable && tbl.kind!=para) || (tbl.type!=inum && tbl.type!=cha))
			{
				pl0Compiler->errors->addError(37);//for后应为整形变量
			}
			else
			{
				int l = tbl.level;
				int a = tbl.address;
				Symbol type = tbl.type;
				getSymbol();
				if(token.first==equsy || token.first==assignsy)
				{
					if(token.first==equsy)
					{
						pl0Compiler->errors->addError(51);//应为赋值符号
					}
					else
					{
						getSymbol();
						set1+=tosy;
						Symbol tempType = expression(set1);
						set1-=tosy;

						pl0Compiler->ccode->gen(STO,lev-l,a);
						if(tempType > type)
						{
							if(tempType != inum)
								pl0Compiler->errors->addError(52);
						}
						
						if(token.first==tosy)
						{
							getSymbol();
							int cx1 = pl0Compiler->ccode->getTopIndex()+1;
							
							set1+=dosy;
							expression(set1);
							set1-=dosy;

							pl0Compiler->ccode->gen(LODI,lev-l,a);
							pl0Compiler->ccode->gen(GRTEQ,0,0);
							pl0Compiler->ccode->gen(JPC,0,0);
							int cx2 = pl0Compiler->ccode->getTopIndex();
							if(token.first==dosy)
							{
								getSymbol();
								set1+= endsy;set1+=semicolonsy;
								stament(set1);
								pl0Compiler->ccode->gen(LODI,lev-l,a);
								pl0Compiler->ccode->gen(LITI,0,1);
								pl0Compiler->ccode->gen(ADD, 0, 0);
								pl0Compiler->ccode->gen(STO,lev-l,a);
								pl0Compiler->ccode->gen(JMP, 0, cx1);
								pl0Compiler->ccode->setAdr(cx2,pl0Compiler->ccode->getTopIndex()+1);
							}
							else
							{
								pl0Compiler->errors->addError(39);
							}
						}
						else
						{
							pl0Compiler->errors->addError(38);//缺少to
						}
					}
				}
				else
				{
					pl0Compiler->errors->addError(12);//标识符后应为:=
				}
			}
		}
	}
	else
	{
		pl0Compiler->errors->addError(37);//for后应为标识符
	}
}

void GramAnalyze::ifFunc(SymSet set1)
{
	set1+=thensy;
	condition(set1);
	set1-=thensy;

	pl0Compiler->ccode->gen(JPC,0,0);
	int cx1 = pl0Compiler->ccode->getTopIndex();
	if(token.first==thensy)
	{
		getSymbol();
		set1+=elsesy;
		stament(set1);
		set1-=elsesy;
	}
	else
		pl0Compiler->errors->addError(40);
	//SymSet tempSet1= set1;
	//tempSet1+=statBegSys;
	//tempSet1+=elsesy;
	//test(tempSet1, set1,35);
	if(token.first==elsesy)
	{
		pl0Compiler->ccode->gen(JMP,0,0);
		int cx2 = pl0Compiler->ccode->getTopIndex();
		pl0Compiler->ccode->setAdr(cx1,cx2+1);
		set1+=endsy;set1+=semicolonsy;
		getSymbol();
		stament(set1);
		pl0Compiler->ccode->setAdr(cx2,pl0Compiler->ccode->getTopIndex()+1);
	}
	else
	{
		pl0Compiler->ccode->setAdr(cx1,pl0Compiler->ccode->getTopIndex()+1);
	}
}

⌨️ 快捷键说明

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