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

📄 pl.cpp

📁 这是我们的一个上机题,做词法分析和语法的,希望对大家的学习有所帮助
💻 CPP
📖 第 1 页 / 共 4 页
字号:
{
	TYPES type;
	int ref,size,helper;

	if(CurSymbol->type==IDENT)
	{
		ENTER(TYPEL);  //被声明的类型标识符
		helper=TX;	
		getASymbol();

		if(CurSymbol->type==EQL)
			getASymbol();
		else
		{
			error(6);//应该是'='
			if(CurSymbol->type==SEMICOLON)
				getASymbol();
		}

		//////////////////////////////////////////////////////////////
		SYMLIST * tempList=new SYMLIST;
		COPYLIST(tempList,listAddSym(listAddSym(listAddSym(list,SEMICOLON),COMMA),IDENT));
		TYP(tempList,type,ref,size);    //获取类型信息
		delete tempList;
		//////////////////////////////////////////////////////////////

		NAMETAB[TX].type=type;         //填表
		NAMETAB[TX].ref=ref;
		NAMETAB[TX].unite.size=size;

		if(CurSymbol->type==SEMICOLON)
			getASymbol();
		else
			error(1);//应该是';'
	}
	else
		error(14);//应该是标识符
}

void VARDECLARATION(SYMLIST * list)   //变量声明
{
	TYPES type;
	int ref,size,helper1,helper2;

	if(CurSymbol->type==IDENT)
	{
		helper1=TX;
		ENTER(VARIABLE);   //被声明的变量
		getASymbol();
		while(CurSymbol->type==COMMA)  //如果是逗号,则面临的是同类型的一串变量列表
		{
			getASymbol();
			if(CurSymbol->type==IDENT)
			{
				ENTER(VARIABLE);  //被声明的变量
				getASymbol();
			}
			else
				error(14);//应该是标识符
		}

		if(CurSymbol->type==COLON)
			getASymbol();
		else
			error(0);//应该是':'

		helper2=TX;

	    //////////////////////////////////////////////////////////
		SYMLIST * tempList=new SYMLIST;
		COPYLIST(tempList,listAddSym(listAddSym(listAddSym(list,SEMICOLON),COMMA),IDENT));
		TYP(tempList,type,ref,size);  //获取变量的类型信息
		delete tempList;
		//////////////////////////////////////////////////////////

		while(helper1<helper2)  //将一串变量的信息填表
		{
			helper1++;
			NAMETAB[helper1].type=type;
			NAMETAB[helper1].ref=ref;
			NAMETAB[helper1].level=displayLevel;
			NAMETAB[helper1].unite.address=DX;
			NAMETAB[helper1].normal=1;
			DX+=size;
		}

		if(CurSymbol->type==SEMICOLON)
			getASymbol();
		else
			error(1);//应该是';'
	}
	else
		error(14);//应该是标识符
}

void PROCDECLARATION(SYMLIST * list)  //过程声明
{
	getASymbol();
	if(CurSymbol->type!=IDENT)
	{
		error(14);  //应该是标识符
		strcpy(CurSymbol->value.lpValue,"");
	}

	ENTER(PROCEDURE);  //被声明的过程名
	NAMETAB[TX].normal=1;
	getASymbol();

	///////////////////////////////////////////////////////////
	SYMLIST * tempList1=new SYMLIST;
	COPYLIST(tempList1,listAddSym(list,SEMICOLON));
	BLOCK(tempList1,displayLevel);   //编译过程体
	delete tempList1;
	///////////////////////////////////////////////////////////

	if(CurSymbol->type==SEMICOLON)
		getASymbol();
	else
		error(1);//应该是';'
}

