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

📄 pl0doc.cpp

📁 PL0语言的编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			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();
			//MyPointer=MyAssitPointer;
			//i = Position(temp);	
			Expression(lev,tx);
			//Generate((Functions)3,lev-table[i].level,table[i].address);//opr =3
			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;
	}	
}

//程序块分析
void CPL0Doc::Block(int lev,int tx)
{
	
	int RelDepth=3;//开头留出三个空间,用来存放一些链接参数用
    int TX0;
	int CIndex0;
	TX0 = TXCode;//保存前一个过程在符号表中的位置,以便在下面反填
	//TXCode;//++
	CIndex0=CIndex;//保存跳转的地址,以便在下面反填要转移到的地方
	//table[TX0].address = TXCode;//???????????????????
	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	,退出该层
}

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=GetNextView(p);
			cv->SetWindowText(result);
		}
	}

	return flag;	
}


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

	return base0;
}

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];
						        /*Top --;
						        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 --;
							   if(Stack[Top+1]!=0)
								   Stack[Top] /= Stack[Top+1];
							   else
							   {
								   MessageBox(0,"除数不能为零!!程序将终止执行!","警告!!",MB_OK);
								   Ip=0;
								   interrupt=true;
							   }

						   }
						   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=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:{//
						       //写换行
						       //并写到文件中去
							}
							break;
					case 16:{//read
						       Top ++;
							   
							   Show Input;
							   Input.DoModal();
							   Stack[Top]=Input.m_Variable;
							   if(Input.flag)
							   {
								   Ip=0;
								   interrupt=true;
							   }
							   //在屏摸上显示提示信息  “请输入:”
							   //同时将提示信息写到文件中去
							   //读入数据,并存放在栈顶中
							   //将读入的数据保存到文件中去*/
							}
							break;
					default:{   //添加出错处理信息,未定义的运算类型
							}
							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;
		}

	/*	 if(Input.flag)
		 {
			 Ip=0;
			 interrupt=true;
		 }*/
	}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);
	 cv=GetNextView(p);	 
	 

	bool   Interrupt=false;
	int    Count=1;
	for(int i=0;i<StackSize;i++)
		Stack[i]=-842150451;
	
	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->SetWindowText(a);	

}

void CPL0Doc::OnSynHelp() 
{
	// TODO: Add your command handler code here
	CString  n;
	n.Empty();
	n+=(char)13;
	n+=(char)10;
	CString text;
	text.Empty();
	text+=n;	
	text+="                                               语法规范说明: "+n  ;
	text+=n;                                                       
	text+="(1)  <程序>::=<分程序>."+n;
	text+="(2)  <分程序>::=[<常量说明部分>][<变量说明部分>][<过程说明部分>]<语句>"+n;
	text+="(3)  <常量说明部分>::=const<常量定义>{,<常量定义>};"+n;
	text+="(4)  <常量定义>::=<标识符>=<整数>"+n;
	text+="(5)  <整数>::={-|+}<数字>{,<数字>}"+n;
	text+="(6)  <变量说明部分>::=var<标识符>{,<标识符>};"+n;
	text+="(7)  <标识符>::=<字母>{<字母>|<数字>}"+n;
	text+="(8)  <过程说明部分>::=<过程首部><分程序>{;<过程说明部分>};"+n;
	text+="(9)  <过程首部>::=procedure<标识符>;"+n;
	text+="(10) <语句>::=<赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<空>"+n;
	text+="(11) <赋值语句>::=<标识符>:=<表达式>"+n;
	text+="(12) <复合语句>::=begin<语句>{;<语句>}end"+n;
	text+="(13) <条件>::=<表达式><关系运算符><表达式>|odd<表达式>"+n;
	text+="(14) <表达式>::=[+|-]<项>{<加减运算符><项>}"+n;
	text+="(15) <项>::=<因子>{<乘除法运算符><因子>}"+n;
	text+="(16) <因子>::=<标识符>|<无符号整数>|(<表达式>)"+n;
	text+="(17) <加减法运算符>::=+|-"+n;
	text+="(18) <乘除法运算符>::=*|/"+n;
	text+="(19) <关系运算符>::=  =|#|<|<=|>|>="+n;
	text+="(20) <条件运算符号>::=if<条件>then<语句>"+n;
	text+="(21) <过程调用语句>::=call<标识符>"+n;
	text+="(22) <当型循环语句>::=while<条件>do<标识符"+n;
	text+="(23) <读语句>::=read(<标识符>{,<标识符>})"+n;
	text+="(24) <写语句>::=write(<表达式>{,<表达式>})"+n;
    text+="(25) <字母>::= a|b|c|d|……|X|Y|Z"+n;
	text+="(26) <数字>::= 0|1|2|……|8|9"+n;
	text+="(27) <注释语句>::= \\……"+n;
	text+=" 符号的解释:::=表示“定义为”;<>表示语法构造成分(非终结符); |表示或;     {  }表示可重复选(0或多个);[ ]任选项;( )其内成分优先"+n;


	SynHelp  HelpDialog;
	HelpDialog.m_HelpContext = text;
	HelpDialog.DoModal();
	
}

⌨️ 快捷键说明

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