gramanalyze.cpp

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

CPP
1,130
字号
#include "GramAnalyze.h"
#include "PL0Compiler.h"
#include "SymSet.h"
#include "Errors.h"
#include "SymbolTable.h"
#include "CCode.h"
#include <iostream>
#include <utility>
using namespace std;

GramAnalyze::GramAnalyze(PL0Compiler *p)
{
	lev = -1;
	for(int i = 0; i <= MAX_LEV; i++)
		dx[i] = 4;
	pl0Compiler = p;

	declBegSys+=constsy; declBegSys+=varsy; declBegSys+=procsy; declBegSys+=funcsy; 
	statBegSys+=beginsy; statBegSys+=ifsy;  statBegSys+=whilesy;statBegSys+=forsy;
	facBegSys+=ident;	 facBegSys+=inum;   facBegSys+=rnum;	facBegSys+=cha; facBegSys+=lparsy;

}


void GramAnalyze::startCompile()
{
	SymSet set1; set1=declBegSys; set1+=statBegSys;
	lev++; 
	getSymbol();
	pl0Compiler->symbolTable->setTable();
	block(set1);

}
bool GramAnalyze::test(SymSet s1, SymSet s2, int errorCode)
{
	if( !s1.inSet(token.first) )
	{
		pl0Compiler->errors->addError(errorCode);
		s1 += s2;
		do {
			getSymbol();
		} while( !s1.inSet(token.first) );
		return false;
	}
	return true;
}

void GramAnalyze::constDeclaration()
{
	int fuhao = 1;
	if( token.first == ident )
	{
		name = token.second;
		getSymbol();
		if(token.first == equsy)
		{
			getSymbol(); 
			if(token.first==plussy) getSymbol();
			if(token.first==minussy) {fuhao=-1; getSymbol();}
			SymSet set1;
			set1+=inum;
			set1+=rnum;
			set1+=cha;
			set1+=chastring;
			if( set1.inSet(token.first) )
			{
				set1-=chastring;
				set1-=cha;
				if(set1.inSet(token.first))
				{
					number = atof(token.second.c_str())*fuhao;
					if(token.first == inum)
						pl0Compiler->symbolTable->enter(constent, inum);
					if(token.first == rnum)
						pl0Compiler->symbolTable->enter(constent, rnum);
				}
				if(token.first == cha )
				{
					number = token.second.at(0);
					pl0Compiler->symbolTable->enter(constent, cha);
				}
				if(token.first == chastring)
				{
					pl0Compiler->ccode->stringEnter(token.second);
					number = pl0Compiler->ccode->getStringID();
					pl0Compiler->symbolTable->enter(constent, chastring);
				}
			}
			else
			{
				pl0Compiler->errors->addError(13);
			}
		}
		else
			pl0Compiler->errors->addError(12);
	}
	else
		pl0Compiler->errors->addError(11);
	getSymbol();

}
void GramAnalyze::varEnter(object kind)
{
	if(token.first == ident)
	{
		name = token.second;
		pl0Compiler->symbolTable->enter(kind,ident);
		dx[lev]++;
		getSymbol();
	}
	else
		pl0Compiler->errors->addError(11);
}

void GramAnalyze::varDeclaration(object kind)
{
	do{
		varEnter(kind);
		while(token.first == commasy)
		{
			getSymbol();
			varEnter(kind);
		}
	}while( token.first == ident );

	if(token.first == colonsy)//如果是‘:’
	{
		getSymbol();//得到类型说明符

		if( token.first==intsy || token.first==realsy || token.first==charsy )
		{
			switch(token.first)
			{
			case intsy:		pl0Compiler->symbolTable->typeFill(inum,kind);	break;
			case realsy:	pl0Compiler->symbolTable->typeFill(rnum,kind);	break;
			case charsy:	pl0Compiler->symbolTable->typeFill(cha,kind);	break;
			default:		pl0Compiler->symbolTable->typeFill(inum,kind);	break;
			}
		}
		else
		{
			pl0Compiler->errors->addError(15);//缺少类型说明符
			pl0Compiler->symbolTable->typeFill(inum,kind);
			return;
		}
	}
	else if( token.first==intsy || token.first==realsy || token.first==charsy )
	{
		pl0Compiler->errors->addError(14);//缺少‘:’

		switch(token.first)
		{
		case intsy:		pl0Compiler->symbolTable->typeFill(inum,kind);	break;
		case realsy:	pl0Compiler->symbolTable->typeFill(rnum,kind);	break;
		case charsy:	pl0Compiler->symbolTable->typeFill(cha,kind);	break;
		default:		pl0Compiler->symbolTable->typeFill(inum,kind);	break;
		}
	}
	else if(token.first == semicolonsy)	
	{
		pl0Compiler->errors->addError(14);//缺少‘:’
		pl0Compiler->errors->addError(15);//缺少类型说明符
		pl0Compiler->symbolTable->typeFill(inum,kind);
		return;
	}
		
	getSymbol();
}


