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

📄 pl0.cpp

📁 pl0的编译程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			if(sym==number)
			{
				enter(constant,ptx,lev,pdx);
				getsymdo;
			}
			else
			{
				error(2);                                         //常量说明=后应是数字
			}
		}
		else
		{
			error(3);                                              //常量说明标识后应是=
		}     
	}
	else
	{
		error(4);                                                  //const后应是标识
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
int vardeclaration(int *ptx,int lev,int *pdx)                              //变量处理声明
{
	if(sym==ident)
	{
		enter(variable,ptx,lev,pdx);
		getsymdo;
	}
	else
	{      
		error(4);                                            //var后应是标识
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
void listcode(int cx0)                         //输出目标代码清单
{
	int i;
	if(listswitch)
	{
		for(i=cx0;i<cx;i++)
		{
			printf("\n%d %s %d %d\n",i,mnemonic[code[i].f],code[i].l,code[i].a);
			fprintf(fa,"%d %s %d %d",i,mnemonic[code[i].f],code[i].l,code[i].a);
		}
	}
	printf("\n");
}

//////////////////////////////////////////////////////////////////////////////////////////////////
int statement(bool *fsys,int *ptx,int lev)            //语句处理
{
	int i,cx1,cx2;
	bool nxtlev[symnum];

	if(sym==ident)
	{
		i=position(id,*ptx);
		if(i==0)
		{
			error(11);                            //变量未找到
		}
		else
		{
			if(table[i].kind!=variable)
			{
				error(12);                        //赋值语句格式错误
				i=0;
			}
			else
			{
				getsymdo;
				if(sym==becomes)
				{
					getsymdo;
				}
				else
				{
					error(13);                        //没有检测到赋值符号      
				}
				memcpy(nxtlev,fsys,sizeof(bool)*symnum);
				expressiondo(nxtlev,ptx,lev);           //处理赋值符号右侧表达式
				if(i!=0) 
				{
					gendo(sto,lev-table[i].level,table[i].adr);
				}
			}
		}
	}
	else
	{
		if(sym==readsym)                          //准备按照read语句处理
		{
			getsymdo;
			if(sym!=lparen)
			{
				error(34);                      //格式错误,应是左括号
			}
			else
			{
				do{
					getsymdo;
					if(sym==ident)
					{
						i=position(id,*ptx);          //查找要读的变量
					}
					else
					{
						i=0;
					}
					if(i==0)
					{
						error(35);                //read()中应是声明过程的变量
					}
					else
					{
						gendo(opr,0,16);          //生成输入指令,读取值到栈顶
						gendo(sto,lev-table[i].level,table[i].adr);  //存储到变量
					}
					getsymdo;
				}while(sym==comma);                   //一条read语句可读多个变量
			}
			if(sym!=rparen)
			{
				error(33);                              //格式错误,应是右括号                                   
				while(!inset(sym,fsys))
				{
					getsymdo;
				}
			}
			else
			{
				getsymdo;
			}
		}
		else
		{
			if(sym==writesym)                       //准备按照write语句处理
			{
				getsymdo;
				if(sym==lparen)
				{
					do{
						getsymdo;
						memcpy(nxtlev,fsys,sizeof(bool)*symnum);
						nxtlev[rparen]=true;
						nxtlev[comma]=true;
						expressiondo(nxtlev,ptx,lev);

						gendo(opr,0,14);
					}while(sym==comma);

					if(sym!=rparen)
					{
						error(33);
					}
					else
					{
						getsymdo;
					}
				}
				gendo(opr,0,15);
			}
			else
			{
				if(sym==callsym)                          //准备按照call语句处理
				{
					getsymdo;
					if(sym!=ident)
					{
						error(14);                      //call后跟标识符
					}
					else
					{
						i=position(id,*ptx);
						if(i==0)
						{
							error(11);                 //过程未找到
						}	
						else 
						{
							if(table[i].kind==procedur)
							{
								gendo(cal,lev-table[i].level,table[i].adr);
							}
							else
							{
								error(15);              //call后标识符为过程
							}
						}
						getsymdo;
					}
				}
				else
				{
					if(sym==ifsym)                      //准备按照if语句处理
					{
						getsymdo;
						memcpy(nxtlev,fsys,sizeof(bool)*symnum);
						nxtlev[thensym]=true;
						nxtlev[dosym]=true;
						conditiondo(nxtlev,ptx,lev);    //调用条件处理函数
						if(sym==thensym)
						{
							getsymdo;
						}
						else
						{
							error(16);               //缺少then
						}
						cx1=cx;
						gendo(jpc,0,0);
						statementdo(fsys,ptx,lev);       //语句处理
						code[cx1].a=cx;
					}
					else
					{
						if(sym==beginsym)               //按照复合语句处理
						{
							getsymdo;
							memcpy(nxtlev,fsys,sizeof(bool)*symnum);
							nxtlev[semicolon]=true;
							nxtlev[endsym]=true;

							statementdo(nxtlev,ptx,lev);           //语句处理
							while(inset(sym,statbegsys)||sym==semicolon)
							{
								if(sym==semicolon)
								{
									getsymdo;
								}
								else
								{
									error(10);            //缺少分号
								}
								statementdo(nxtlev,ptx,lev);
							}
							if(sym==endsym)
							{
								getsymdo;
							}
							else
							{
								error(17);          //缺少end
							}
						}
						else
						{
							if(sym==whilesym)              //按照while语句处理
							{
								cx1=cx;
								getsymdo;
								memcpy(nxtlev,fsys,sizeof(bool)*symnum);
								nxtlev[dosym]=true;
								conditiondo(nxtlev,ptx,lev);           //条件处理
								cx2=cx;
								gendo(jpc,0,0);
								if(sym==dosym)
								{
									getsymdo;
								}
								else
								{
									error(18);                 //缺少do
								}
								statementdo(fsys,ptx,lev);
								gendo(jmp,0,cx1);
								code[cx2].a=cx;
							}
							else
							{
								memset(nxtlev,0,sizeof(bool)*symnum);
								testdo(fsys,nxtlev,19);
							}
						}
					}
				}
			}
		}
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
int expression(bool *fsys,int *ptx,int lev)     //表达式处理
{
	enum symbol addop;                          //用于保存正负号
	bool nxtlev[symnum];

	if(sym==plus||sym==minus)                  //开头的正负号,此时当前表达式看作一个正的或负的项
	{
		addop=sym;
		getsymdo;
		memcpy(nxtlev,fsys,sizeof(bool)*symnum);
		nxtlev[plus]=true;
		nxtlev[minus]=true;
		termdo(nxtlev,ptx,lev);               //处理项
		if(addop==minus)
		{
			gendo(opr,0,1);
		}
	}
	else
	{
		memcpy(nxtlev,fsys,sizeof(bool)*symnum);
		nxtlev[plus]=true;
		nxtlev[minus]=true;
		termdo(nxtlev,ptx,lev);             //处理项
	}
	while(sym==plus||sym==minus)
	{
		addop=sym;
		getsymdo;
		memcpy(nxtlev,fsys,sizeof(bool)*symnum);
		nxtlev[plus]=true;
		nxtlev[minus]=true;
		termdo(nxtlev,ptx,lev);
		if(addop==plus)
		{
			gendo(opr,0,2);
		}
		else
		{
			gendo(opr,0,3);
		}
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
int term(bool *fsys,int *ptx,int lev)    //处理项
{
	enum symbol mulop;                    //用于保存乘除法符号
	bool nxtlev[symnum];

	memcpy(nxtlev,fsys,sizeof(bool)*symnum);
	nxtlev[times]=true;
	nxtlev[slash]=true;
	factordo(nxtlev,ptx,lev);             //处理因子
	while(sym==times||sym==slash)
	{
		mulop=sym;
		getsymdo;
		factordo(nxtlev,ptx,lev);
		if(mulop==times)
		{
			gendo(opr,0,4);
		}
		else
		{
			gendo(opr,0,5);
		}
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
int factor(bool *fsys,int *ptx,int lev)       //因子处理
{
	int i;
    bool nxtlev[symnum];

	testdo(facbegsys,fsys,24);
	while(inset(sym,facbegsys))
	{
		if(sym==ident)
		{
			i=position(id,*ptx);
			if(i==0)
			{
				error(11);                  //标示符未声明
			}
			else
			{
				switch (table[i].kind)
				{
				case constant:                                           //名字为常量
							gendo(lit,0,table[i].val);                   //直接把常量值入栈
							break;
				case variable:                                           //名字为变量
							gendo(lod,lev-table[i].level,table[i].adr);  //找到变量地址将其值入栈
							break;
				case procedur: 
							error(21);                                    //名字不能为过程
							break;
				}
			}
			getsymdo;
		}
		else 
		{
			if (sym==number)                         //因子为数
			{
				if(num>amax)
				{
					error(31);
					num=0;	
				}
				gendo(lit,0,num);
				getsymdo;
			}
			else 
			{
				if(sym==lparen)                     //因子为表达式
				{
					getsymdo;
					memcpy(nxtlev,fsys,sizeof(bool)*symnum);
					nxtlev[rparen]=true;
					expressiondo(nxtlev,ptx,lev);
					if(sym==rparen)
					{
						getsymdo;
					}
				    else
					{
						error(22);                //缺少右括号
					}
				}
				testdo(fsys,facbegsys,23);
			}
		}
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
int condition (bool *fsys,int *ptx,int lev)        //条件处理
{
	enum symbol relop;
	bool nxtlev[symnum];
	
	if(sym==oddsym)                        //准备按照odd运算处理
	{
		getsymdo;
		expressiondo(fsys,ptx,lev);
		gendo(opr,0,6);
	}
	else                                   //逻辑表达式处理
	{
		memcpy(nxtlev,fsys,sizeof(bool)*symnum);
		nxtlev[eql]=true;
		nxtlev[neq]=true;
        nxtlev[lss]=true;
		nxtlev[leq]=true;
		nxtlev[gtr]=true;
        nxtlev[geq]=true;
		expressiondo(nxtlev,ptx,lev);
		if(sym!=eql&&sym!=neq&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq)
		{
			error(20);                                   //应为关系运算符
		}
		else
		{
			relop=sym;
			getsymdo;
			expressiondo(nxtlev,ptx,lev);
			switch(relop)
			{
			case eql:
				gendo (opr,0,8);
				break;
			case neq:
				gendo (opr,0,9);
				break;
			case lss:
				gendo (opr,0,10);
				break;
			case geq:
				gendo (opr,0,11);
				break;
			case gtr:
				gendo (opr,0,12);
				break;
			case leq:
				gendo (opr,0,13);
				break;
			}	
		}
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
void interpret()                             //解释程序
{
	int p,b,t;
	struct instruction i;
	int s[stacksize];
	printf("start pl0\n");
	t=0;
	b=0;
	p=0;
	s[0]=s[1]=s[2]=0;
	do{
		i=code[p];
		p++;
		switch(i.f)
		{
		case lit:
				s[t]=i.a;
				t++;
				break;
		case opr:
			switch (i.a)
			{
			   case 0:
				   t=b;
			       p=s[t+2];
				   b=s[t+1];
				   break;
		       case 1:
				   s[t-1]=-s[t-1];
				   break;
			   case 2:
				   t--;
				   s[t-1]=s[t-1]+s[t];
				   break;
               case 3:
				   t--;
				   s[t-1]=s[t-1]-s[t];
				   break;
		       case 4:
				   t--;
				   s[t-1]=s[t-1]*s[t];
				   break;
			   case 5:
				   t--;
				   s[t-1]=s[t-1]/s[t];
				   break;
			   case 6:
				   t--;
				   s[t-1]=s[t-1]%2;
				   break;
			   case 8:
				   t--;
				   s[t-1]=(s[t-1]==s[t]);
				   break;
			   case 9:
				   t--;
				   s[t-1]=(s[t-1]!=s[t]);
				   break;
			   case 10:
				   t--;
				   s[t-1]=(s[t-1]<s[t]);
				   break;
			   case 11:
				   t--;
				   s[t-1]=(s[t-1]>=s[t]);
				   break;
			   case 12:
				   t--;
				   s[t-1]=(s[t-1]>s[t]);
				   break;
			   case 13:
				   t--;
				   s[t-1]=(s[t-1]<=s[t]);
				   break;
			   case 14:
				   printf("%d",s[t-1]);
				   fprintf(fa2,"%d",s[t-1]);
				   t--;
				   break;
			   case 15:
				   printf("\n");
				   fprintf(fa2,"\n");
				   break;
			   case 16:
				   printf("?");
				   fprintf(fa2,"?");
				   scanf("%d",&(s[t]));
				   fprintf(fa2,"%d\n",s[t]);
				   t++;
				   break;
			}
			break;
        case lod:
			s[t]=s[base(i.l,s,b)+i.a];
			t++;
			break;
		case sto:
			t--;
			s[base(i.l,s,b)+i.a]=s[t];
			break;
		case cal:
			s[t]=base(i.l,s,b);
			s[t+1]=b;
			s[t+2]=p;
			b=t;
			p=i.a;
			break;
		case inte:
			t+=i.a;
			break;
		case jmp:
			p=i.a;
			break;
		case jpc:
			t--;
			if(s[t]==0)
			{
				p=i.a;
			}
			break;
	  }
	}while(p!=0);
}

//////////////////////////////////////////////////////////////////////////////////////////////////
int base(int l,int* s,int b)                //通过过程基址求上一层过程的基址
{
	int b1;
	b1=b;
	while(l>0)
	{
		b1=s[b1];
		l--;
	}
	return b1;
}

⌨️ 快捷键说明

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