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

📄 semantic.cpp

📁 PL语言到中间代码的编译程序
💻 CPP
字号:
#include "common.h"

NametabItem *LastName;
ObjItem *ProgramBlock();
void Expression();
void Sentences();
void Factor();

void GotoNextSymbol()
{
	if(CurSymbol->Next)
		CurSymbol=CurSymbol->Next;
	else
	{
		Error(4);
		exit(3);
	}
}

void ArrayItemAddress(NametabItem *array)
{	//数组元素地址的计算代码
	int dimension[MAXDIMENSION*2],i=0;
	ArrayItem *array_info=(ArrayItem *)array->Ref;

	if(!array_info)
	{
		Error(13);
		return;
	}
	for(;array_info;array_info=array_info->Elref)
	{
		dimension[i++]=array_info->Size; 
		dimension[i++]=array_info->Low;
	}
	GotoNextSymbol();
	if(CurSymbol->Type!=LPAREN)
		Error(22);
	else
		GotoNextSymbol();
	Factor();	
	if(dimension[--i])
	{
		GenerateCode(LIT,0,dimension[i]);
		GenerateCode(SUB,0,0);	//减去下界值
	}
	while(CurSymbol->Type==COMMA)
	{
		GotoNextSymbol();
		GenerateCode(LIT,0,dimension[--i]);
		GenerateCode(MULT,0,0);  //乘某一维的长度
		Factor();
		if(dimension[--i])
		{
			GenerateCode(LIT,0,dimension[i]);
			GenerateCode(SUB,0,0);
		}
		GenerateCode(ADD,0,0);
	}
	if(CurSymbol->Type!=RPAREN)
		Error(22);
	else
		GotoNextSymbol();
	GenerateCode(LODA,array->Level,array->Value);
	GenerateCode(ADD,0,0);	//准备变址寻址
	return;
}

#include "declaration.cpp"
#include "expression.cpp"

void AssignmentSentence()
{	//赋值语句
	char *lvar_name;	//赋值号左边的变量名
	NametabItem *lvar;

	assert(CurSymbol->Type==IDENT);
	lvar_name=CurSymbol->Value.lpValue;  
	lvar=FindLowLevelNametabItem(lvar_name,VARIABLE);
	if(!lvar)
		Error(11);
	if(lvar->Type!=TARRAY) 
	{
		if(lvar->Normal>=0)  
			GenerateCode(LODA,lvar->Level,lvar->Value);
		else
			GenerateCode(LOD,lvar->Level,lvar->Value);
		GotoNextSymbol();
	}
	else
		ArrayItemAddress(lvar);

	if(CurSymbol->Type!=BECOME)
		Error(23);
	GotoNextSymbol();
	Expression();   //表达式处理
	GenerateCode(STO,0,0);
}

void IfStatement()
{
	ObjItem *fillback_true,*fillback_false;

	assert(CurSymbol->Type==IFSYM);
	GotoNextSymbol();
	Expression();
	if(CurSymbol->Type!=THENSYM)
		Error(25);
	fillback_false=GenerateCode(JPC,0,0);
	GotoNextSymbol();
	Sentences();
	if(CurSymbol->Type==ELSESYM)
	{
		fillback_true=GenerateCode(JMP,0,0);
		fillback_false->DestOp.iValue=CurrentCode->LineNum; 
		GotoNextSymbol();
		Sentences();
		fillback_true->DestOp.iValue=CurrentCode->LineNum; 
	}
	else
	{
		fillback_true=NULL;
		fillback_false->DestOp.iValue=CurrentCode->LineNum; 
	}
}

void WhileStatement()
{
	ObjItem *jmp_back,*fillback_false;
	assert(CurSymbol->Type==WHILESYM);
	GotoNextSymbol();
	jmp_back=CurrentCode;
	Expression();
	fillback_false=GenerateCode(JPC,0,0);
	if(CurSymbol->Type!=DOSYM)
		Error(26);
	GotoNextSymbol();
	Sentences();
	GenerateCode(JMP,0,jmp_back->LineNum);
	fillback_false->DestOp.iValue=CurrentCode->LineNum;  
}

void CompoundSentences()
{
	assert(CurSymbol->Type==BEGINSYM);
	GotoNextSymbol();
	Sentences();
	while(CurSymbol->Type==SEMICOLON)
	{
		GotoNextSymbol();
		Sentences();
	}
	if(CurSymbol->Type!=ENDSYM)
		Error(9);
	GotoNextSymbol();
}

void StandardProcedure(char *proc_name)
{
	int instruction;
	NametabItem *variable;

	if(!stricmp(proc_name,"READ"))
	{
		instruction=RED;
	}
	if(!stricmp(proc_name,"WRITE"))
	{
		instruction=WRT;
	}
	if(CurSymbol->Type==LPAREN)
	{
		GotoNextSymbol();
		if(CurSymbol->Type!=IDENT || !(variable=FindLowLevelNametabItem(CurSymbol->Value.lpValue,VARIABLE)))
			Error(28);
		if(variable->Normal>=0) 
			GenerateCode(LODA,variable->Level,variable->Value);
		else
			GenerateCode(LOD,variable->Level,variable->Value);

		GenerateCode(instruction,0,variable->Type==TINT?0:1); 
		GotoNextSymbol();
		while(CurSymbol->Type==COMMA)
		{
			GotoNextSymbol();
			if(CurSymbol->Type!=IDENT || !(variable=FindLowLevelNametabItem(CurSymbol->Value.lpValue,VARIABLE)))
				Error(28);

			if(variable->Normal>=0) 
				GenerateCode(LODA,variable->Level,variable->Value);
			else
				GenerateCode(LOD,variable->Level,variable->Value);			GenerateCode(instruction,0,variable->Type==TINT?0:1); 
			GotoNextSymbol();
		}
	}
	if(CurSymbol->Type!=RPAREN)
		Error(22);
	GotoNextSymbol();
}

