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

📄 pl0doc.cpp

📁 编译原理实践教程PL0语言编译程序源代码。参考书:清华大学出版社的《编译原理》作者吕映芝、张素琴等。 实现主要功能有:对使用PL0语言编写的程序进行词法分析
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	{   
		Advanced();
		Expression(lev,tx);//完成		
		Advanced();
	}
}


//项分析
void CPL0Doc::Term(int lev,int tx,int i)
{
    int mulop;
	if(i==1)
		Advanced();
	Factor(lev,tx);//第一个因子,得到结果
	while(Sym == 15||Sym == 16)// * is 15  while  / is 16
	{
		mulop = Sym;
		Advanced();
		Factor(lev,tx);//第二个因子,得到结果
		if(mulop == 15)
			Generate((Functions)2,0,4);//栈顶两个元素相乘,结果放在次栈顶
		else 
			Generate((Functions)2,0,5);//栈顶两个元素相除,结果放在次栈顶
	}
}


//表达式
void CPL0Doc::Expression(int lev,int tx)
{
	
    int addop;
	addop = Sym;
	if(Sym == 13||Sym == 14)//定符号数 + is 13   - is 14
	{
		//Advanced();
		Term(lev,tx);
		if(addop == 14)
			Generate((Functions)2,0,1);//是负数opr = 2
	}
	else//不是 + 或 -	
		Term(lev,tx,0);

	while(Sym == 13||Sym == 14)
	{
		addop = Sym;
		//Advanced();
		Term(lev,tx);
		if(addop == 13)
			Generate((Functions)2,0,2);//  +
		else 
			Generate((Functions)2,0,3);// -
	}
}

//条件判断中的条件真假判断
void CPL0Doc::Condition(int lev,int tx)
{
	int relop ;//关系运算符
	if(Sym == 29)//oddsym = 29
	{	
		Advanced();
		Expression(lev,tx);		
		Generate((Functions)2,0,6);//取反opr = 2
	}
	else
	{
		    Expression(lev,tx);//离开时,顺带一个 标识符   表达式 1		
			relop = Sym;	
			Advanced();
			Expression(lev,tx); //表达式 2
			switch(relop)              //两个表达式进行运算  opr =2
			{
			    case 20:Generate((Functions)2,0,8);break;//eql = 20
				case 28:Generate((Functions)2,0,9);break;//neq = 28
				case 18:Generate((Functions)2,0,10);break;//lss = 18 
				case 22:Generate((Functions)2,0,11);break;//geq = 22
				case 21:Generate((Functions)2,0,12);break;//gtr = 21
				case 19:Generate((Functions)2,0,13);break;//leq = 19
			}
	}
}

//语句处理部分
void CPL0Doc::Statement(int lev,int tx)
{
	int cx1,cx2;
	int i = -1;
	//分支 identifier
	if(Sym == 888)//"ident"
	{	
		i = Position(temp);		
		Advanced();	
		Advanced();	
		Expression(lev,tx);		
		Generate((Functions)4,lev-table[i].level,table[i].address);//sto =4
	}
    //分支 read
	else if(Sym == 10)//readsym
	{	
		Advanced();
		do
		{			
			Advanced();			
			i = Position(temp);		
			Generate((Functions)2,0,16);//opr =2
			Generate((Functions)4,lev-table[i].level,table[i].address);//sto =4				
			Advanced();

		}while(Sym == 27 );//comma		
		Advanced();
	}
	//分支write

	else if(Sym == 9)//writesym = 9
	{
		Advanced();
		do
		{		
			Advanced();
			Expression(lev,tx);
			Generate((Functions)2,0,14);	//opr =2		
		}while(Sym == 27);  //comma   = 27  	
		Advanced();
		Generate((Functions)2,0,15);//opr
	}
	//分支 call
	else if(Sym == 8)//callsym
	{
		i = -1;	
		Advanced();		
		i = Position(temp);		
		Generate((Functions)5,lev-table[i].level,table[i].address);// cal	 = 5	
		Advanced();		
	}
	//分支 if
	else if(Sym == 3)//ifsym = 3
	{
		Advanced();
		Condition(lev,tx);			  
		Advanced();		
		cx1 = CIndex;
		Generate((Functions)8,0,0);//待返填,当条件为假时,跳转jpc
		Statement(lev,tx);
		Codes[cx1].Addr = CIndex;//跳到语句结束处
	}
	//分支 begin
	else if(Sym == 1)//beginsym = 1
	{				
		do
		{			
			Advanced();
			Statement(lev,tx);			
		}while(Sym == 26 );//分号semicolon	= 26
		Advanced();
	}

	//分支 while
	else if(Sym == 11)//whilesym = 11
	{
		cx1 = CIndex;	
		Advanced();
		Condition(lev,tx);
		cx2 = CIndex;
		Generate((Functions)8,0,0);//jpc = 8
		Advanced();		
		Statement(lev,tx);
		Generate((Functions)7,0,cx1);//jmp = 7
		Codes[cx2].Addr = CIndex;
	}
	else error(33);
}

