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

📄 pl0.java

📁 pl0的好的编译程序,通过这个程序可以很好的了解编译的过程,掌握编译器的运行原理!
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	if(sym==Symbol.ident)
	{
		x=enter(Object.variable,ptx,lev,pdx);
		getsym();
	}
	else
	   error(4);
   
   return x;
}

void listcode(int cx0)
{
	int i;
  	for(i=cx0;i<cx;i++)
  	{	if(code[i].f==Function.inte)
  		  System.out.printf("%d %s %d %d\n",i,"int",code[i].l,code[i].a);
     	else   System.out.printf("%d %s %d %d\n",i,code[i].f.name(),code[i].l,code[i].a);
  	}
  	
}

int statement(int ptx,int lev)
{
	int i,cx1,cx2;
   	if(sym==Symbol.ident)
   	{
		i=position(token,ptx);
   	 	if(i!=0)
   	 	{
   	 		if(table[i].kind==Object.variable)
   	 		{
   	 	        getsym();
	 			if(sym==Symbol.assign)
	 			{
	 				getsym();
	 				ptx=expression(ptx,lev);
	 			}
	 			else
	 				error(13);
	 		 	gen(Function.sto,lev-table[i].level,table[i].adr);
	 			
   	 		 	
   	 		}
   	 		else
   	 		{
   	 		   error(12);
	 		 i=0;
   	 	    }
   		}
   	 		
   	 	else error(11);
   	
    }
    else if(sym==Symbol.readsym)
    	{
    	 	getsym();
    	 	if(sym==Symbol.lparen)
    	 	{
    	 		do{
	   			getsym();
	   	   		if(sym==Symbol.ident)
	   	   		    i=position(token, ptx);
	   	   		else
	   	   		  i=0;
	   	   	  
	   	   		
	   	     if(i!=0)
	   	   		{
	   	   			gen(Function.opr,0,16);
					gen(Function.sto,lev-table[i].level,table[i].adr);	//储存到变量
				}
	   	   else
	   		   error(35);
				getsym();
			}while (sym==Symbol.comma);
    	 	  
			}
    	    else
			error(34);
			
			if(sym==Symbol.rparen)
				getsym();
		}
	else if(sym==Symbol.writesym)		
			{
				getsym();
				if(sym==Symbol.lparen)
				{
					do{
						getsym();
						ptx=expression(ptx,lev);
						gen(Function.opr,0,14);//生成输出指令,输出栈顶的值
					}while(sym==Symbol.comma);
					if(sym==Symbol.rparen)
						getsym();	
					else
						error(33);
					
				}
				gen(Function.opr,0,15);		//输出换行
			}
	else if(sym==Symbol.callsym)		
		{
					getsym();
				
		if(sym==Symbol.ident)
		{
			i=position(token,ptx);
			if(i!=0){
				
			if(table[i].kind==Object.procedure)
			    gen(Function.cal,lev-table[i].level,table[i].adr);  //生成call指令
			else
				 error(15);     
			}
			else
				error(11);   
						getsym();
		}
			else error(14);
		}
  else if(sym==Symbol.ifsym)    
	{
		getsym();
		ptx=condition(ptx,lev);  
		if(sym==Symbol.thensym)
				getsym();
		else
				error(16);         
		cx1=cx;                //保存当前指令地址
		gen(Function.jpc,0,0);        //生成条件跳转指令,跳转地址暂写0
		ptx=statement(ptx,lev);   //处理then后的语句
		code[cx1].a=cx;     //地址回填,经statement处理后,cx为then后语句执行完的位置,它正是前面未定的跳转地址
	}
	else if(sym==Symbol.beginsym)   
	{
		getsym();
		ptx=statement(ptx,lev);
		while(sym==Symbol.beginsym|sym==Symbol.callsym|sym==Symbol.ifsym|sym==Symbol.whilesym|sym==Symbol.semicolon)
		{
		   if(sym==Symbol.semicolon)
			   getsym();
		    else
		    	error(10);
			ptx=statement(ptx,lev);
		}
		if(sym==Symbol.endsym)
		     getsym();
		else
			error(17); 
		}
	else if(sym==Symbol.whilesym)
	{
		cx1=cx;        //保存判断条件的位置
		getsym();
		ptx=condition(ptx,lev); 
		cx2=cx;       //保存循环体的结束的下一个位置
		gen(Function.jpc,0,0);//生成条件跳转,但跳出循环体的地址未知
		if(sym==Symbol.dosym)
		   getsym();
		else
			error(18);     
								
		ptx=statement(ptx,lev); 
		gen(Function.jmp,0,cx1);//回头重新判断条件
		code[cx2].a=cx;   //回填跳出循环体的地址
	}
	
	return ptx;
}