void GramAnalyze::block(SymSet set1)
{
	//生成跳转指令,跳过声明部分到符合语句处理部分
	pl0Compiler->ccode->gen(JMP,0,0);
	int tx = pl0Compiler->ccode->getTopIndex();
	pl0Compiler->symbolTable->setFunProAdr(tx);
	
	//*********************************常量声明部分************************************/
	if(token.first == constsy)
	{
		getSymbol();
		do{
			constDeclaration();
			while(token.first==commasy)
			{
				getSymbol();
				constDeclaration();
			}
			if(token.first==semicolonsy)
				getSymbol();
			else if(token.first != ident)
				pl0Compiler->errors->addError(14);
		}while(token.first == ident);
	}

	//*********************************变量声明部分************************************/
	if(token.first == varsy)
	{
		getSymbol();
		do{
			varDeclaration(variable);
			if(token.first == semicolonsy)
				getSymbol();
			else
				pl0Compiler->errors->addError(14);
		}while(token.first == ident);
	}
	//*********************************************************************************/
	

	int i = pl0Compiler->symbolTable->findRecentFunPro();
	if(i>=0)
		pl0Compiler->symbolTable->setNumOfBlock(pl0Compiler->symbolTable->getTable(i).kind);

	SymSet tempSet1; tempSet1=set1; 
	SymSet tempSet2; tempSet2+=endsy;
	while(token.first==procsy || token.first == funcsy)
	{
		//********************************过程声明部分*************************************/
		if(token.first==procsy)
		{
			do{
				getSymbol();
				procDeclaration(set1);
				if(token.first==semicolonsy) getSymbol();
				else	pl0Compiler->errors->addError(14);
			}while(token.first==procsy);	
		}
		
		test(tempSet1,tempSet2,25);
		//**********************************************************************************/

		//**********************************函数声明****************************************/
		if(token.first==funcsy)
		{
			do{
				getSymbol();
				funcDeclaration(set1);
				if(token.first==semicolonsy) getSymbol();
				else pl0Compiler->errors->addError(14);
			}while(token.first==funcsy);
		}
		test(tempSet1,tempSet2,25);
	}
 	

	//填入之前跳转指令的跳转地址
	pl0Compiler->ccode->setAdr(tx,pl0Compiler->ccode->getTopIndex()+1);
	//***********************************************************************************/
	
	if(lev==0)
	{
		int n = pl0Compiler->symbolTable->sizeOfBBlock();
		pl0Compiler->ccode->gen(ALOC,-1,n);
	}
	else if(lev>0)
	{
		int i = pl0Compiler->symbolTable->findRecentFunPro();
		if(i >= 0)
		{
			table_type tbl = pl0Compiler->symbolTable->getTable(i);
			pl0Compiler->ccode->gen(ALOC,0,tbl.numOfBlock);
			int numOfPara = pl0Compiler->symbolTable->noOfPara(tbl.name);
			for(int i = numOfPara+3; i>=4; i--)
			{
				pl0Compiler->ccode->gen(STO, 0, i);
			}
		}
	}

	//******************************一下为复合语句处理部分*******************************/
	if(token.first!=beginsy)	
		pl0Compiler->errors->addError(24);
	else
	{
		tempSet1.reSet();
		tempSet1=set1;
		set1+=endsy;
		getSymbol();
		pl0Compiler->gramAnalyze->compStament(tempSet1);
	}
	//***********************************************************************************/
	


	lev--;
	pl0Compiler->symbolTable->rsetTable();
	pl0Compiler->ccode->gen(RTN,0,0);
	
	if(lev==-1)
	{
		if(token.first!=dot)
			pl0Compiler->errors->addError(53);
	}
}