//程序块分析
void CPL0Doc::Block(int lev,int tx)
{
	
	int RelDepth=3;//开头留出三个空间,用来存放一些链接参数用
    int TX0;
	int CIndex0;
	TX0 = TXCode;//保存前一个过程在符号表中的位置,以便在下面反填
	CIndex0=CIndex;//保存跳转的地址,以便在下面反填要转移到的地方
	Generate((Functions)7,0,0);//"jmp"	
	do
	{
		if(Sym == 6)//constsym
		{		
			Advanced();			
			Constdeclaration(RelDepth);	
			Advanced();
		
		}

		if(Sym == 5)//"varsym"
		{	
			Vardeclaration(RelDepth);	
			Advanced();			
		}


		if(Sym == 7)//"procsym"
		{			
			TXCode++;
			Advanced();
			Advanced();
			Advanced();
			Block(lev + 1,tx);			
			Advanced();
		}		
	}while((Sym ==5|| Sym==6||Sym ==7));//   var const procedure;
	//下面开始语句部分的处理
	Codes[CIndex0].Addr=CIndex;
	table[TX0].address = CIndex;
	table[TX0].size = RelDepth;//为变量分配
	TX0 = TXCode;
	Generate((Functions)6,0,RelDepth);//init =1
	Statement(lev,tx);
	Generate((Functions)2,0,0);//opr =2	,退出该层
}

int CPL0Doc::Base(int lev)
{
	int base0;
	base0 = CurBase;
	while(lev > 0)
	{
		base0 = Stack[base0];
		lev --;
	}

	return base0;
}

bool CPL0Doc::OnCodesAnalyze() 
{
	bool flag=false;
	if(OnSyntaxAnalyze()==true)		
	{		      
		if(twoelement.head!=NULL)
		{		
			Advanced(0);			
			TXCode = 0;	
			CIndex = 0;	
			Block(0,0);					
			flag=true;
			CString result;			
			result.Empty();					
			result+="中间代码已经生成!";	
			CView* cv;			
			POSITION p=GetFirstViewPosition();
			cv=GetNextView(p);	
			cv->SetWindowText(result);
		}
	}

	return flag;	
}