void CallStatement()
{
	char *proc_name;
	NametabItem *procedure,*var_para;
	int var_define[MAXVARNUMBER],i;
	NametabItem *para;

	assert(CurSymbol->Type==CALLSYM);
	GotoNextSymbol();
	proc_name=CurSymbol->Value.lpValue;
	procedure=FindLowLevelNametabItem(proc_name,PROCEDURE);
	if(!procedure)
		Error(21);
	GotoNextSymbol();
	if(!procedure->Level)
	{
		StandardProcedure(proc_name);
		return;
	}
	for(para=((BlockItem *)(procedure->Ref))->LastPar,i=0;para;para=para->Link,i++)
		var_define[i]=((para->Normal)==-1?1:0);
	GenerateCode(OPAC,0,0);
	if(CurSymbol->Type==LPAREN)
	{
		GotoNextSymbol();
		if(i<=0)
			Error(27);
		if(var_define[--i])
		{
			if(CurSymbol->Type!=IDENT)
				Error(28);
			var_para=FindLowLevelNametabItem(CurSymbol->Value.lpValue,VARIABLE);  
			if(!var_para)
				Error(28);
			if(var_para->Type!=TARRAY)
			{
				if(var_para->Normal>=0) 
					GenerateCode(LODA,var_para->Level,var_para->Value);
				else
					GenerateCode(LOD,var_para->Level,var_para->Value);

				GotoNextSymbol();
			}
			else
				ArrayItemAddress(var_para);
		}
		else
			Expression();
		while(CurSymbol->Type==COMMA)
		{
			GotoNextSymbol();
			if(i<=0)
				Error(27);
			if(var_define[--i])
			{
				if(CurSymbol->Type!=IDENT)
					Error(28);
				var_para=FindLowLevelNametabItem(CurSymbol->Value.lpValue,VARIABLE);  
				if(!var_para)
					Error(28);
				if(var_para->Type!=TARRAY)
				{
					if(var_para->Normal>=0)
						GenerateCode(LODA,var_para->Level,var_para->Value);  
					else
						GenerateCode(LOD,var_para->Level,var_para->Value);  
					GotoNextSymbol();
				}
				else
					ArrayItemAddress(var_para);
			}
			else
				Expression();
		}
		if(i)
			Error(27);
	}
	if(CurSymbol->Type!=RPAREN)
		Error(22);
	GotoNextSymbol();
	GenerateCode(CAL,procedure->Level,procedure->Value);
	if(DisplayLevel-1>procedure->Level)
		GenerateCode(UDIS,procedure->Level,DisplayLevel-1);
}

void Sentences()
{	//语句处理
	switch(CurSymbol->Type)
	{
	case IDENT:		//赋值语句
		AssignmentSentence();
		break;
	case IFSYM:		//条件语句if
		IfStatement();
		break;
	case WHILESYM:	//循环语句while
		WhileStatement();
		break;
	case BEGINSYM:	//复合语句
		CompoundSentences();
		break;
	case CALLSYM:	//过程调用语句
		CallStatement();
		break;
	default:	//空语句
		return;
	}
}

void Program()
{
	ObjItem *fill_back_var_size;

	LastName=NULL;
	if(CurSymbol->Type!=PROGRAMSYM)
		Error(3);
	GotoNextSymbol();
	if(CurSymbol->Type!=IDENT)
		Error(5);
	GotoNextSymbol();
	if(CurSymbol->Type!=SEMICOLON)
		Error(6);
	GotoNextSymbol();
	EnterBlock();
	fill_back_var_size=GenerateCode(ENTP,1,0);
	ProgramBlock();
	fill_back_var_size->DestOp.iValue=Display[1]->PSize+Display[1]->VSize;
	QuitBlock();
	GenerateCode(ENDP,0,0);
	if(CurSymbol->Type!=PERIOD)
		Error(10);
}

ObjItem *ProgramBlock()
{	//程序体
	ObjItem *fillback;
	
	fillback=GenerateCode(JMP,0,0);
	if(CurSymbol->Type==CONSTSYM)
	{
		GotoNextSymbol();
		while(CurSymbol->Type==IDENT)
		{
			//常量说明
			ConstDeclaration();
		}
	}
	if(CurSymbol->Type==TYPESYM)
	{
		GotoNextSymbol();
		while(CurSymbol->Type==IDENT)
		{
			//类型说明
			TypeDeclaration();
		}
	}
	if(CurSymbol->Type==VARSYM)
	{
		GotoNextSymbol();
		while(CurSymbol->Type==IDENT)
		{
			//变量说明
			VarDeclaration();
		}
	}

	while(CurSymbol->Type==PROCSYM)
	{	//过程说明
		ProcedureDeclaration();
	}

	if(CurSymbol->Type==BEGINSYM)
	{
		fillback->DestOp.iValue=CurrentCode->LineNum; 
		do
		{
			GotoNextSymbol();
			//语句处理
			Sentences();
		}
		while(CurSymbol->Type==SEMICOLON);

		if(CurSymbol->Type==ENDSYM)	
		{
			GotoNextSymbol();
			return fillback;
		}
		else
			Error(9);
	}
	else
		Error(8);
	return fillback;
}

⌨️ 快捷键说明

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