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

📄 pl0.c

📁 pl0编译器,包括词法分析,语法语义分析,以及解释执行
💻 C
📖 第 1 页 / 共 2 页
字号:
			if(getsym()==-1)
				return -1;
		}
		memcpy(ts,s,sizeof(int)*SYMNUM);
		if(stat(ptx,ts,lev)==-1)
			return -1;
		code[cx1].a=cx;
	}
	else if(sym==whilesym)
	{
		int cx1,cx2;
		cx1=cx;
		if(getsym()==-1)
			return -1;
		memcpy(ts,s,sizeof(int)*SYMNUM);
		ts[dosym]=1;
		if(con(ptx,ts,lev)==-1)
			return -1;
		cx2=cx;
		if(gen(jpc,0,0)==-1)
			return -1;
		if(sym!=dosym)
			error(31);
		else
		{
			if(getsym()==-1)
				return -1;
		}
		if(stat(ptx,ts,lev)==-1)
			return -1;
		if(gen(jmp,0,cx1)==-1)
			return -1;
		code[cx2].a=cx;
	}
	else if(sym==readsym)
	{
		if(getsym()==-1)
			return -1;
		if(sym!=lparen)
			error(19);
		else
		{
			if(getsym()==-1)
				return -1;
			if(sym==ident)
			{
				p=extable(id,*ptx);
				if(p==0)
					error(20);
				else
				{
					if(tb[p].kind!=variable)
					{
						error(21);
						p=0;
					}
					else
					{
						if(getsym()==-1)
							return -1;
					}
				}
				if(p!=0)
				{
					if(gen(opr,0,16)==-1||gen(sto,lev-tb[p].lev,tb[p].adr)==-1)
						return -1;
				}
			}
			else
				error(21);
			while(sym==comma)
			{
				if(getsym()==-1)
					return -1;
				if(sym!=ident)
					error(21);
				else
				{
					p=extable(id,*ptx);
					if(p==0)
						error(20);
					else
					{
						if(tb[p].kind!=variable)
						{
							error(21);
							p=0;
						}
						else
						{
							if(getsym()==-1)
								return -1;
						}
					}
					if(p!=0)
					{
						if(gen(opr,0,16)==-1||gen(sto,lev-tb[p].lev,tb[p].adr)==-1)
							return -1;
					}
				}
			}
			if(sym!=rparen)
			{
				error(22);
				while(!inset(sym,s))
				{
					if(getsym()==-1)
						return -1;
				}
			}
			if(getsym()==-1)
				return -1;
		}
	}
	else if(sym==writesym)
	{
		if(getsym()==-1)
			return -1;
		if(sym==lparen)
		{
			if(getsym()==-1)
				return -1;
			memcpy(ts,s,sizeof(int)*SYMNUM);
			ts[rparen]=1;
			ts[comma]=1;
			if(exp(ptx,ts,lev)==-1)
				return -1;
			if(gen(opr,0,14)==-1)
				return -1;
			while(sym==comma)
			{
				if(exp(ptx,ts,lev)==-1)
					return -1;
				if(gen(opr,0,14)==-1)
				return -1;
			}
			if(sym!=rparen)
				error(23);
			else
			{
				if(getsym()==-1)
					return -1;
			}
		}
		else
			error(24);
		if(gen(opr,0,15)==-1)
			return -1;
	}
	else
	{
		memset(ts,0,sizeof(int)*SYMNUM);
		if(test(s,ts,32)==-1)
			return -1;
	}
	return 0;
}

int exp(int *ptx,int *s,int lev)
{
	enum sbl tmp;
	int f=0;
	int ts[SYMNUM];
	if(sym==plus||sym==minus)
	{
		
		if(getsym()==-1)
			return -1;
		if(sym==minus)
			f=1;
	}
	memcpy(ts,s,sizeof(int)*SYMNUM);
	ts[plus]=1;
	ts[minus]=1;
	if(term(ptx,ts,lev)==-1)
		return -1;
	if(f==1)
	{
	if(gen(opr,0,1)==-1)
			return -1;
	}
	while(sym==plus||sym==minus)
	{
		tmp=sym;
		if(getsym()==-1)
			return -1;
		memcpy(ts,s,sizeof(int)*SYMNUM);
		ts[plus]=1;
		ts[minus]=1;
		if(term(ptx,ts,lev)==-1)
			return -1;
		if(tmp==plus)
		{
			if(gen(opr,0,2)==-1)
				return -1;
		}
		else   //if(tmp==minus)
		{
			if(gen(opr,0,3)==-1)
				return -1;
		}
	}
	return 0;
}