void GramAnalyze::formalPar(SymSet set1)
{
	varDeclaration(para);
	while(token.first==semicolonsy)
	{
		getSymbol();
		varDeclaration(para);
	}
}

void GramAnalyze::procDeclaration(SymSet set1)
{
	lev++;
	dx[lev]=4;
	if(token.first==ident)
	{
		name = token.second;
		pl0Compiler->symbolTable->enter(procedure,nul);
		pl0Compiler->symbolTable->setTable();	
		getSymbol();
		if(token.first==lparsy)//处理参数列表
		{
			getSymbol();
			formalPar(set1);
			if(token.first==rparsy)	getSymbol();
			else	pl0Compiler->errors->addError(17);
		}
	}
	else
		pl0Compiler->errors->addError(16);//缺少过程或函数名
	if(token.first==semicolonsy) getSymbol();
	else	pl0Compiler->errors->addError(14);//过程首部结尾缺少‘;’
	set1+=semicolonsy;
	block(set1);

}

void GramAnalyze::funcHead(SymSet set1)
{
	if(token.first==ident)
	{
		name = token.second;
		pl0Compiler->symbolTable->enter(func,funcsy);
		pl0Compiler->symbolTable->setTable();
		getSymbol();
		if(token.first==lparsy)
		{
			getSymbol();
			formalPar(set1);
			if(token.first==rparsy) 
			{
				getSymbol();
				if(token.first == colonsy)//如果是‘:’
				{
					getSymbol();//得到类型说明符

					if( token.first==intsy || token.first==realsy || token.first==charsy )
					{
						switch(token.first)
						{
						case intsy:		pl0Compiler->symbolTable->typeFill(inum,func);	break;
						case realsy:	pl0Compiler->symbolTable->typeFill(rnum,func);	break;
						case charsy:	pl0Compiler->symbolTable->typeFill(cha,func);	break;
						default:		pl0Compiler->symbolTable->typeFill(inum,func);	break;
						}
						getSymbol();
					}
					else
					{
						pl0Compiler->errors->addError(15);//缺少类型说明符
						pl0Compiler->symbolTable->typeFill(inum,func);
						getSymbol();
						return;
					}
				}
				else if( token.first==intsy || token.first==realsy || token.first==charsy )
				{
					pl0Compiler->errors->addError(14);//缺少‘:’
					
					switch(token.first)
					{
					case intsy:		pl0Compiler->symbolTable->typeFill(inum,func);	break;
					case realsy:	pl0Compiler->symbolTable->typeFill(rnum,func);	break;
					case charsy:	pl0Compiler->symbolTable->typeFill(cha,func);	break;
					default:		pl0Compiler->symbolTable->typeFill(inum,func);	break;
					}
					getSymbol();
				}
				else if(token.first == semicolonsy)	
				{
					getSymbol();
					pl0Compiler->errors->addError(14);//缺少‘:’
					pl0Compiler->errors->addError(15);//缺少类型说明符
					pl0Compiler->symbolTable->typeFill(inum,func);
					return;
				}
			}
			else	pl0Compiler->errors->addError(17);
		}


		else if(token.first == colonsy)//如果是‘:’
		{
			getSymbol();//得到类型说明符

			if( token.first==intsy || token.first==realsy || token.first==charsy )
			{
				switch(token.first)
				{
				case intsy:		pl0Compiler->symbolTable->typeFill(inum,func);	break;
				case realsy:	pl0Compiler->symbolTable->typeFill(rnum,func);	break;
				case charsy:	pl0Compiler->symbolTable->typeFill(cha,func);	break;
				default:		pl0Compiler->symbolTable->typeFill(inum,func);	break;
				}
				getSymbol();
			}
			else
			{
				pl0Compiler->errors->addError(15);//缺少类型说明符
				pl0Compiler->symbolTable->typeFill(inum,func);
				getSymbol();
			}
		}
		else if( token.first==intsy || token.first==realsy || token.first==charsy )
		{
			pl0Compiler->errors->addError(14);//缺少‘:’

			switch(token.first)
			{
			case intsy:		pl0Compiler->symbolTable->typeFill(inum,func);	break;
			case realsy:	pl0Compiler->symbolTable->typeFill(rnum,func);	break;
			case charsy:	pl0Compiler->symbolTable->typeFill(cha,func);	break;
			default:		pl0Compiler->symbolTable->typeFill(inum,func);	break;
			}
			getSymbol();
		}
		else if(token.first == semicolonsy)	
		{
			pl0Compiler->errors->addError(14);//缺少‘:’
			pl0Compiler->errors->addError(15);//缺少类型说明符
			pl0Compiler->symbolTable->typeFill(inum,func);
			getSymbol();
			return;
		}
	}
	else
		pl0Compiler->errors->addError(16);//缺少函数或过程名
	if(token.first==semicolonsy)	getSymbol();
	else	pl0Compiler->errors->addError(14);//函数首部结尾缺少‘;’
}
void GramAnalyze::funcDeclaration(SymSet set1)
{
	lev++;
	dx[lev]=4;
	SymSet tempset1; tempset1=set1; tempset1+=declBegSys; tempset1+=statBegSys;
	funcHead(tempset1);
	set1+=semicolonsy;
	block(set1);
}

