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

📄 pl0.cpp

📁 用VC写的扩充的pl0文法编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
							else
							{
								str[slength]=ch;
								Getch();
							}
						}
						if(slength==sleng)
							Error(27,linecount);//字符串不允许为空串!
						sleng=slength-sleng;
						Getch();
					}
					else
					{
						switch(ch)
						{
						case '+':
							sym=PLUS;
							break;
						case '-':
							sym=MINUS;
							break;
						case '*':
							sym=TIMES;
							break;
						case '/':
							sym=SLASH;
							break;
						case '(':
							sym=LPAREN;
							break;
						case ')':
							sym=RPAREN;
							break;
						case '=':
							sym=EQL;
							break;
						case ',':
							sym=COMMA;
							break;
						case '.':
							sym=PERIOD;
							break;
						case ';':
							sym=SEMICOLON;
							break;
						//default:
							//sym=NUL;
							//ch=' ';
						}
						//sym=(SYMBOL)ssym[ch];
						//cout<<"symbol:"<<ch<<setw(12)<<word_Type[sym]<<endl;
						//if(cc!=ll)
							//Getch();
						Getch();
					}
					
				
}
void PL0::Gen(FCT x,float y,float z)
{
	if (cx > cxmax)
	{
		cout<<"Program too long\n";
		return;
	}
	code[cx].f= x;
	code[cx].l= y;
	code[cx].a= z;
	//cout<<"cx="<<cx<<"++++++++++++++++"<<fctmap[code[cx].f]<<setw(5)<<code[cx].l<<setw(5)<<code[cx].a<<"+++++++++++"<<endl;
	cx++;
}//gen end

void PL0::Test(SYMSET s1,SYMSET s2,int n)
{
	if(sourceEnd)return;
	if (s1.find(sym)==s1.end())
	{
		Error(n,linecount);
		SYMSET::iterator it;
		for(it=s2.begin();it!=s2.end();it++)
			s1.insert(*it);//s1=s1+s2
		while (s1.find(sym)==s1.end())
			Getsym();
	}
}//test end
void PL0::Test(SYMSET s1,SYMSET s2,string s)
{
	if(sourceEnd)
		return;
	if(s1.find(sym)==s1.end())
	{
		Error(s,linecount);
		SYMSET::iterator it;
		for(it=s2.begin();it!=s2.end();it++)
			s1.insert(*it);
		while(s1.find(sym)==s1.end())
			Getsym();
	}
}

void PL0::Enter(OBJ k,int &tx,int &dx,int lev)
{
	if(tx==txmax)
	{
		cout<<"符号表溢出"<<endl;
		return;
	}
	int j,l,i;
	j=btab[DISPLAY[lev]].last,l=j;
	i=strcmp(id,table[j].name);
	while((i!=0)&&j!=0)
	{
		j=table[j].link;
		i=strcmp(id,table[j].name);
	}
	if(j!=0)
		Error(28,linecount);//标识符重复定义
	else
	{
		tx= tx+1;
		strcpy(table[tx].name,id);
		table[tx].link=l;
	    table[tx].kind=k;
		table[tx].ref=0;
	    table[tx].level=lev;
		switch(k)
		{
		case CONSTANT:
			switch(sym)
			{
			case CNUM:
				table[tx].val=num;
			    table[tx].type=chars;
				//table[tx].ref=0;
			    break;
			case INUM:
				table[tx].val=num;
			    table[tx].type=ints;
				//table[tx].ref=0;
			    break;
			case RNUM:
				table[tx].val=num;
				table[tx].type=reals;
				//table[tx].ref=0;
				break;
			}
			break;
		case VARIABLE:
			
		    table[tx].adr=dx;
		    dx++;
		    break;
		case PARAMETER:
			//table[tx].ref=0;
		    table[tx].adr=dx;
		    dx++;
		    break;
			//case PROCEDURE:
			//table[tx].ref=bx;
		    //break;
			//case FUNCTION:
		    //table[tx].ref=bx;
		    //break;
		}
	}
	btab[DISPLAY[lev]].last=tx;
}