void error(int errCode)   //负责显示出错信息的函数
{
	char errorScript[][100]=
	{
		"应该是\':\'",//0
        "应该是\';\'",//1
		"应该是\')\'",//2
		"应该是\'(\'",//3
		"应该是\'[\'",//4
		"应该是\']\'",//5
		"应该是\'=\'",//6
		"应该是\':=\'",//7
		"应该是\'.\'",//8
		"应该是\'do\'",//9
		"应该是\'of\'",//10
		"应该是\'then\'",//11
		"应该是\'end\'",//12
		"应该是\'program\'",//13
		"应该是标识符",//14
		"应该是类型标识符",//15
		"应该是变量",//16
		"应该是常量或常量标识符",//17
		"应该是过程名",//18
		"数组上下界大小关系错误",//19
		"数组定义时,下标元素类型错误",//20
		"数组定义时,上下界类型不一致",//21
		"引用时,数组元素下标元素类型出错",//22
		"下标个数不正确",//23
		"数组表溢出",//24
		"名字表溢出",//25
		"程序体表溢出",//26
		"系统为本编译程序分配的堆不够用",//27
		"实参与形参个数不等",//28
		"实参与形参类型不一致",//29
		"实参个数不够",//30
		"程序体内符号重定义",//31
		"if或while后面表达式必须为布尔类型",//32
		"标识符没有定义",//33
		"过程名或类型名不能出现在表达式中",//34
		"操作数类型错误",//35
		"类型定义出错",//36
		"类型不一致",//37
		"不认识的字符出现在源程序",//38
		"不能打开.lst文件",//39
		"不能打开.pld文件",//40
		"不能打开.lab文件",//41
		"应该是\'..\'",//42
		"分析时缺少标识符",//43
		//***************************************                   @@@@@@
		"应该是\'until\'",//44 添加
		"until后面表达式必须为布尔类型",//45添加
		"应该是\'to\'",//46添加
		"应该是整数",//47添加
};

	if(CurSymbol && CurSymbol->lineNumber>0)
		printf("\n<<<<<<  Line number %d ",CurSymbol->lineNumber);
	printf("found error %d : %s !  >>>>>>\n\n",errCode,errorScript[errCode]);
	nError++;
	
}


void FACTOR(SYMLIST * list,TYPEITEM & typeItem)  //获取下一个“因子”的信息,传引用参数typeItem用来保存信息
{
	int i;

	typeItem.typ=NOTYP;
	typeItem.ref=0;

	////////////////////////////////////////////////////////
	SYMLIST * tempList2=new SYMLIST;
	COPYLIST(tempList2,listAddSym(list,RPAREN));	
	////////////////////////////////////////////////////////

	while(SYMINLIST(CurSymbol->type,&FACBEGSYS))
	{
		switch(CurSymbol->type)
		{
		case IDENT:
			i=GETPOSITION(CurSymbol->value.lpValue);  //如果是标识符,则查表
			Temporary_i=i;    //修改
			getASymbol();
			if(i!=0)
			{
				switch(NAMETAB[i].kind)
				{
				case KONSTANT:
					typeItem.typ=NAMETAB[i].type;
					typeItem.ref=0;
					GEN(LIT,0,NAMETAB[i].unite.value);
					break;
				case VARIABLE:
					typeItem.typ=NAMETAB[i].type;
					typeItem.ref=NAMETAB[i].ref;
					if(NAMETAB[i].type==INTS || NAMETAB[i].type==BOOLS || NAMETAB[i].type==CHARS)
					{
						if(NAMETAB[i].normal)
							GEN(LOD,NAMETAB[i].level,NAMETAB[i].unite.address);
						else
							GEN(ILOD,NAMETAB[i].level,NAMETAB[i].unite.address);
					}
					else
					{
						if(NAMETAB[i].type==ARRAYS)
						{
							if(NAMETAB[i].normal)
								GEN(LODA,NAMETAB[i].level,NAMETAB[i].unite.address);
							else
								GEN(LOD,NAMETAB[i].level,NAMETAB[i].unite.address);
							if(CurSymbol->type==LBRACK)
								ARRAYELEMENT(list,typeItem);
							if(typeItem.typ!=ARRAYS)
								GEN(LODT,0,0);
						}
					}
					break;
				case PROCEDURE:
				case TYPEL:
					error(34);  //过程名或类型名不能出现在表达始中
					break;
				}
			}
			break;

		case INTCON:
		case CHARCON:
			if(CurSymbol->type==INTCON)
				typeItem.typ=INTS;
			else
				typeItem.typ=CHARS;
			typeItem.ref=0;
			GEN(LIT,0,CurSymbol->value.iValue);
			Temporary_i=CurSymbol->value.iValue;      //修改
			getASymbol();
			break;
		case LPAREN:  //如果是左括号
			getASymbol();
			EXPRESSION(tempList2,typeItem);  //获取一个“表达式”的信息
			if(CurSymbol->type==RPAREN)
				getASymbol();
			else 
				error(2); //应该是')'
			break;
		case NOTSYM:   //如果是“非”
			getASymbol();
			FACTOR(list,typeItem);   //获取一个“因子”的信息
			if(typeItem.typ==BOOLS)
				GEN(NOTS,0,0);
			else
				error(35);  //操作数类型错误
			break;
		}

	}
	delete tempList2;
}