int expression(int ptx,int lev)
{
	Symbol addop;

	if(sym==Symbol.plus||sym==Symbol.minus)           
	{
		addop=sym; // 保存开头的正负号
		getsym();
		
		ptx=term(ptx,lev);
		if(addop==Symbol.minus)
			gen(Function.opr,0,1);//如果开头为负号生成取负指令
	}
	else                            
		ptx=term(ptx,lev);           
	
	while(sym==Symbol.plus||sym==Symbol.minus)
	{
		addop=sym;
		getsym();
		
		ptx=term(ptx,lev);            
		if(addop==Symbol.plus)
			gen(Function.opr,0,2);              
		
		else
			 gen(Function.opr,0,3);           		
	}
	return ptx;
}

int term(int ptx,int lev)
{
    Symbol mulop;               //用于保存乘除法符号
     ptx=factor(ptx,lev);      
    while(sym==Symbol.multiply||sym==Symbol.divide)
    {
		mulop=sym;
        getsym();
        ptx=factor(ptx,lev);
        if(mulop==Symbol.multiply)
            gen(Function.opr,0,4);      
        else
            gen(Function.opr,0,5);        
        
    }
     return ptx;
}

int factor(int ptx,int lev)
 {
    int i;
  
    while(sym==Symbol.ident|sym==Symbol.number|sym==Symbol.lparen)         
    {
        if(sym==Symbol.ident)                 
        {
            i=position(token,ptx);        
           
            if(i!=0)  
            	switch(table[i].kind)
				{
					case constant:                                      
						gen(Function.lit,0,table[i].val);  //直接把常量的值入栈
						break;
					case variable:                                
						gen(Function.lod,lev-table[i].level,table[i].adr); //找到变量地址并将其值入栈
						break;
					case procedure:                                     
						error(21);                                      
						break;
				}
			
            else
                error(11);              
            
			getsym();


		}
	else if(sym==Symbol.number)                                             
		{	gen(Function.lit,0,num);
				getsym();
			}
	else if(sym==Symbol.lparen)                                         
		{		getsym();
				ptx=expression(ptx,lev);
				if(sym==Symbol.rparen)
					getsym();
				else
					error(22);                                     
					
		}
	}
	return ptx;
}

int condition(int ptx,int lev)
{
    Symbol relop;
  
    if(sym==Symbol.oddsym)                        
   	{
		getsym();
		ptx=expression(ptx,lev);
		gen(Function.opr,0,6); //生成odd指令
    }
    else
    {
		ptx=expression(ptx,lev);
		if(sym!=Symbol.eql&&sym!=Symbol.neq&&sym!=Symbol.lss&&sym!=Symbol.leq&&sym!=Symbol.gtr&&sym!=Symbol.geq)
		{
			error(20);
		}
		else
		{
			relop=sym;
			getsym();
			ptx=expression(ptx,lev);
			switch(relop)
			{
				case eql:
					gen(Function.opr,0,8);
					break;
				case neq:
					gen(Function.opr,0,9);
					break;
				case lss:
					gen(Function.opr,0,10);
					break;
				case geq:
					gen(Function.opr,0,11);
					break;
				case gtr:
					gen(Function.opr,0,12);
					break;
				case leq:
					gen(Function.opr,0,13);
					break;
			}

		}
    }
    return ptx;
}                            