void GramAnalyze::readFunc(SymSet set1)
{
	if(token.first==lparsy)
	{
		do{
			getSymbol();
			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)
					{
						pl0Compiler->errors->addError(20);//不可向非常量赋值
						i = 0;
					}
					else
					{
						if(pl0Compiler->symbolTable->getTable(i).type==cha)
						{
							pl0Compiler->ccode->gen(READS, lev-tbl.level, tbl.address);
						}
						else if(pl0Compiler->symbolTable->getTable(i).type==inum)
						{
							pl0Compiler->ccode->gen(READI, lev-tbl.level, tbl.address);
						}
						else if(pl0Compiler->symbolTable->getTable(i).type==rnum)
						{
							pl0Compiler->ccode->gen(READR, lev-tbl.level, tbl.address);
						}
					}
				}
				getSymbol();
			}
			else
				pl0Compiler->errors->addError(11);//缺少标识符
		}while(token.first==commasy);
	}
	else
		pl0Compiler->errors->addError(19);//缺少左括号
	if(token.first!=rparsy)
		pl0Compiler->errors->addError(13);//缺少右括号
	else
		getSymbol();
}

void GramAnalyze::writeFunc(SymSet set12)
{
	SymSet set1;
	set1+=plussy; set1+=minussy; set1+=ident; set1+=inum; set1+=rnum; set1+=lparsy;
	if(token.first==lparsy)
	{
		do{
			getSymbol();
			bool b = false;
			if(token.first==chastring)
			{
				string temp = token.second;
				pl0Compiler->ccode->stringEnter(token.second);
				int id = pl0Compiler->ccode->getStringID();
				pl0Compiler->ccode->gen(WRTSTR,0,id);
				getSymbol();
				if(token.first==commasy)
					getSymbol();
				else
					pl0Compiler->errors->addError(22);//缺少‘,’
			}
			else
			{
				pl0Compiler->errors->addError(22);
				b = true;
			}

			if(set1.inSet(token.first))
			{
				int id2;
				set12+=commasy; set12+=rparsy;
				if(token.first==ident)
				{
					int i = pl0Compiler->symbolTable->position(token.second);
					id2 = pl0Compiler->symbolTable->getTable(i).Val;
				}
				Symbol tempType = expression(set12);
				switch(tempType)
				{
				case cha:	pl0Compiler->ccode->gen(WRTCH,0,0); break;
				case inum:	pl0Compiler->ccode->gen(WRTI,0,0); break;
				case rnum:	pl0Compiler->ccode->gen(WRTR,0,0); break;
				case chastring: pl0Compiler->ccode->gen(WRTSTR,0,id2); break;
				}	
				//pl0Compiler->ccode->list();
				
				//getSymbol();
			}
			else
			{
				if(!b)
					pl0Compiler->errors->addError(22);
			}
		}while(token.first == commasy);
	}
	else
		pl0Compiler->errors->addError(19);//缺少左括号
	if(token.first!=rparsy)
		pl0Compiler->errors->addError(17);//缺少右括号
	else
		getSymbol();

⌨️ 快捷键说明

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