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

📄 pl.cpp

📁 这是我们的一个上机题,做词法分析和语法的,希望对大家的学习有所帮助
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	ENTERID("",VARIABLE,NOTYP,0);
	ENTERID("char",TYPEL,CHARS,1);
	ENTERID("integer",TYPEL,INTS,1);
	ENTERID("boolean",TYPEL,BOOLS,1);
	ENTERID("false",KONSTANT,BOOLS,0);
	ENTERID("true",KONSTANT,BOOLS,1);
	ENTERID("read",PROCEDURE,NOTYP,1);
	ENTERID("write",PROCEDURE,NOTYP,2);

	BTAB[0].last=TX;
	BTAB[0].lastPar=1;
	BTAB[0].pSize=0;
	BTAB[0].vSize=0;
}

void ASSIGNMENT(SYMLIST * list)  //分析赋值语句
{
	TYPEITEM typeItem1,typeItem2;
	int i;

	i=GETPOSITION(CurSymbol->value.lpValue);
	if(i==0)
		error(33);  //标识符没有定义
	else
	{
		if (NAMETAB[i].kind!=VARIABLE)  //':='左边应该是变量
		{
			error(16);  //应该是变量
            i=0;
		}
        getASymbol();
        typeItem1.typ=NAMETAB[i].type;
        typeItem1.ref=NAMETAB[i].ref;
        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)  //如果当前标识符是左大括号,那么正在为一个数组的元素赋值
		{
			//////////////////////////////////////////////////////////
			SYMLIST * tempList=new SYMLIST;
			COPYLIST(tempList,listAddSym(list,BECOMES));
            ARRAYELEMENT(tempList,typeItem1);  //获得此数组元素的信息
			delete tempList;
            //////////////////////////////////////////////////////////
		}
			
		if(CurSymbol->type==BECOMES)
			getASymbol();
		else
		{
			error(7);  //应该是':='
            if(CurSymbol->type==EQL)
				getASymbol();
		}
		EXPRESSION(list,typeItem2);  //':='右边是表达式
		if(typeItem1.typ!=typeItem2.typ)
			error(37);//类型不一致
		else
		{
			if(typeItem1.typ==ARRAYS)
			{
				if(typeItem1.ref==typeItem2.ref)
					GEN(CPYB,0,ATAB[typeItem1.ref].size);
				else
					error(35);//操作数类型出错
			}
			else
				GEN(STO,0,0);
		}
	}
	Temporary_i=i;
}


void IFSTATEMENT(SYMLIST * list)  //分析if语句
{
	TYPEITEM typeItem;
	int fillBackFalse,fillBackTrue;

	getASymbol();
	
	/////////////////////////////////////////////////////////////////
	SYMLIST * tempList=new SYMLIST;
	COPYLIST(tempList,listAddSym(listAddSym(list,DOSYM),THENSYM));
	EXPRESSION(tempList,typeItem);  //获取布尔表达式的信息
	delete tempList;
	/////////////////////////////////////////////////////////////////

	if(typeItem.typ!=BOOLS)
		error(32);  //if或while后面的表达式类型必须为布尔类型
	if(CurSymbol->type==THENSYM)
		getASymbol();
	else 
		error(11);  //应该是'then'

	fillBackFalse=CX;  //回填
	GEN(JPC,0,0);

	/////////////////////////////////////////////////////////////////
	SYMLIST * tempList1=new SYMLIST;
	COPYLIST(tempList1,listAddSym(list,ELSESYM));
	STATEMENT(tempList1);  //语句分析
	delete tempList1;
	/////////////////////////////////////////////////////////////////

	if(CurSymbol->type==ELSESYM)
	{
		getASymbol();
		fillBackTrue=CX;  //回填
		GEN(JMP,0,0);
		CODE[fillBackFalse].address=CX;
		JUMADRTAB[JX]=CX;
		JX++;
		STATEMENT(list);
		CODE[fillBackTrue].address=CX;
		JUMADRTAB[JX]=CX;
		JX++;
	}
	else
	{
		CODE[fillBackFalse].address=CX;
		JUMADRTAB[JX]=CX;
		JX++;
	}
}


