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

📄 pl0.cpp

📁 用于模拟编译系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		gen(OPR,0,6);
	}
	else
	{
		expression(tmp,tx,lev);
		if(tmp.find(sym)==tmp.end())
			error(20);
		else
		{
			relop= sym;
			getsym();
			expression(fsys,tx,lev);
			switch(relop)
			{
			case EQL: gen(OPR,0,8);
				break;
			case NEQ: gen(OPR,0,9);
				break;
			case LSS: gen(OPR,0,10);
				break;
			case GEQ: gen(OPR,0,11);
				break;
			case GTR: gen(OPR,0,12);
				break;
			case LEQ: gen(OPR,0,13);
				break;
			}
		}
	}
}//condition end
void PL0::statement(symset fsys,int tx,int lev)
{
	if(sourceEnd)
		return;
	int i,cx1,cx2;
	if(sym ==IDENT)
	{
		i= position(id,tx);
		if (i == 0)
			error(11);
		else if (table[i].kind!=VARIABLE)
		{
			error(12);
			i= 0;
		}
		getsym();
		if(sym ==BECOMES)
			getsym();
		else
			error(13);
		expression(fsys,tx,lev);
		if(sym!=SEMICOLON)
			error(10);
		if( i!= 0)
			gen(STO,lev-table[i].other.inOther.level,table[i].other.inOther.adr);
	}
	else if( sym==READSYM)
	{
		getsym();
		if( sym!=LPAREN)
			error(34);
		else
			do{
				getsym();
				if (sym==IDENT)
					i=position(id,tx);
				else
					i=0;
				if( i==0 )
					error(35);
				else
				{
					gen(OPR,0,16);
					gen(STO,lev-table[i].other.inOther.level,table[i].other.inOther.adr);
				}
				getsym();
			}while(sym==COMMA);
			if (sym!=RPAREN)
			{
				error(33);
				while (fsys.find(sym)!=fsys.end())  getsym();
			}
			else 
				getsym();
	}
	else if( sym==WRITESYM)
	{
		getsym();
		if (sym==LPAREN)
		{
			do{
				getsym();
				symset tmp=fsys;
				for(int t=RPAREN;t<=COMMA;t++)
					tmp.insert((symbol)t);
				expression(tmp,tx,lev);
				gen(OPR,0,14);
			}while(sym==COMMA);
			if (sym!=RPAREN)
				error(33);
			else
				getsym();
		}
		gen(OPR,0,15);
	}
	else if( sym ==CALLSYM)
	{
		getsym();
		if( sym!=IDENT)
			error(14);
		else
		{
			i= position(id,tx);
			if (i == 0)
				error(11);
			else if (table[i].kind = PROCEDURE)
				gen(CAL,lev-table[i].other.inOther.level,table[i].other.inOther.adr);
			else
				error(15);
			getsym();
		}
	}
	else if( sym ==IFSYM)
	{
		getsym();
		symset tmp=fsys;
		for(int i=THENSYM;i<=DOSYM;i++)
			tmp.insert((symbol)i);
		condition(tmp,tx,lev);
		if( sym == THENSYM)
			getsym();
		else
			error(16);
		cx1= cx;
		gen(JPC,0,0);
		statement(fsys,tx,lev);
		code[cx1].a= cx;
	}
	else if( sym ==BEGINSYM)
	{
		getsym();
		symset tmp=fsys;
		for(int i=SEMICOLON;i<=ENDSYM;i++)
			tmp.insert((symbol)i);
		statement(tmp,tx,lev);
		tmp=statbegsys;
		tmp.insert(SEMICOLON);
		while( tmp.find(sym)!=tmp.end())
		{
			if(sourceEnd)return;
			if (sym ==SEMICOLON||sym ==ENDSYM)
				getsym();
			else if(sym=PERIOD)
			{
				error(26);
				getsym();
			}
			else
				error(10);
			tmp=fsys;
			for(i=SEMICOLON;i<=ENDSYM;i++)
				tmp.insert((symbol)i);
			if(sourceEnd)return;
			if(sym==ENDSYM)
				break;
			statement(tmp,tx,lev);
		}
		if( sym ==ENDSYM)
			getsym();
		else if(!sourceEnd)
			error(17);
	}
	else if(sym ==WHILESYM)
	{
		cx1= cx;
		getsym();
		symset tmp=fsys;
		tmp.insert(DOSYM);
		condition(tmp,tx,lev);
		cx2= cx;
		gen(JPC,0,0);
		if(sym ==DOSYM)
			getsym();
		else
			error(18);
		statement(fsys,tx,lev);
		gen(JMP,0,cx1);
		code[cx2].a= cx;
	}
	symset setT;
	test(fsys,setT,19);
}//statement end
void PL0::block(int lev,int tx,symset fsys)
{
	if(sourceEnd)
		return;
	int dx;//data allocation index
	int tx0;//initial table index
	int cx0;//initial code index
	dx= 3;
	tx0= tx;
	table[tx].other.inOther.adr= cx;
	gen(JMP,0,0);
	if( lev>levmax)
		error(32);
	do{  
		if( sym ==CONSTSYM)
		{
			getsym();
			do{
				constdeclaration(tx,dx,lev);
				while (sym ==COMMA)
				{
					getsym();
					constdeclaration(tx,dx,lev);
				}
				if (sym ==SEMICOLON)
					getsym();
				else
					error(5);
			}while(sym==IDENT);
		}
		if( sym ==VARSYM)
		{
			getsym();
			do{
				vardeclaration(tx,dx,lev);
				while( sym ==COMMA){
					getsym();
					vardeclaration(tx,dx,lev);
				}
				if( sym ==SEMICOLON)
					getsym();
				else
					error(5);
			}while(sym==IDENT);
		}
		while( sym ==PROCSYM)
		{
			getsym();
			if (sym ==IDENT)
			{
				enter(PROCEDURE,tx,dx,lev);
				getsym();
			}
			else
				error(4);
			if( sym ==SEMICOLON)
				getsym();
			else
				error(5);
			symset tmp=fsys;
			tmp.insert(SEMICOLON);
			block(lev+1,tx,tmp);
			if (sym ==SEMICOLON){
				getsym();
				symset tmp=statbegsys;
				for(int i=IDENT;i<=PROCSYM;i++)
					tmp.insert((symbol)i);
				test(tmp,fsys,6);
			}
			else
				error(5);
		}
		symset tmp=statbegsys;
		tmp.insert(IDENT);
		test(tmp,declbegsys,7);
	}while(declbegsys.find(sym)!=declbegsys.end());
	code[table[tx0].other.inOther.adr].a= cx;
	table[tx0].other.inOther.adr= cx;// start adr of code
	table[tx0].other.inOther.size=dx;
	cx0= cx;
	gen(INT,0,dx);
	symset tmp=statbegsys;
	for(int i=SEMICOLON;i<=ENDSYM;i++)
		tmp.insert((symbol)i);
	statement(tmp,tx,lev);
	gen(OPR,0,0);// return
	symset s2;
	test(fsys,s2,8);
	listcode(cx0);
}// block end
int PL0::base(int l,int b,int s[])
{
	int b1;
	b1= b;//find base l levels down
	while(l>0){
		b1= s[b1];
		l= l-1;
	}
	return  b1;
}
void PL0::interpret()
{
	int err1=errorString.size();
	if(err1>0)
	{
		cout<<"存在%d个错误:"<<err1<<endl;
		for(int i=0;i<err1;i++)
			cout<<errorString[i]<<endl;
		return;
	}
	const stacksize = 500;
	int  p=0,b=1,t=0;//program-,base-,topstack-registers
	instruction  i;// instruction register
	int  s[stacksize+1]={0};//  datastore
	cout<<" Start PL/0\n";
	do{
		i= code[p];
		p= p+1;
		switch(i.f)
		{
		case LIT:
			t= t+1;
			s[t]= i.a;
			break;
		case OPR:
			switch(i.a) //operator
			{
			case 0:// return
				t= b-1; 
				p= s[t+3]; 
				b= s[t+2];
				break;
			case 1:
				s[t]= -s[t];
				break;
			case 2:
				t= t-1;
				s[t]= s[t]+s[t+1];
				break;
			case 3:
				t= t-1;
				s[t]= s[t]-s[t+1];
				break;
			case 4:
				t= t-1;
				s[t]= s[t]*s[t+1];
				break;
			case 5:
				t= t-1;
				s[t]= s[t] / s[t+1];
				break;
			case 6:
				if(s[t]%2)
					s[t]=1;
				else
					s[t]=0;
				break;
			case 8:
				t= t-1;
				if(s[t]==s[t+1])
					s[t]=1;
				else
					s[t]=0;
				break;
			case 9:
				t= t-1;
				if(s[t]==s[t+1])
					s[t]=0;
				else
					s[t]=1;
				break;
			case 10:
				t= t-1;
				if(s[t]<s[t+1])
					s[t]=1;
				else
					s[t]=0;
				break;
			case 11:
				t= t-1;
				if(s[t]>=s[t+1])
					s[t]= 1;
				else
					s[t]=0;
				break;
			case 12:
				t= t-1;
				if(s[t]>s[t+1])
					s[t]= 1;
				else
					s[t]=0;
				break;
			case 13:
				t= t-1;
				if(s[t]<=s[t+1])
					s[t]= 1;
				else
					s[t]=0;
				break;
			case 14:
				cout<<"    "<<s[t];
				t=t-1;
				break;
			case 15:
				cout<<endl;
				break;
			case 16:
				t=t+1;
				cout<<"?";
				s[t]=0;
				cin>>s[t];
				break;
			};
			break;
			case LOD:
				t= t+1;
				s[t]= s[base(i.l,b,s)+i.a];
				break;
			case STO:
				s[base(i.l,b,s)+i.a]= s[t];
				t= t-1;
				break;
			case CAL://generate new block mark
				s[t+1]= base(i.l,b,s);
				s[t+2]= b;
				s[t+3]= p;
				b= t+1;
				p=i.a;
				break;
			case INT: 
				t= t+i.a;
				break;
			case JMP:
				p= i.a;
				break;
			case JPC:
				if (s[t] == 0)
					p= i.a;
				t= t-1;
				break;
		}//switch end 
	  }while(p!=0);
	  cout<<" End PL/0\n";
}//interpret end
void PL0::SaveCode()
{
	if(fout)
		for (int i=0;i<cx;i++)
			fprintf(fout,"%d  %s %d %d\n ",i,mnemonic[code[i].f],code[i].l,code[i].a);
}

⌨️ 快捷键说明

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