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

📄 pl.cpp

📁 编译原理的教程和一个实习的例子程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	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);

	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()  //预先填入符号表的信息,将这些信息作为“过程零”里面的数据
{
	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);
		}
	}
}


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 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);//实参与形参类型不一致
							}
							else
							{//形式参数
								if(CurSymbol->type!=IDENT)
									error(14);//应该是标识符
								else
								{
									k=GETPOSITION(CurSymbol->value.lpValue);
									getASymbol();
									if(k!=0)
									{
										if(NAMETAB[k].kind!=VARIABLE)
											error(16);//应该是变量
										typeItem.typ=NAMETAB[k].type;
										typeItem.ref=NAMETAB[k].ref;
										if(NAMETAB[k].normal)
											GEN(LODA,NAMETAB[k].level,NAMETAB[k].unite.address);
										else
											GEN(LOD,NAMETAB[k].level,NAMETAB[k].unite.address);
										if(CurSymbol->type==LBRACK)
										{   
											ARRAYELEMENT(tempList,typeItem);
										}
										if(NAMETAB[cp].type!=typeItem.typ || NAMETAB[cp].ref!=typeItem.ref)
											error(29);//实参与形参类型不一致
									}
								}
							}
						}
					}
					while(CurSymbol->type==COMMA);
					delete tempList1;
					if(CurSymbol->type==RPAREN)
						getASymbol();
					else
						error(2);//应该是')'
				}
				if(cp<lastPar)
					error(30);//实在参数个数不够
				GEN(CAL,NAMETAB[i].level,NAMETAB[i].unite.address);
				if(NAMETAB[i].level<displayLevel)
					GEN(UDIS,NAMETAB[i].level,displayLevel);
			}
		}
		else
			error(18);//应该是过程名
	}
	else

⌨️ 快捷键说明

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