void WHILESTATEMENT(SYMLIST * list)  //while 语句的分析
{
	TYPEITEM typeItem;
	int jumpback,fillBackFalse;

	getASymbol();
	JUMADRTAB[JX]=CX;
	JX++;
	jumpback=CX;  //记录while循环执行时需要往前返回的地址

	/////////////////////////////////////////////////////////////////
	SYMLIST * tempList=new SYMLIST;
	COPYLIST(tempList,listAddSym(list,DOSYM));
	EXPRESSION(tempList,typeItem);
	delete tempList;
	/////////////////////////////////////////////////////////////////

	if(typeItem.typ!=BOOLS)
		error(32);  //if或while后面的表达式类型应该是布尔类型
	fillBackFalse=CX;  //条件测试失败后从哪里往循环“外”跳
	GEN(JPC,0,0);
	if(CurSymbol->type==DOSYM)
		getASymbol();
	else
		error(9);//应该是'do'

	STATEMENT(list);  //分析语句
	GEN(JMP,0,jumpback);
	CODE[fillBackFalse].address=CX;  //回填
	JUMADRTAB[JX]=CX;
	JX++;
}

void COMPOUND(SYMLIST * list)  //begin 开头的组合语句的分析
{
	getASymbol();

    ////////////////////////////////////////////////////////////
	SYMLIST * tempList=new SYMLIST;
	COPYLIST(tempList,listAddSym(listAddSym(list,ENDSYM),SEMICOLON));
	STATEMENT(tempList);
	
	////////////////////////////////////////////////////////////
	SYMLIST * tempList1=new SYMLIST;
	COPYLIST(tempList1,listAddSym(&STATBEGSYS,SEMICOLON));
	///////////////////////////////////////////////////////////

	while(SYMINLIST(CurSymbol->type,tempList1))  //一条条的分析语句
	{
		if(CurSymbol->type==SEMICOLON)
			getASymbol();
		else
			error(1);//应该是';'
	    STATEMENT(tempList);  
	}
	if(CurSymbol->type==ENDSYM)
		getASymbol();
	else
		error(12);  //应该是'end'
	delete tempList;delete tempList1;
}

//*********************************************************                   @@@@@@

void FORSTATEMENT(SYMLIST * list)       //for语句分析
{
	TYPEITEM typeItem;
	int jumpBack,fillBackFalse;

	getASymbol();

	//////////////////////////////////////////////////////
	SYMLIST * tempList=new SYMLIST;
	COPYLIST(tempList,listAddSym(listAddSym(list,TOSYM),DOSYM));
	////////////////////////////////////////////////////////////

	ASSIGNMENT(list);				//compile -- i:=n
	int i=Temporary_i;

	if(CurSymbol->type==TOSYM)			//it should be "to"
		getASymbol();
	else
		error(44);						

	jumpBack=CX;						//jump table -- record for_begin_lab
	JUMADRTAB[JX]=CX;
	JX++;

	GEN(LOD,NAMETAB[i].level,NAMETAB[i].unite.address);//push i to stack

	EXPRESSION(list,typeItem);			//compile(expression) -- m
										//        and  push m to stack

	if(typeItem.typ != INTS)
		error(45);          			//m should be integer

	GEN(LE,0,0);						//compare n to m

	fillBackFalse=CX;					//backfill flag

	GEN(JPC,0,0);						//true:execute in sequence
										//false:jump to for_end_lab (to be filled)

	if(CurSymbol->type==DOSYM)
		getASymbol();

	STATEMENT(tempList);				//compile statement

	GEN(LODA,NAMETAB[i].level,NAMETAB[i].unite.address);//push the address of i to stack
	GEN(LOD,NAMETAB[i].level,NAMETAB[i].unite.address); //push the value of i to stack
	GEN(LIT,0,1);									    //push 1 to stack
	GEN(ADD,0,0);										//i
	GEN(STO,0,0);										//i+1 --> (i)
	GEN(JMP,0,jumpBack);								//jump to for_begin_lab

	CODE[fillBackFalse].address=CX;    //backfill for_end_lab
	JUMADRTAB[JX]=CX;					//jump table -- record for_end_lab
	JX++;

	delete tempList;

}