int PL0::Position(ALFA id,int lev)
{
	int i,j,k;
	i=lev,strcpy(table[0].name,id);
	do
	{
		j=btab[DISPLAY[i]].last;
		k=strcmp(table[j].name,id);
		while(k!=0)
		{
			j=table[j].link;
            k=strcmp(table[j].name,id);
		}
		i--;
	}while(i!=0&&j==0);
	return j;
}
void PL0::Constdeclaration(int &tx,int &dx,int lev)
{
	SYMBOL opr=NUL;
	if(sym==IDENT)
	{
		Getsym();
		if(sym==EQL||sym==BECOMES)
		{
			if(sym==BECOMES)
				Warning("常量声明应该用=,而不是':='",linecount);//Error(1)
			Getsym();
			if(sym==MINUS||sym==PLUS)
			{
				opr=sym;
				Getsym();
			}
			if(sym==CNUM||sym==INUM||sym==RNUM)
			{
				if(opr==MINUS)
				{
					num=-num;
					opr=NUL;
				}
				switch(sym)
				{
				case CNUM:
					//tp=chars;
					Enter(CONSTANT,tx,dx,lev);
					//table[tx].type=tp;
					Getsym();
					break;
				case INUM:
					//tp=ints;
					Enter(CONSTANT,tx,dx,lev);
					//table[tx].type=tp;
					Getsym();
					break;
				case RNUM:
					//tp=reals;
					Enter(CONSTANT,tx,dx,lev);
					//table[tx].type=tp;
					Getsym();
					break;
				}	

			}
			else
				Error(2,linecount);//=号后应为字符,整数或实数
		}
		else
		Error(3,linecount);//标识符后应该为=
	}
	else
	{
		Error(4,linecount);//const,var,procedure,function后面应该是标识符
	}
}

void PL0::Vardeclaration(int&tx,int&dx,int lev)
{
	TYP tp=notyp;
	int t0,t1;
	//Getsym();
	while(sym==IDENT)
	{
		t0=tx;
		
		Enter(VARIABLE,tx,dx,lev);
		Getsym();
		while(sym==COMMA)
		{
			Getsym();
			Enter(VARIABLE,tx,dx,lev);
			Getsym();
		}
		if(sym==COLON)
			Getsym();
		else
			Error(29,linecount);//变量声明应该以冒号标识
		t1=tx;
		switch(sym)
		{
		case CHARSYM:
			tp=chars;
			Getsym();
			break;
		case INTSYM:
			tp=ints;
			Getsym();
			break;
		case REALSYM:
			tp=reals;
			Getsym();
			break;
		default:
			Error(31,linecount);//变量声明缺少类型标识符
			Getsym();
			
		}
		while(t0<t1)
		{
			t0++;
			table[t0].type=tp;
		}
		if(sym==SEMICOLON)
			Getsym();
		else
			Error(5,linecount);//变量声明后缺少分号
		//test();
	}
}

void PL0::Parameterlist(int &tx,int &dx,int lev)
{
	TYP tp=notyp;
	int t0;
	Getsym();
	while(sym==IDENT||sym==VARSYM)
	{
		if(sym==VARSYM)
			Getsym();
		t0=tx;
		if(sym==IDENT)
		{
			Enter(VARIABLE,tx,dx,lev);
		}
		else
			Error(32,linecount);//形式参数不能为空
		Getsym();
		while(sym==COMMA)
		{
			Getsym();
			if(sym==IDENT)
				Enter(VARIABLE,tx,dx,lev);
			else
				Error(32,linecount);//形式参数不能为空
			Getsym();
		}
		if(sym==COLON)
		{
			Getsym();
			if(sym==CHARSYM||sym==INTSYM||sym==REALSYM)
			{
				switch(sym)
				{
				case CHARSYM:
					tp=chars;
					break;
				case INTSYM:
					tp=ints;
					break;
				case REALSYM:
					tp=reals;
					break;
				}
			}
			else
				Error(33,linecount);//缺少参数类型说明符
			//Test();
		}
		else
			Error(29,linecount);//缺少':',在说明类型时必须有此冒号
		while(t0<tx)
		{
			t0++;
			table[t0].type=tp;
		}
		Getsym();
		if(sym!=RPAREN)
		{
			if(sym==SEMICOLON)
				Getsym();
			else
			{
				Error(5,linecount);//应该是分号
				if(sym==COMMA)
					Getsym();
			}
			//Test();
		}
	}
	if(sym==RPAREN)
	{
		Getsym();
		//SYMSET temp;

		//Test();
	}
	else
		Error(41,linecount);//缺少右括号')'
}
void PL0::Procdeclaration(int &tx,int &dx,int lev,SYMSET &fsys)
{
	bool flag=false;
	if(sym==FUNCSYM)
		flag=true;
	Getsym();
	if(sym!=IDENT)
		Error(42,linecount);//缺少函数名
	if(flag==true)
		Enter(FUNCTION,tx,dx,lev);
	else
		Enter(PROCEDURE,tx,dx,lev);
	Getsym();
	SYMSET temp;
	temp=fsys;
	temp.insert(SEMICOLON);
	
	Block(flag,lev+1,temp);
	if(sym==SEMICOLON)
		Getsym();
	else
		Error(5,linecount);//缺少分号';'
	//生成语句
}

