expressanalysis.h

来自「一个pascal子集编译器。输入pascal原程序」· C头文件 代码 · 共 911 行 · 第 1/2 页

H
911
字号
	}

	int GetCondecl()
	{	//Condecl的规约 <condecl>→const <const>{,<const>};
		int go;
		do
		{
			if(FALSE==GetConst()) return FALSE;//分析const
			if(FALSE==Match(tempword,SIGN_COMMA,SIGN_SEMI)) return FALSE;
			if(tempword.type==SIGN_COMMA) go=1;//如果遇到“,”,继续分析const
			else go=0;
			tempword=was.GetOneWord();
		}while(1==go);
		return TRUE;
	}

	int Getvardecl()
	{	//vardecl的规约 <vardecl>→var <id>{,<id>};
		int go;
		do
		{
			if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;
			tempaddfh.type=FH_VAR;
			strcpy(tempaddfh.mgc,tempmhs);
			AddFh(tempword.data,tempaddfh);//往符号表里添加该变量
			GenCode("INT",0,1);//活动记录指针向上移一个单位,给变量分配空间
			tempword=was.GetOneWord();
			if(FALSE==Match(tempword,SIGN_COMMA,SIGN_SEMI)) return FALSE;
			if(tempword.type==SIGN_COMMA) go=1;//如果遇到“,”,继续分析标示符
			else go=0;
			tempword=was.GetOneWord();
		}while(1==go);
		return TRUE;
	}

	int GetProc()
	{	//Proc的规约  <proc>→procedure <id>(<id>{,<id>});<block>{;<proc>}
		char thismhs[L2MAX];
		int go;
		if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;//过程名必须是标示符
		tempaddfh.type=FH_PRONAME;
		strcpy(thismhs,tempmhs);
		strcpy(tempaddfh.mgc,thismhs);
		AddFh(tempword.data,tempaddfh);//往符号表里添加该过程
		strcpy(tempmhs,tempword.data);
		GenCode("INT",0,3);//活动记录指针向上移3,给新过程的返回地址、静态链、动态链开辟空间
		tempword=was.GetOneWord();
		if(strcmp("(",tempword.data)==0)
		{
			do
			{
			tempword=was.GetOneWord();

			if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;//形参名必须是标示符
			tempaddfh.type=FH_XC;
			strcpy(tempaddfh.mgc,tempmhs);
			AddFh(tempword.data,tempaddfh);//往符号表里添加该形参
			GenCode("INT",0,1);//留出位置给形参
			tempword=was.GetOneWord();
			if(FALSE==Match(tempword,SIGN_RIGHTBRA,SIGN_COMMA)) return FALSE;
			if(tempword.type==SIGN_COMMA) go=1;//如果形参后面接",",还需要继续分析形参
			else go=0;
			}
			while(1==go);
			tempword=was.GetOneWord();
		}
		if(FALSE==Match(tempword,SIGN_SEMI)) return FALSE;
		tempword=was.GetOneWord();
		if(FALSE==GetBlock()) return FALSE;
		GenCode("OPR",0,OP_RETURN);//过程结束后要返回到被调用函数
		if(tempword.type==SIGN_PROCEDURE) 
		{	//如果接下去有同一层的其他过程
			tempword=was.GetOneWord();
			strcpy(tempmhs,thismhs);
			if(FALSE==GetProc()) return FALSE;
		}
		return TRUE;
	}

	int GetBlock()
	{	//Block的规约  <block>→[<condecl>][<vardecl>][<proc>]<body>
		char savemhs[L2MAX];
		int t;

		strcpy(savemhs,tempmhs);
		if(tempword.type==SIGN_CONST)
		{	//分析condecl
			tempword=was.GetOneWord();
			if(FALSE==GetCondecl()) return FALSE;
		}
		if(tempword.type==SIGN_VAR)
		{	//分析vardecl
			tempword=was.GetOneWord();
			if(FALSE==Getvardecl()) return FALSE;
		}
		if(tempword.type==SIGN_PROCEDURE)
		{	//分析proc
			GenCode("JMP",0,0);
			t=codenum-1;
			tempword=was.GetOneWord();
			if(FALSE==GetProc()) return FALSE;
			Backpatch(t,codenum);
		}
		strcpy(tempmhs,savemhs);
		if(GetBody()==FALSE) return FALSE;//分析body
		else return TRUE;
	}

	int GetBody()
	{	//Body的规约  <body>→begin <statement>{;<statement>} end
		if(FALSE==Match(tempword,SIGN_BEGIN)) return FALSE;
		tempword=was.GetOneWord();
		if(FALSE==GetStatement()) return FALSE;
		if(FALSE==Match(tempword,SIGN_END,SIGN_SEMI)) return FALSE;
		while(tempword.type!=SIGN_END)
		{//如果statement后面不是end,继续分析statement
			tempword=was.GetOneWord();
			if(FALSE==GetStatement()) return FALSE;//分析statement
			if(FALSE==Match(tempword,SIGN_END,SIGN_SEMI)) return FALSE;
		}
		if(FALSE==Match(tempword,SIGN_END)) return FALSE;
		tempword=was.GetOneWord();
		return TRUE;
	}

	int GetFactor()
	{	//Factor的规约  <factor>→<id>|<integer>|(<exp>)
		switch(tempword.type)
		{
		case SIGN_INTEGER://如果是整数
			GenCode("LIT",0,atoi(tempword.data));//将常量取到栈顶
			tempword=was.GetOneWord();
			break;
		case SIGN_NAME://如果是标示符
			//从符号表里查找标示符的类型
			if(FindFh(tempword.data,tempmhs,&tempfindfh)==FALSE) return FALSE;
			if(tempfindfh.type==FH_CONST)
			{//标示符代表常量
				GenCode("LIT",0,tempfindfh.value);//将常量取到栈顶
			}
			else if(tempfindfh.type==FH_VAR || tempfindfh.type==FH_XC)
			{//标示符代表变量或形参
				GenCode("LOD",tempfindfh.depth,tempfindfh.address);//将变量取到栈顶
			}
			else if(tempfindfh.type==FH_PRONAME)
			{//标示符代表过程,出错
				sprintf(error,"第%d行 不能为过程名",tempword.line);
				return FALSE;
			}
			tempword=was.GetOneWord();
			break;
		case SIGN_LEFTBRA://如果是"(",递归地分析Exp
			tempword=was.GetOneWord();
			GetExp();
			if(FALSE==Match(tempword,SIGN_RIGHTBRA)) return FALSE;
			tempword=was.GetOneWord();
			break;
		default:
			break;
		}
		return TRUE;
	}

	int GetTerm()
	{	//Term的规约  <term>→<factor>{<mop><factor>}
		char optemp[L2MAX];
		if(FALSE==GetFactor()) return FALSE;
		if(tempword.type==SIGN_MULTIPLY || tempword.type==SIGN_DEVIDE)
		{//如果接的是mop
			while(tempword.type==SIGN_MULTIPLY || tempword.type==SIGN_DEVIDE)
			{
				strcpy(optemp,tempword.data);
				tempword=was.GetOneWord();
				if(FALSE==GetFactor()) return FALSE;//递归地分析Factor
				if(strcmp(optemp,"*")==0)
					GenCode("OPR",0,OP_MUL);
				else
					GenCode("OPR",0,OP_DIV);
			}
		}
		return TRUE;
	}

	int GetExp()
	{	//Exp的规约   <exp>→[+|-]<term>{<aop><term>}
		char optemp[L2MAX];
		int t=0;
		if(tempword.type==SIGN_ADD || tempword.type==SIGN_SUBTRACT)
		{	//如果前面有+或-
			if(tempword.type==SIGN_SUBTRACT) t=1;
			tempword=was.GetOneWord();
		}
		if(FALSE==GetTerm()) return FALSE;
		if(1==t) GenCode("OPR",0,OP_NOT);//如果是-,要做取反操作
		if(tempword.type==SIGN_ADD || tempword.type==SIGN_SUBTRACT)
		{//如果接的是aop
			while(tempword.type==SIGN_ADD || tempword.type==SIGN_SUBTRACT)
			{
				strcpy(optemp,tempword.data);
				tempword=was.GetOneWord();
				if(FALSE==GetTerm()) return FALSE;//递归地分析Term
				if(strcmp(optemp,"+")==0)
					GenCode("OPR",0,OP_ADD);
				else
					GenCode("OPR",0,OP_SUB);
			}
		}
		return TRUE;
	}

	int GetCondition(int *acgo,int *wago)
	{	//Condition的规约 <lexp>→<exp><lop><exp>|odd<exp>
		if(tempword.type==SIGN_ODD)
		{
			tempword=was.GetOneWord();
			if(FALSE==GetExp()) return FALSE;
			GenCode("OPR",0,OP_ODD);
		}
		else 
		{
			if(FALSE==GetExp()) return FALSE;
			switch(tempword.type)
			{
			case SIGN_EQUAL:
				{// =
				tempword=was.GetOneWord();
				if(FALSE==GetExp()) return FALSE;
				GenCode("OPR",0,OP_EQUAL);
				break;
				}
			case SIGN_LESS:
				{// <
					tempword=was.GetOneWord();
					if(FALSE==GetExp()) return FALSE;
					GenCode("OPR",0,OP_LESS);
					break;
				}
			case SIGN_LESSEQUAL:
				{// <=
					tempword=was.GetOneWord();
					if(FALSE==GetExp()) return FALSE;
					GenCode("OPR",0,OP_LESSQ);
					break;
				}
			case SIGN_MORE:
				{// >
					tempword=was.GetOneWord();
					if(FALSE==GetExp()) return FALSE;
					GenCode("OPR",0,OP_MORE);
					break;
				}
			case SIGN_MOREEQUAL:
				{// >=
					tempword=was.GetOneWord();
					if(FALSE==GetExp()) return FALSE;
					GenCode("OPR",0,OP_MOREQ);
					break;
				}
			case SIGN_NOTEQUAL:
				{// <>
					tempword=was.GetOneWord();
					if(FALSE==GetExp()) return FALSE;
					GenCode("OPR",0,OP_NOEQUAL);
					break;
				}
			default:
				{
					return FALSE;
					break;
				}
			}
		}
		*acgo=codenum;//acgo表示条件符合时的链头
		*wago=codenum+1;//wago表示条件不符合时的链头
		GenCode("JPC",0,0);//条件跳转,如果条件为真,跳到目标指令
		GenCode("JMP",0,0);//无条件跳转,当前一句指令JPC不做时(也就是条件为假),跳到目标位置
		return TRUE;
	} 

	void Backpatch(int p,int t)
	{//将链头号为p的链的arg2设为t
		int q;
		while(p!=0)
		{
			q=code[p].arg2;
			code[p].arg2=t;
			p=q;
		}
	}

	int GetStatement()
	{	//Statement的规约
		char strtemp1[L2MAX];
		int acgo,wago,thengo,whilego,go;
		switch(tempword.type)
		{
		case SIGN_NAME:
			{	//<id>:=<exp>
				 strcpy(strtemp1,tempword.data);
				 tempword=was.GetOneWord();
				 if(FALSE==Match(tempword,SIGN_EVAL)) return FALSE;//要匹配:=
				 tempword=was.GetOneWord();
				 if(FALSE==GetExp()) return FALSE;

				 //从符号表里查变量的相对层数和地址
				 if(FALSE==FindFh(strtemp1,tempmhs,&tempfindfh)) return FALSE;
				 if(tempfindfh.type==FH_XC || tempfindfh.type==FH_VAR)
				 {	//将栈顶元素存到变量里
					 GenCode("STO",tempfindfh.depth,tempfindfh.address);
				 }
				 else if(tempfindfh.type==FH_PRONAME)
				 {// 赋值号左边是过程名则出错
					sprintf(error,"第%d行 赋值号左边不能是过程名",tempword.line);
					return FALSE;
				 }
				 else if(tempfindfh.type==FH_CONST)
				 {// 常量不能被赋值
					 sprintf(error,"第%d行 常量不能被赋值",tempword.line);
					 return FALSE;
				 }
				 break;
			}
		case SIGN_IF:
			{   //if <lexp> then <statement> [else <statement>]
				tempword=was.GetOneWord();
				if(FALSE==GetCondition(&acgo,&wago)) return FALSE;//处理条件语句
				if(FALSE==Match(tempword,SIGN_THEN)) return FALSE;//匹配then
				Backpatch(acgo,codenum);//回填真链
				tempword=was.GetOneWord();
				if(FALSE==GetStatement()) return FALSE;//生成真链指向的指令代码
				if(tempword.type==SIGN_ELSE)
				{	//如果有else
					thengo=codenum;//真链指向的指令的最后一条的地址
					//真链指向的指令执行结束,要跳到假链指向的指令后面,
					//但由于假链指向的指令未生成,故目标指令地址暂时不填
					GenCode("JMP",0,0);
					Backpatch(wago,codenum);//回填假链
					tempword=was.GetOneWord();
					GetStatement();//生成假链指向的指令代码
					Backpatch(thengo,codenum);//回填真链指向指令的最后一条
				}
				else Backpatch(wago,codenum);//回填假链
				break;
			}
		case SIGN_WHILE:
			{	//while <lexp> do <statement>
				whilego=codenum;
				tempword=was.GetOneWord();
				if(FALSE==GetCondition(&acgo,&wago)) return FALSE;//处理条件语句
				if(FALSE==Match(tempword,SIGN_DO)) return FALSE;//匹配do
				Backpatch(acgo,codenum);//回填真链
				tempword=was.GetOneWord();
				if(FALSE==GetStatement()) return TRUE;//生成真链指向的指令代码
				GenCode("JMP",0,0);//真链指向的指令执行完毕,要跳回到while处
				Backpatch(codenum-1,whilego);//回填上一条指令
				Backpatch(wago,codenum);//回填假链
				break;
			}
		case SIGN_CALL:
			{	//call <id> [(<exp>{,<exp>})]
				tempword=was.GetOneWord();
				if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;

				strcpy(strtemp1,tempword.data);//将过程名暂时记下
				tempword=was.GetOneWord();
				if(tempword.type==SIGN_LEFTBRA)
				{//如果有"(",说明调用的过程有参数,处理参数
					tempword=was.GetOneWord();
					if(FALSE==GetExp()) return FALSE;
					while(tempword.type==SIGN_COMMA)
					{//只要参数后面跟的是“,”,说明后面还有参数,继续处理
						tempword=was.GetOneWord();
						GetExp();
					}
					if(FALSE==Match(tempword,SIGN_RIGHTBRA)) return FALSE;
					tempword=was.GetOneWord();
				}
				if(FALSE==FindFh(strtemp1,tempmhs,&tempfindfh)) return FALSE;
				if(tempfindfh.type==FH_PRONAME)
				{//call后面的标示符必须是过程名
				 //从符号表中查出被调用过程相对调用过程的相对层数和指令地址,生成机器码
					GenCode("CAL",tempfindfh.depth,tempfindfh.address);
				}
				else
				{
					sprintf(error,"第%d行 call后面应该是过程名",tempword.line);
					return FALSE;
				}
				break;
			}
		case SIGN_READ:
			{	//read (<id>{,<id>})
				tempword=was.GetOneWord();
				if(FALSE==Match(tempword,SIGN_LEFTBRA)) return FALSE;
				do
				{
					tempword=was.GetOneWord();
					if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;
					
					if(FALSE==FindFh(tempword.data,tempmhs,&tempfindfh)) return FALSE;
					if(tempfindfh.type==FH_VAR || tempfindfh.type==FH_XC)
					{
						GenCode("RED",tempfindfh.depth,tempfindfh.address);
					}
					else
					{
						sprintf(error,"第%d行 read后面应该是变量或形参",tempword.line);
						return FALSE;
					}
					tempword=was.GetOneWord();
					if(strcmp(tempword.data,",")==0) go=1;//变量或形参后面是“,”,说明还未处理完
					else go=0;
					if(1==go && Match(tempword,SIGN_COMMA)==FALSE) return FALSE;
					if(0==go && Match(tempword,SIGN_RIGHTBRA)==FALSE) return FALSE;
				}while(1==go);
				tempword=was.GetOneWord();
				break;
			}
		case SIGN_WRITE:
			{	//write(<exp>{,<exp>})
				tempword=was.GetOneWord();
				if(FALSE==Match(tempword,SIGN_LEFTBRA)) return FALSE;
				do
				{
					tempword=was.GetOneWord();
					if(FALSE==GetExp()) return FALSE;//处理表达式
					GenCode("WRT",0,0);
					if(strcmp(tempword.data,",")==0) go=1;//表达式后面是“,”,说明还未处理完
					else go=0;
					if(1==go && Match(tempword,SIGN_COMMA)==FALSE) return FALSE;
					if(0==go && Match(tempword,SIGN_RIGHTBRA)==FALSE) return FALSE;
				}while(1==go);
				tempword=was.GetOneWord();
				break;
			}
		case SIGN_BEGIN:
			{	//<body>
				if(FALSE==GetBody()) return FALSE;//递归地处理body
				break;
			}
		default:
			{
				sprintf(error,"第%d行 过程体有错",tempword.line);
				return FALSE;
				break;
			}
		}
		if(tempword.type==SIGN_END && strcmp(tempmhs,"program")!=0)
		{
		}
		return TRUE;
	}
};

⌨️ 快捷键说明

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