void TERM(SYMLIST * list,TYPEITEM & typeItem)  //获取一个“项”的信息
{
	SYMBOL mulop;
	TYPEITEM helpTypeItem;

	///////////////////////////////////////////////////////////
	SYMLIST * tempList=new SYMLIST;
	SYMLIST * tempList1=new SYMLIST;
	tempList1->AddHead(TIMES);	tempList1->AddHead(DIVSYM);	tempList1->AddHead(MODSYM);	tempList1->AddHead(ANDSYM);
	COPYLIST(tempList,listsAdd(tempList1,list));
	FACTOR(tempList,typeItem);    //获取一个“因子”的信息
	///////////////////////////////////////////////////////////

	while(SYMINLIST(CurSymbol->type,tempList1))
	{
		mulop=CurSymbol->type;  
		getASymbol();
		FACTOR(tempList,helpTypeItem);   //获取一个“因子”的信息
		if(typeItem.typ!=helpTypeItem.typ)
		{
			error(37);//类型不一致
			typeItem.typ=NOTYP;
			typeItem.ref=0;
		}
		else
		{
			switch(mulop)
			{
			case TIMES:
				if(typeItem.typ==INTS)
					GEN(MULT,0,0);
				else
					error(35);//操作数类型错误
				break;
			case DIVSYM:
				if(typeItem.typ==INTS)
					GEN(IDIV,0,0);
				else
					error(35);//操作数类型错误
				break;
			case MODSYM:
				if(typeItem.typ==INTS)
					GEN(IMOD,0,0);
				else
					error(35);//操作数类型错误
				break;
			case ANDSYM:
				if(typeItem.typ==INTS)
					GEN(ANDS,0,0);
				else
					error(35);//操作数类型错误
				break;
			}
		}
	}
	delete tempList;delete tempList1;
}

void SIMPLEEXPRESSION(SYMLIST * list,TYPEITEM & typeItem)  //获取一个“简单表达式”的信息
{
	SYMBOL addop;
	TYPEITEM helpTypeItem;

	/////////////////////////////////////////////////
	SYMLIST * tempList=new SYMLIST;
	SYMLIST * tempList1=new SYMLIST;
	tempList->AddHead(PLUS);	tempList->AddHead(MINUS);	tempList->AddHead(ORSYM);
	COPYLIST(tempList1,listsAdd(tempList,list));
	/////////////////////////////////////////////////

	if(CurSymbol->type==PLUS || CurSymbol->type==MINUS)
	{
		addop=CurSymbol->type;
		getASymbol();
		TERM(tempList1,typeItem);  //获取一个“项”的信息
		if(addop==MINUS)
			GEN(MUS,0,0);
	}
	else
		TERM(tempList1,typeItem);   //获取一个“项”的信息

	while(SYMINLIST(CurSymbol->type,tempList))
	{
		addop=CurSymbol->type;
		getASymbol();
		TERM(tempList1,helpTypeItem);   //获取一个“项”的信息
		if(typeItem.typ!=helpTypeItem.typ)  //如果两个项的信息发生冲突
		{
			error(37);//类型不一致
			typeItem.typ=NOTYP;
			typeItem.ref=0;
		}
		else
		{
			switch(addop)
			{
			case PLUS:
				if(typeItem.typ==INTS)
					GEN(ADD,0,0);
				else
					error(35);//操作数类型错误
				break;
			case MINUS:
				if(typeItem.typ==INTS)
					GEN(SUB,0,0);
				else
					error(35);//操作数类型错误
				break;
			case ORSYM:
				if(typeItem.typ==BOOLS)
					GEN(ORS,0,0);
				else
					error(35);//操作数类型错误
				break;
			}
		}
	}
	delete tempList;delete tempList1;
}

void EXPRESSION(SYMLIST * list,TYPEITEM & typeItem)   //获取一个“表达式”的信息
{
	SYMBOL relationop;
	TYPEITEM helpTypeItem;

	/////////////////////////////////////////////////////////////////
	SYMLIST * tempList=new SYMLIST;
	SYMLIST * tempList1=new SYMLIST;
	tempList->AddHead(EQL);	tempList->AddHead(NEQ);	tempList->AddHead(LSS);
	tempList->AddHead(GTR);	tempList->AddHead(LEQ);	tempList->AddHead(GEQ);
	COPYLIST(tempList1,listsAdd(tempList,list));
	SIMPLEEXPRESSION(tempList1,typeItem);  //获取一个“简单表达式”的信息
	/////////////////////////////////////////////////////////////////

	while(SYMINLIST(CurSymbol->type,tempList))
	{
		relationop=CurSymbol->type;
		getASymbol();
		SIMPLEEXPRESSION(list,helpTypeItem);   ///获取一个“简单表达式”的信息
		if(typeItem.typ!=helpTypeItem.typ)
			error(37);//类型不一致
		else
		{
			switch(relationop)
			{
			case EQL: GEN(EQ,0,0);break;
			case NEQ: GEN(NE,0,0);break;
			case LSS: GEN(LS,0,0);break;
			case GEQ: GEN(GE,0,0);break;
			case GTR: GEN(GT,0,0);break;
			case LEQ: GEN(LE,0,0);break;
			}
		}
		typeItem.typ=BOOLS;
	}
	delete tempList;delete tempList1;
}