void PL0::Block(bool isfun,int lev,SYMSET fsys)
{
	int dx;
	int tx0;
	int cx0;
	//int tx0;
	int bx0;
	int x;
	

	dx=4;
	tx0=tx;
	table[tx].adr=cx;
	Gen(Jmp,0,0);
	if(sourceEnd==true)
		return;
	if(lev>levmax)
		Error(43,linecount);//分程序嵌套层次超过最大层数3
	Enterblock(bx);
	bx0=bx,DISPLAY[lev]=bx;
	table[tx0].type=notyp;
	table[tx0].ref=bx0;
	if(sym==LPAREN&&lev>1)
		Parameterlist(tx,dx,lev);
	btab[bx0].lastpar=tx;
	btab[bx0].psize=dx;
	if(isfun)
	{
		if(sym==COLON)
		{
			Getsym();
			if(sym==CHARSYM||sym==INTSYM||sym==REALSYM)
			{
				switch(sym)
				{
				case CHARSYM:
					table[tx0].type=chars;
					break;
				case INTSYM:
					table[tx0].type=ints;
					break;
				case REALSYM:
					table[tx0].type=reals;
					break;
				}
				Getsym();
			}
			else
				Error("缺少函数返回值类型标识符",linecount);
			//SYMSET temp;

		}
		else
			Error("缺少冒号':'",linecount);
		//Getsym();
	}
	if(sym==SEMICOLON)
		Getsym();
	else
	{
		if(lev!=1)
			Error("缺少分号",linecount);
	}
	do
	{
		if(sym==CONSTSYM)
		{
			Getsym();
			Constdeclaration(tx,dx,lev);
			while(sym==COMMA)
			{
				Getsym();
				Constdeclaration(tx,dx,lev);
			}
			if(sym==SEMICOLON)
				Getsym();
			else
				Error("常量声明应该以分号结束",linecount);
		}
		if(sym==VARSYM)
		{
			Getsym();
			Vardeclaration(tx,dx,lev);
			
		}
		
		btab[bx0].vsize=dx;
		//Getsym();
		while(sym==PROCSYM||sym==FUNCSYM)
		{
			Procdeclaration(tx,dx,lev,fsys);
		}
	}while(declbegsys.find(sym)!=declbegsys.end());
	//PrintTable(tx);
	//cout<<"//----------------------------打印分程序索引表-------------------------------//"<<endl;
    //PrintBtab(bx);
//---------------------------------------------语句处理开始--------------------------------------------//
	code[table[tx0].adr].a=cx;
	table[tx0].adr=cx;
	cx0=cx;
	Gen(Int,0,dx);
    SYMSET temp;
	temp=fsys;
	temp.insert(SEMICOLON);
	temp.insert(ENDSYM);

	Statement(temp,lev);
	
	Gen(Opr,0,0);
	temp.clear();
	Test(fsys,temp,"");
	//Listcode();
}

⌨️ 快捷键说明

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