int term(int *ptx,int *s,int lev)
{
	enum sbl tmp;
	int ts[SYMNUM];
	memcpy(ts,s,sizeof(int)*SYMNUM);
	ts[times]=1;
	ts[slash]=1;
	if(fac(ptx,ts,lev)==-1)
		return -1;
	while(sym==times||sym==slash)
	{
		tmp=sym;
		if(getsym()==-1)
			return -1;
		if(fac(ptx,ts,lev)==-1)
			return -1;
		if(tmp==times)
		{
			if(gen(opr,0,4)==-1)
				return -1;
		}
		else  //if(tmp==slash)
		{
			if(gen(opr,0,5)==-1)
				return -1;
		}
	}
	return 0;
}

int fac(int *ptx,int *s,int lev)
{
	int ts[SYMNUM];
	int p;
	if(test(fcbsys,s,33)==-1)
		return -1;
	while(inset(sym,fcbsys))
	{
		if(sym==ident)
		{
			p=extable(id,*ptx);
			if(p==0)
				error(34);
			else
			{
				if(tb[p].kind==constant)
				{
					if(gen(lit,0,tb[p].val)==-1)
						return -1;
				}
				else if(tb[p].kind==variable)
				{
					if(gen(lod,lev-tb[p].lev,tb[p].adr)==-1)
						return -1;
				}
				else    //类型为过程
					error(35);
			}
			if(getsym()==-1)
				return -1;
		}
		else if(sym==number)
		{
			if(num>AMAX)
			{
				error(7);
				num=0;
			}
			if(gen(lit,0,num)==-1)
				return -1;
			if(getsym()==-1)
				return -1;
		}
		else 
		{
			if(sym==lparen)
			{
				if(getsym()==-1)
					return -1;
				memcpy(ts,s,sizeof(int)*SYMNUM);
				ts[rparen]=1;
				if(exp(ptx,ts,lev)==-1)
					return -1;
				if(sym!=rparen)
					error(36);
				else
				{
					if(getsym()==-1)
						return -1;
				}
			}
			if(test(s,fcbsys,37)==-1)
				return -1;
		}
	}
	return 0;
}

int con(int *ptx,int *s,int lev)
{
	int ts[SYMNUM];
	if(sym==oddsym)
	{
		if(getsym()==-1)
			return -1;
		if(exp(ptx,s,lev)==-1)
			return -1;
		if(gen(opr,0,6)==-1)
			return -1;
	}
	else
	{
		enum sbl tmp;
		memcpy(ts,s,sizeof(int)*SYMNUM);
		ts[eql]=1;
		ts[neq]=1;
		ts[lss]=1;
		ts[leq]=1;
		ts[gtr]=1;
		ts[geq]=1;
		if(exp(ptx,ts,lev)==-1)
			return -1;
		tmp=sym;
		if(sym!=eql&&sym!=neq&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq)
			error(38);
		else
		{
			if(getsym()==-1)
				return -1;
			memcpy(ts,s,sizeof(int)*SYMNUM);
			if(exp(ptx,ts,lev)==-1)
				return -1;
			if(tmp==eql)
			{
				if(gen(opr,0,8)==-1)
					return -1;
			}
			else if(tmp==neq)
			{
				if(gen(opr,0,9)==-1)
					return -1;
			}
			else if(tmp==lss)
			{
				if(gen(opr,0,10)==-1)
					return -1;
			}
			else if(tmp==leq)
			{
				if(gen(opr,0,11)==-1)
					return -1;
			}
			else if(tmp==gtr)
			{
				if(gen(opr,0,12)==-1)
					return -1;
			}
			else    //if(tmp==geq)
			{
				if(gen(opr,0,13)==-1)
					return -1;
			}
		}
	}
	return 0;
}