void interpret()
{
	int p,b,t;            
	Instruction i;  //存放当前指令
	int[] s=new int[stackSize];   
	System.out.printf("start pl0\n");
	t=0;
	b=0;
	p=0;
	s[0]=s[1]=s[2]=0;
	do{
		i=code[p];         //读当前指令
		p++;
		switch(i.f)
		{
			case lit:        //将常数a的值取到栈顶
				s[t]=i.a;
				t++;
				break;
			case opr:        
				switch(i.a)
				{
					case 0:
						t=b;
						p=s[t+2];
						b=s[t+1];
						break;
					case 1://取反
						s[t-1]=-s[t-1];
						break;
					case 2://求和
						t--;
						s[t-1]=s[t-1]+s[t];
						break;
					case 3://求差
						t--;
						s[t-1]=s[t-1]-s[t];
						break;
					case 4://求乘积
						t--;
						s[t-1]=s[t-1]*s[t];
						break;
					case 5://求除法
						t--;
						s[t-1]=s[t-1]/s[t];
             			break;
					case 6://奇偶判断
						s[t-1]=s[t-1]%2;
						break;
					case 8://两个数是否相等
						t--;
						if(s[t-1]==s[t])
						s[t-1]=1;
						else
							s[t-1]=0;
 						break;
					case 9://两个数是否不等
						t--;
						if(s[t-1]!=s[t])
						s[t-1]=1;
						else s[t-1]=0;
 						break;
					case 10://第一是否小于第二个
						t--;
						if(s[t-1]<s[t])
						s[t-1]=1;
						else 
							s[t-1]=0;
 						break;
					case 11://第一个数是否大于等于第二个
						t--;
						if(s[t-1]>=s[t])
						s[t-1]=1;
						else
							s[t-1]=0;
 						break;
					case 12://第一个数是否大于
						t--;
						if(s[t-1]>s[t])
						s[t-1]=1;
						else
							s[t-1]=0;
 						break;
					case 13://第一个数是否小于等于
						t--;
						if(s[t-1]<=s[t])
						s[t-1]=1;
						else s[t-1]=0;
 						break;
					case 14://输出
						System.out.print("The result is:");
						System.out.printf("%d",s[t-1]);
						t--;
						break;
					case 15://换行
						System.out.printf("\n");
						break;
					case 16://读入
						System.out.printf("Enter a integer:");
						Scanner scanner = new Scanner(System.in); 
                        s[t]=scanner.nextInt();
						t++;
						break;
				}
				break;
			case lod:       //取相对当前过程的数据基地址为a的内存的值到栈顶
				s[t]=s[base(i.l,s,b)+i.a];
				t++;
				break;
			case sto:       //栈顶的值存到相对当前过程的数据基地址为a的内存
				t--;
	            s[base(i.l,s,b)+i.a]=s[t];
				break;
			case cal:           
				s[t]=base(i.l,s,b); //将父过程基地址入栈
				s[t+1]=b;           //将本过程基地址入栈,主要用于base函数
				s[t+2]=p;           //将当前指令指针入栈
				b=t;            //    改变基地址指针值为新过程的基地址
				p=i.a;           //   跳转
				break;
			case inte:            
				t+=i.a;
				break;
			case jmp:           
				p=i.a;
				break;
			case jpc:             
				t--;
				if(s[t]==0)
					p=i.a;
				
	    		break;
		}
	}while (p!=0);
}

int base(int l,int[] s,int b)
{
	int b1;
	b1=b;
	 while(l>0)
	 {
		 b1=s[b1];
     	 l--;
	 }
	 return b1;
}



}

⌨️ 快捷键说明

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