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

📄 pl0.cpp

📁 对PL0原编译器进行了以下的扩充:1.增加以下保留字else(elsesym), for(forsym),to(tosym),downto(downtosym),return(returnsym),[
💻 CPP
📖 第 1 页 / 共 3 页
字号:
								if(sym==semicolon)
								{
									getsymdo;
								}
								else
								{
									error(10);/*缺少分号*/
								}
								statementdo(nxtlev,ptx,lev,tx0,hreturn);
							}
							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;/*后跟符号为do*/
								conditiondo(nxtlev,ptx,lev);  /*调用条件处理*/
								cx2=cx;       /*保存循环体的结束的下一个位置*/
								gendo(jpc,0,0);/*生成条件跳转,但跳出循环的地址未知*/
								if(sym==dosym)
								{
									getsymdo;
								}
								else
								{
									error(18);      /*缺少do*/
								}
								statementdo(fsys,ptx,lev,tx0,hreturn); /*循环体*/
								gendo(jmp,0,cx1);/*回头重新判断条件*/
								code[cx2].a=cx;   /*反填跳出循环的地址,与if类似*/
							}
							else
							{
								if(sym==forsym)
								{
									bool point=false;
									int cxstar,cxend;
									getsymdo;
									if(sym==padsym)
									{
										point=true;
										getsymdo;
									}
									if(sym==ident)
   									{
										  memcpy(nxtlev,fsys,sizeof(bool)* symnum);
                                          i=identbc(nxtlev,ptx,lev,cxstar,cxend,point);
										  cx1=cx;
										  genrp(cxstar,cxend);
										  ldst(lod,lev,i,point);
									}
									if(sym==tosym||sym==downtosym)
									{
										enum symbol resym=sym;
										getsymdo;
										memcpy(nxtlev,fsys,sizeof(bool)*symnum);
										nxtlev[dosym]=true;
										expressiondo(nxtlev,ptx,lev);
										switch(resym)
										{
											case tosym:
												gendo(opr,0,13);
												break;
											case downtosym:
												gendo(opr,0,11);
												break;
										}
										cx2=cx;
										gendo(jpc,0,0);
										if(sym==dosym)
										{
											getsymdo;
										}
										else
										{
											error(18);
										}
										statementdo(fsys,ptx,lev,tx0,hreturn);
	                                    switch(resym)
										{
											case tosym:
												genrp(cxstar,cxend);
												ldst(lod,lev,i,point);
												gendo(lit,0,1);
												gendo(opr,0,2);
												ldst(sto,lev,i,point);
												break;
											case downtosym:
												genrp(cxstar,cxend);
												ldst(lod,lev,i,point);
												gendo(lit,0,1);
												gendo(opr,0,3);
												ldst(sto,lev,i,point);
												break;
										}
										gendo(jmp,0,cx1);
										code[cx2].a=cx;
									}
								}
								else
								{
									if(sym==dplus||sym==dminus)
									{
											dpm(fsys,0,ptx,lev,-1,false);
									}
									else
									{
										if(sym==returnsym)
										{
											table[tx0].retn=true;
											if(hreturn==true)
											{
												printf("just can return one value\n");
												error(66);
											}
											getsymdo;
											hreturn=true;
											expressiondo(nxtlev,ptx,lev);
											if(sym!=endsym)
											{
												printf("return must at the last\n");
												error(46);
											}
										}
										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 point=false;
    bool nxtlev[symnum];
    testdo(facbegsys,fsys,24);           /*检测因子的开始符好号*/
    while(inset(sym,facbegsys))          /*循环直到不是因子开始符号*/
    {
		if(sym==padsym)
		{
			point=true;
			getsymdo;
		}
        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);                       /*直接把常量的值入栈*/
						getsymdo;
						break;
					case variable:                                      /*名字为变量*/
						countadr(fsys,ptx,lev,i);
						ldst(lod,lev,i,point);                          /*找到变量地址并将其值入栈*/
					    dpm(fsys,i,ptx,lev,2,point);
						break;
					case procedur:                                      /*名字为过程*/
						error(21);                                       /*不能为过程*/
						break;
				}
			}
		}
		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);                                      /*缺少右括号*/
					}
				}
				else
				{
					if(sym==dplus||sym==dminus)
					{
						dpm(fsys,i,ptx,lev,1,false);
					}
					else if(sym==radsym)
					{
						getsymdo;
						if(sym==ident)
						{
                             i=position(id,*ptx);        /*查找名字*/
                             if(i==0)
							 {
								error(11);               /*标识符未声明*/
							 }
							 else
							 {
								if(table[i].kind!=variable)
								{
									error(12);
								}
								else
								{
									countadr(fsys,ptx,lev,i);
									gendo(rad,lev-table[i].level,i);
								}
							 }
						}
						else
						{
							error(12);
						}
					}
					else
					{
				        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);                              /*生成odd指令*/
    }
    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(fsys,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,n;             /*指令指针,指令基址,栈顶指针*/
	int k=0,kk=0,adr,ls=0;
	int s[stacksize];      /*栈*/
	struct instruction i;  /*存放当前指令*/
	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:        /*将a的值取到栈顶*/
				s[t]=i.a;
				t++;
				break;
			case opr:        /*数字、逻辑运算*/
				switch(i.a)
				{
					case 0:
						ls=s[t-1];
						t=b;
						p=s[t+2];
						b=s[t+1];
						s[t]=ls;
						t++;
						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:
						s[t-1]=s[t-1]%2;
						break;
					case 7:
						t--;
						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:       /*取相对当前过程的数据基地址为a的内存的值到栈顶*/
				s[t]=s[base(i.l,s,b)+i.a];
				t++;
				break;
			case lay:
				adr=table[i.a].drt; 
				for(k=0;k<table[i.a].drt;k++)
				{
					ls=s[base(i.l,s,b)+table[i.a].adr+k];
					if(ls>=table[i.a].eachdrt[k]||ls<0)
					{
						printf("array overflow\n");
						error(40);
						break;
					}
					for(kk=k+1;kk<table[i.a].drt;kk++)
					{
						ls=ls*table[i.a].eachdrt[kk];
					}
					adr=adr+ls;
				}
				s[t]=s[base(i.l,s,b)+table[i.a].adr+adr];
				t++;
			    break;
			case rad:
				if(table[i.a].size==1)
				{
					s[t]=base(i.l,s,b)+table[i.a].adr;
					t++;
					break;
				}
				else if(table[i.a].size>1)
				{
					adr=table[i.a].drt; 
					for(k=0;k<table[i.a].drt;k++)
					{
						ls=s[base(i.l,s,b)+table[i.a].adr+k];
						if(ls>=table[i.a].eachdrt[k]||ls<0)
						{
							printf("array overflow\n");
							error(40);
							break;
						}
						for(kk=k+1;kk<table[i.a].drt;kk++)
						{
							ls=ls*table[i.a].eachdrt[kk];
						}
						adr=adr+ls;
					}
					s[t]=base(i.l,s,b)+table[i.a].adr+adr;
					t++;
					break;
				}
			case pad:
				if(table[i.a].size==1)
				{
					s[t]=s[s[base(i.l,s,b)+table[i.a].adr]];
					t++;
					break;
				}
				else if(table[i.a].size>1)
				{
					adr=table[i.a].drt;
					for(k=0;k<table[i.a].drt;k++)
					{
						ls=s[base(i.l,s,b)+table[i.a].adr+k];
						if(ls>=table[i.a].eachdrt[k]||ls<0)
						{
							printf("array overflow\n");
							error(40);
							break;
						}
						for(kk=k+1;kk<table[i.a].drt;kk++)
						{
							ls=ls*table[i.a].eachdrt[kk];
						}
						adr=adr+ls;
					}
					s[t]=s[s[base(i.l,s,b)+table[i.a].adr+adr]];
					t++;
					break;
				}
			case par:
				if(table[i.a].size==1)
				{
					t--;
					s[s[base(i.l,s,b)+table[i.a].adr]]=s[t];
					break;
				}
				else if(table[i.a].size>1)
				{
					adr=table[i.a].drt;
					for(k=0;k<table[i.a].drt;k++)
					{
						ls=s[base(i.l,s,b)+table[i.a].adr+k];
						if(ls>=table[i.a].eachdrt[k]||ls<0)
						{
							printf("array overflow\n");
							error(40);
							break;
						}
						for(kk=k+1;kk<table[i.a].drt;kk++)
						{
							ls=ls*table[i.a].eachdrt[kk];
						}
						adr=adr+ls;
					}
					t--;
					s[s[base(i.l,s,b)+table[i.a].adr+adr]]=s[t];
					break;
				}
			case sto:       /*栈顶的值存到相对当前过程的数据基地址为a的内存*/
				t--;
	            s[base(i.l,s,b)+i.a]=s[t];
				break;
			case say:
				adr=table[i.a].drt;
				for(k=0;k<table[i.a].drt;k++)
				{
					ls=s[base(i.l,s,b)+table[i.a].adr+k];
					if(ls>=table[i.a].eachdrt[k]||ls<0)
					{
						printf("array overflow\n");
						error(40);
						break;
					}
					for(kk=k+1;kk<table[i.a].drt;kk++)
					{
						ls=ls*table[i.a].eachdrt[kk];
					}
					adr=adr+ls;
				}
				t--;
				s[base(i.l,s,b)+table[i.a].adr+adr]=s[t];
				break;
			case cal:              /*调用子程序*/
				s[t]=base(i.l,s,b); /*将父过程基地址入栈*/
				s[t+1]=b;           /*将本过程基地址入栈,此两项用于base函数*/
				s[t+2]=p;           /*将当前指令指针入栈*/
				for(n=0;n<table[i.a].n;n++)
				{
					s[t+3+n]=s[t-table[i.a].n+n];
				}
				b=t;                /*改变基地址指针值为新过程的基地址*/
				p=table[i.a].adr;              /*跳转*/
				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);
}
/*通过过程基址求上1层过程的基址*/
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 + -