void itp()
{
	int sk[STACKSIZE];             //栈
	int t=0,b=0,p=0;               //t栈顶指针,b当前过程基指针,p当前指令指针    
	struct ins op;                 //当前指令
	sk[0]=sk[1]=sk[2]=0;
	printf("\nStart running\n");
	do{
		op=code[p];
		p++;
		if(op.f==lit)              //取常数到栈顶
		{
			sk[t]=op.a;
			t++;
		}
		else if(op.f==lod)         //取变量
		{
			sk[t]=sk[base(op.l,sk,b)+op.a];  //取相对当前过程数据基地址为a的内存的值到栈顶
			t++;
		}
		else if(op.f==sto)         //栈顶值存到相对当前过程数据基地址为a的内存
		{
			t--;
			sk[base(op.l,sk,b)+op.a]=sk[t];
		}
		else if(op.f==cal)        //子程序调用
		{
			sk[t]=base(op.l,sk,b);//父过程基地址入栈
			sk[t+1]=b;            //本过程基地址入栈
			sk[t+2]=p;            //当前指令入栈
			b=t;                  //基地址改为新过程基地址
			p=op.a;               //跳转
		}
		else if(op.f==inte)       //分配三个联系单元及变量内存
		{
			t+=op.a;
		}
		else if(op.f==jmp)        //跳转
		{
			p=op.a;
		}
		else if(op.f==jpc)        //条件跳转
		{
			t--;
			if(sk[t]==0)
				p=op.a;
		}
		else if(op.f==opr)
		{
			if(op.a==0)
			{
				t=b;
				b=sk[t+1];
				p=sk[t+2];
			}
			else if(op.a==1)
			{
				sk[t-1]=-sk[t-1];
			}
			else if(op.a==2)
			{
				t--;
				sk[t-1]=sk[t-1]+sk[t];
			}
			else if(op.a==3)
			{
				t--;
				sk[t-1]=sk[t-1]-sk[t];
			}
			else if(op.a==4)
			{
				t--;
				sk[t-1]=sk[t-1]*sk[t];
			}
			else if(op.a==5)
			{
				t--;
				sk[t-1]=sk[t-1]/sk[t];
			}
			else if(op.a==6)
			{
				sk[t-1]=sk[t-1]%2;
			}
			else if(op.a==8)
			{
				t--;
				sk[t-1]=(sk[t-1]==sk[t]);
			}
			else if(op.a==9)
			{
				t--;
				sk[t-1]=(sk[t-1]!=sk[t]);
			}
			else if(op.a==10)
			{
				t--;
				sk[t-1]=(sk[t-1]<sk[t]);
			}
			else if(op.a==11)
			{
				t--;
				sk[t-1]=(sk[t-1]<=sk[t]);
			}
			else if(op.a==12)
			{
				t--;
				sk[t-1]=(sk[t-1]>sk[t]);
			}
			else if(op.a==13)
			{
				t--;
				sk[t-1]=(sk[t-1]>=sk[t]);
			}
			else if(op.a==14)
			{
				t--;
				printf("%d",sk[t]);
				fprintf(fa2,"%d",sk[t]);
			}
			else if(op.a==15)
			{
				printf("\n");
				fprintf(fa2,"\n");
			}
			else if(op.a==16)
			{
				printf("?");
				fprintf(fa2,"?");
				scanf("%d",&sk[t]);
				fprintf(fa2,"%d\n",sk[t]);
				t++;
			}
		}
	}while(p!=0);
}

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

main()
{
	int nlev[SYMNUM];
	int k;
	printf("\n     * * * * * * * * * * *     PL0 Compiler v1.0     * * * * * * * * * * *      \n");
	printf("Input pl0 file name:");
	scanf("%s",fname);
	fin=fopen(fname,"r");
	if(fin==NULL)
		printf("Can't open %s!\n",fname);
	else
	{
		printf("List object code:\n");     /*输出虚拟机代码*/
		fa1=fopen("fa1.txt","w");
		fprintf(fa1,"Input pl0 file name:");
    	fprintf(fa1,"%s\n",fname);
		init();
		err=cx=cc=ll=0;
		ch=' ';
		if(getsym()!=-1)
		{
			fa=fopen("fa.txt","w");
			addset(nlev,dcbsys,stbsys,SYMNUM);
			nlev[period]=1;
			if(mb(0,0,nlev)==-1)
			{
				fclose(fa);
				fclose(fa1);
				fclose(fin);
				printf("\n");
				return 0;
			}
			fclose(fa1);
			if(sym!=period)
				error(39);
			printf("\n\n");
			fprintf(fa,"\n\n");
			for(k=0;k<cx;k++)
			{
				printf("%d\t%s\t%d\t%d\n",k,mc[code[k].f],code[k].l,code[k].a);
				fprintf(fa,"%d\t%s\t%d\t%d\n",k,mc[code[k].f],code[k].l,code[k].a);
			}
			if(err==0)
			{
				fa2=fopen("fa2.txt","w");
				itp();
				fclose(fa2);
			}
			else
			{
				printf("\n%d errors!\n",err);
				fprintf(fa,"\n%d errors!\n",err);
			}
		}
		fclose(fa);
		fclose(fin);
	}
	printf("\n");
	return 0;
}

⌨️ 快捷键说明

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