void REPEATSTATEMENT(SYMLIST * list)   //repeat语句分析                   @@@@@@
{
	TYPEITEM typeItem;	
	int jumpback;

	getASymbol();		//获取下一个符号

	JUMADRTAB[JX]=CX;	//将当前指令数填入跳转表 CX指令数组索引
	JX++;				//跳转表索引增1 JX跳转表索引

	jumpback=CX;		//记录repeat循环的跳转点 

	//*************************************************************
	SYMLIST * tempList=new SYMLIST;
	COPYLIST(tempList,listAddSym(list,UNTILSYM));

	STATEMENT(tempList);			//分析语句
	//*************************************************************

	if(CurSymbol->type==UNTILSYM)	//应该是"until"
		getASymbol();
	else
		error(44);					

	EXPRESSION(tempList,typeItem);	////获取布尔表达式的信息

	delete tempList;

	if(typeItem.typ!=BOOLS)			//until后面的表达式类型必须为布尔类型
		error(45);					

	GEN(JPC,0,jumpback);			//产生代码: 栈顶值为0时转移至jumpback处


}

// function : compile the case statement
// annotation -- syntax of case :
// case  e    -- e must be integer expression or char variable
// c1 : statement 
// c2 : statement 
//       ...
// cn : statement 
// end;

// the code format:
//# recognize <case>                                    
//# calculate expression "e"
//# jump to lab_test							
//# lab1:		s1 ;		jump to lab_end
//# lab2:		s2 ;		jump to lab_end
//# ....
//# ....
//# labn:		sn ;		jump to lab_end
//# lab_test:
//# e == c1  ?  jump to lab1 : execute in sequence
//# e == c2  ?  jump to lab2 : execute in sequence
//# ...
//# e == cn  ?  jump to labn : execute in sequence
//# lab_end : ...

void CASESTATEMENT(SYMLIST * list)
{
	TYPEITEM typeItem;
	int i,needJumpTest;

	IntVector PosVector;						//record the position(in fact,value) of ci(c1,c2,...,cn)
	IntVector L;								//record the value of labi(lab1,lab2,...,labn)
	IntVector NeedJumpEndVector;				//record the position that need fillback lab_end

	getASymbol();

	FirstIn=1;
	EXPRESSION(list,typeItem);					//analyse "e"
	i=Temporary_i;								//i record position of "e" in name table

	if(typeItem.typ != INTS)
		error(46);								//case之后的条件表达式必须是整形的结果

	needJumpTest=CX;							//record the code position to be fillbacked by lab_test
	GEN(JMP,0,0);								//jump to lab_test

	while (CurSymbol->type==INTCON)
	{
		EXPRESSION(list,typeItem);				//analyse "ci"
		PosVector.push_back(Temporary_i);
		L.push_back(CX);

		JUMADRTAB[JX]=CX;						//labi --> jump table
		JX++;

		if (typeItem.typ!=INTS)
			error(47);							//case之后的分支表达式必须是整形的结果

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

		STATEMENT(list);						//analyse "si"

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

		NeedJumpEndVector.push_back(CX);
		GEN(JMP,0,0);						    //jump to lab_end
	}

	CODE[needJumpTest].address=CX;				//fillback lab_test

	JUMADRTAB[JX]=CX;							//lab_test --> jump table
	JX++;


	for(int k=0;k<L.size();k++)
	{
		GEN(LIT, 0,PosVector[k]);//push the value of e into stack
		GEN(LOD, NAMETAB[i].level,NAMETAB[i].unite.address);//push the value of e into stack
		GEN(NE,0,0);										// ci != e?????
		GEN(JPC,0,L[k]);		// ci != e ? jump to labi : execute in sequence
	}

	for(k=0;k<L.size();k++)
		CODE[NeedJumpEndVector[k]].address=CX;	//fillback lab_end
	
	if (CurSymbol->type!=ENDSYM)				
		error(12);								//应该为 "end"
	else
		getASymbol();

}

//***********************************************************