void ARRAYELEMENT(SYMLIST * list,TYPEITEM & typeItem)  //获取一个数组元素的信息
{
	int p;
	TYPEITEM helpTypeItem;

	p=typeItem.ref;
	if(CurSymbol->type==LBRACK)
	{
		SYMLIST * tempList=new SYMLIST;
		COPYLIST(tempList,listAddSym(list,COMMA));
		do
		{
			getASymbol();
			EXPRESSION(tempList,helpTypeItem);   //引用数组元素时所使用的数组下标的信息
			if(typeItem.typ!=ARRAYS)
				error(23);  //下标个数不正确
			else
			{
				if(helpTypeItem.typ!=ATAB[p].intType)
					error(22);  //数组元素引用时,下标元素类型出错
				GEN(LIT,0,ATAB[p].low);    //下面是产生的计算数组元素地址的代码
				GEN(SUB,0,0);
				GEN(LIT1,0,ATAB[p].elSize);
				GEN(MULT,0,0);
				GEN(ADD1,0,0);
				typeItem.typ=ATAB[p].eleType;
				typeItem.ref=ATAB[p].elRef;
				p=ATAB[p].elRef;
			}
		}
		while(CurSymbol->type==COMMA);  //多维数组

		if(CurSymbol->type==RBRACK)
			getASymbol();
		else
			error(5);//应该是']'
	}
	else
		error(4);//应该是'['	
}


void INITIAL()  //编译程序初始化所作的一些工作
{
	nError=0;
	displayLevel=0;
	DISPLAY[0]=0;

	DX=0;
	CX=0;
	BX=1;
	TX=-1;
	JX=0;

	// FIVE SYMLISTS' INITIALIZATION

	DECLBEGSYS.AddHead(CONSTSYM);	DECLBEGSYS.AddHead(VARSYM);
	DECLBEGSYS.AddHead(TYPESYM);	DECLBEGSYS.AddHead(PROCSYM);

	STATBEGSYS.AddHead(BEGINSYM);	STATBEGSYS.AddHead(CALLSYM);
	STATBEGSYS.AddHead(IFSYM);	STATBEGSYS.AddHead(WHILESYM);
	
	//**********************************************************                   @@@@@@
	//修改
	STATBEGSYS.AddHead(REPEATSYM);	STATBEGSYS.AddHead(FORSYM);
	STATBEGSYS.AddHead(CASESYM);
	//**********************************************************

	FACBEGSYS.AddHead(IDENT);	FACBEGSYS.AddHead(INTCON);	FACBEGSYS.AddHead(LPAREN);
	FACBEGSYS.AddHead(NOTSYM);	FACBEGSYS.AddHead(CHARCON);

	TYPEBEGSYS.AddHead(IDENT);	TYPEBEGSYS.AddHead(ARRAYSYM);

	CONSTBEGSYS.AddHead(PLUS);	CONSTBEGSYS.AddHead(MINUS);	CONSTBEGSYS.AddHead(INTCON);
	CONSTBEGSYS.AddHead(CHARCON);	CONSTBEGSYS.AddHead(IDENT);
}


void ENTERID(char * name,OBJECT kind,TYPES type,int value)  //向符号表中填入信息要用的函数
{
	TX++;
	strcpy(NAMETAB[TX].name,name);
	NAMETAB[TX].link=TX-1;
	NAMETAB[TX].kind=kind;
	NAMETAB[TX].type=type;
	NAMETAB[TX].ref=0;
	NAMETAB[TX].normal=1;
	NAMETAB[TX].level=0;
	switch(kind)
	{
	case VARIABLE:
	case PROCEDURE:
		NAMETAB[TX].unite.address=value;break;
	case KONSTANT:
		NAMETAB[TX].unite.value=value;break;
	case TYPEL:
		NAMETAB[TX].unite.size=value;break;
	}
	return;
}

void ENTERPREID()  //预先填入符号表的信息,将这些信息作为“过程零”里面的数据
{

⌨️ 快捷键说明

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