void CPL0Doc::Interpret(bool & interrupt,int count)
{
	Top = 0;
	CurBase = 1;
	Ip = 0;
	Stack[1] = 0;
	Stack[2] = 0;
	Stack[3] = 0;
	do
	{
		Instructor = Codes[Ip];
		Ip ++;
		switch(Instructor.function)
		{
		    case 1:Stack[++Top] = Instructor.Addr;break;//lit
			case 2://opr
				switch(Instructor.Addr)
				{
				    case 0:{//subproc finished
						        Top = CurBase - 1;
						        Ip = Stack[Top+3];
						        CurBase = Stack[Top+2];
						   }
						   break;
					case 1:Stack[Top] = -Stack[Top];break;//reverse
					case 2:{//add
						        Top --;
								Stack[Top] += Stack[Top+1];
						   }
						   break;
					case 3:{//minus
						        Top --;
								Stack[Top] -= Stack[Top+1];
						   }
						   break;
					case 4:{//mul
						       Top --;
							   Stack[Top] *= Stack[Top+1];
						   }
						   break;
					case 5:{//div
						       Top --;
							   Stack[Top] /= Stack[Top+1];
						   }
						   break;
					case 6:Stack[Top] = (int)!Stack[Top];//odd
						   break;
					case 8:{//=
						       Top --;
							   Stack[Top] = (int)(Stack[Top]==Stack[Top+1]);
						   }
						   break;
					case 9:{//!=
						       Top --;
							   Stack[Top] = (int)(Stack[Top] != Stack[Top+1]);
						   }
						   break;
					case 10:{//<
						       Top --;
							   Stack[Top] = (int)(Stack[Top] < Stack[Top+1]);
							}
							break;
					case 11:{//>=
						       Top --;
							   Stack[Top] = (int)(Stack[Top] >=Stack[Top+1]);
							}
							break;
					case 12:{//>
						       Top --;
							   Stack[Top] = (int)(Stack[Top] > Stack[Top+1]);
							}
							break;
					case 13:{//<=
						       Top --;
							   Stack[Top] = (int)(Stack[Top] <= Stack[Top+1]);
							}
							break;
					case 14:{//write						       
					           CString  str;
						       CString result;
							   result.Empty();
							   str.Empty();
						       CView* cv;
							   POSITION p=GetFirstViewPosition();
							   cv=GetNextView(p);
							   cv->GetWindowText(result);
							   str.Format("%d",count++);
							   result+="输出["+str+"]"+":";
							   str.Empty();
							   str.Format("   %d",Stack[Top]);
							   result+=str+(char)13+(char)10;
							   cv->SetWindowText(result);							   
						       //将栈顶元素写出来 
						       //同时 写进文件
						       Top--;
							}
							break;
					case 15:{
								//换行分支,写在case 14: 中
							}
							break;
					case 16:{//read
						       Top ++;
							   
							   CAnotherShow Input;
							   Input.DoModal();
							   Stack[Top]=Input.m_Variable;
							   if(Input.flag)
							   {
								   Ip=0;
								   interrupt=true;
							   }
							}
							break;
					default:{   
								error(33);
							}
							break;
				}
				break;
			case 3:{//lod
				            Top ++;
							Stack[Top] = Stack[Base(Instructor.levdiff) + Instructor.Addr];
					   }
					   break;
			case 4:{//sto
				           Stack[Base(Instructor.levdiff) + Instructor.Addr] = Stack[Top];
						   Top --;
					   }
					   break;
			case 5:{//cal
				           Stack[Top+1] = Base(Instructor.levdiff);
						   Stack[Top+2] = CurBase;
						   Stack[Top+3] = Ip;
						   CurBase=Top+1;
						   //Top
						   Ip = Instructor.Addr;
					   }
					   break;
			case 6:Top = Top + Instructor.Addr;break;//int
				       
			case 7:Ip = Instructor.Addr;break;//jmp
				       
			case 8:{//jpc
				           if(Stack[Top] == 0)
							   Ip = Instructor.Addr;
						   Top --;
					   }
					   break;
			default:{
					}
					break;
		}
	}while(Ip !=0);
}


void CPL0Doc::OnExecute() 
{
	// TODO: Add your command handler code here
     CString result;
	 result.Empty();	
	 CView * cv;
	 POSITION p=GetFirstViewPosition();	 	
	 cv=GetNextView(p);	 

	bool   Interrupt=false;
	int    Count=1;
	
	if(OnCodesAnalyze())
	{
		cv->SetWindowText(result);
		Interpret(Interrupt,Count);
	}	
	 CString finished;
	 finished.Empty();
	 if(Interrupt==false)
		 finished+="执行完毕";
	 else
		 finished+="中途停止";	
	 result.Empty();
	 cv->GetWindowText(result);	
	 
	 result+=finished;
	 cv->SetWindowText(result);
}

					
	

void CPL0Doc::OnCodesview() 
{
	// TODO: Add your command handler code here
	CString a,b,c,d,e,n;		
	n+=(char)13;
	n+=(char)10;	
	a.Empty();
	a+="代码:(功能,层差,偏移地址|数值)"+n;
	for(int i=0;i<CIndex;i++)
	{
		b.Empty();
		c.Empty();
		d.Empty();
		e.Empty();
		switch(Codes[i].function)
		{
		case 1:b="lit";break;
		case 2:b="opr";break;
		case 3:b="lod";break;
		case 4:b="sto";break;			
		case 5:b="cal";break;	
		case 6:b="init";break;
		case 7:b="jmp";break;
		case 8:b="jpc";break;		
		}	
		c.Format("%d",Codes[i].levdiff);
		d.Format("%d",Codes[i].Addr);	
		e.Format("%d",i);
		a+=( e+":       " + b+ " ----- " + c+ " ----- "+ d+ "      " + n );			
	}	
	 CView* cv;
	 POSITION p=GetFirstViewPosition();
	 cv=GetNextView(p);
	 cv=GetNextView(p);
	 cv=GetNextView(p); 	 
	 cv->SetWindowText(a);	
}


void CPL0Doc::OnInstru() 
{
	// TODO: Add your command handler code here
	CInstruction dlg;
	dlg.DoModal();
	
}

⌨️ 快捷键说明

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