void STANDPROC(SYMLIST * list,int i)  //两个基本过程read和write的调用,他们在符号表里面分别在第六项和第七项
{
	int helper;
	TYPEITEM typeItem;

	if(i==6)//如果是第六项,read();
	{
		getASymbol();
		if(CurSymbol->type==LPAREN)
		{
			do
			{
				getASymbol();
				if(CurSymbol->type==IDENT)
				{
					helper=GETPOSITION(CurSymbol->value.lpValue);
					getASymbol();
					if(helper==0)
					{
						error(33);//标识符没有定义
					}
					else
					{
						if(NAMETAB[helper].kind!=VARIABLE)
						{
							error(16);//应该是变量
							helper=0;
						}
						else
						{
							typeItem.typ=NAMETAB[helper].type;
							typeItem.ref=NAMETAB[helper].ref;

							if(NAMETAB[helper].normal)
								GEN(LODA,NAMETAB[helper].level,NAMETAB[helper].unite.address);
							else
								GEN(LOD,NAMETAB[helper].level,NAMETAB[helper].unite.address);
							if(CurSymbol->type==LBRACK)
							{
								//////////////////////////////////////////////////////
								SYMLIST * tempList1=new SYMLIST;
								COPYLIST(tempList1,listAddSym(list,COMMA));
								ARRAYELEMENT(tempList1,typeItem);
								delete tempList1;
								//////////////////////////////////////////////////////
							}
							if(typeItem.typ==INTS)
								GEN(RED,0,0);
							else if(typeItem.typ==CHARS)
								GEN(RED,0,1);
							else
								error(35);//操作数类型错误
						}
					}
				}
				else
					error(14);//应该是标识符
			}while(CurSymbol->type==COMMA);

			if(CurSymbol->type!=RPAREN)
			{	
				error(2);//应该是')'
			}
			else 
				getASymbol();
		}
		else
			error(3);//应该是'('
	}
	else if(i==7)//如果是第七项,write();
	{
		getASymbol();
		if(CurSymbol->type==LPAREN)
		{
			do
			{
				getASymbol();
				///////////////////////////////////////////////////////
				SYMLIST * tempList=new SYMLIST;
				COPYLIST(tempList,listAddSym(listAddSym(list,RPAREN),COMMA));
				EXPRESSION(tempList,typeItem);
				delete tempList;
				////////////////////////////////////////////////////////
				
				if(typeItem.typ==INTS)
					GEN(WRT,0,0);
				else if(typeItem.typ==CHARS)
					GEN(WRT,0,1);
				else
					error(35);//操作数类型出错
			}
			while(CurSymbol->type==COMMA);
			
			if(CurSymbol->type!=RPAREN)
				error(2);//应该是')'
			else
				getASymbol();
		}
		else
			error(3);//应该是'('
	}
}

void CALL(SYMLIST * list)  //调用语句的分析
{
	int i,lastPar,cp,k;
	TYPEITEM typeItem;

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

	getASymbol();
	if(CurSymbol->type==IDENT)
	{
		i=GETPOSITION(CurSymbol->value.lpValue);
		if(NAMETAB[i].kind==PROCEDURE)
		{
			if(NAMETAB[i].level==0)  //如果在“过程零”,那么必定是read 或者 write
				STANDPROC(list,i);
			else
			{
				getASymbol();
				GEN(OPAC,0,0);//打开活动记录
				lastPar=BTAB[NAMETAB[i].ref].lastPar;
				cp=i;
				if(CurSymbol->type==LPAREN)
				{//实在参数列表
					/////////////////////////////////////////////////////////
					SYMLIST * tempList1=new SYMLIST;
					COPYLIST(tempList1,listAddSym(listAddSym(listAddSym(list,RPAREN),COLON),COMMA));					
					/////////////////////////////////////////////////////////
					do
					{
						getASymbol();
						if(cp>=lastPar)
							error(28);//实参与形参个数不等
						else
						{
							cp++;
							if(NAMETAB[cp].normal)
							{//值参数

								EXPRESSION(tempList1,typeItem);
								if(typeItem.typ==NAMETAB[cp].type)
								{
									if(typeItem.ref!=NAMETAB[cp].ref)
										error(29);//实参与形参类型不一致
									else if(typeItem.typ==ARRAYS)
										GEN(LODB,0,ATAB[typeItem.ref].size);
								}
								else
									error(29);//实参与形参类型不一致
							}

⌨️ 快捷键说明

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