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

📄 pl02.java

📁 一个pl0 的很好的编译程序,完整的实验,可以很好的了解pl0的编译过程,已经编译的整个过程
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
						{
							cx2=cx;        //保存下一条目标代码的位置
							gen(fct.jmp,0,0);   //生成新的目标代码 ,当真语句被执行完成后跳出if语句
							code[cx1].a=cx; // 填充CX1的地址,即条件语句的假入口
							getsym();
							ptx=statement(fsys,ptx,lev);  //执行假语句
							code[cx2].a=cx; //回填 CX2,即整个if语句的出口
						}
						else
							code[cx1].a=cx;     /*经statement处理后,cx为then后语句执行
                            完的位置,它正是前面未定的跳转地址*/
					}
					else if(sym==symbol.beginsym)   /*准备按照复合语句处理*/
						{
							getsym();
							for(int j=0;j<symnum;j++)
								nxtlev[j]=fsys[j];
						
							nxtlev[symbol.semicolon.ordinal()]=true;
							nxtlev[symbol.endsym.ordinal()]=true;/*后跟符号为分号或end*/
							/*循环调用语句处理函数,直到下一个符号不是语句开始符号或收到end*/
							ptx=statement(nxtlev,ptx,lev);
							while(inset(sym.ordinal(),statbegsys)||sym==symbol.semicolon)
							{
								if(sym==symbol.semicolon)
								{
									getsym();
								}
								else
								{
									error(10);/*缺少分号*/
								}
								ptx=statement(nxtlev,ptx,lev);
							}
							if(sym==symbol.endsym)
							{
								getsym();
							}
							else
							{
								error(17); /*缺少end或分号*/
							}
						}
					else if(sym==symbol.whilesym)/*准备按照while语句处理*/
							{
								cx1=cx;        /*保存判断条件超作的位置*/
								getsym();
								for(int j=0;j<symnum;j++)
									nxtlev[j]=fsys[j];
								
								nxtlev[symbol.dosym.ordinal()]=true;/*后跟符号为do*/
								ptx=condition(nxtlev,ptx,lev);  /*调用条件处理*/
								cx2=cx;       /*保存循环体的结束的下一个位置*/
								gen(fct.jpc,0,0);/*生成条件跳转,但跳出循环的地址未知*/
								if(sym==symbol.dosym)
								{
									getsym();
								}
								else
								{
									error(18);      /*缺少do*/
								}
								ptx=statement(fsys,ptx,lev); /*循环体*/
								gen(fct.jmp,0,cx1);/*回头重新判断条件*/
								code[cx2].a=cx;   /*反填跳出循环的地址,与if类似*/
							}
						else
							{
								for(int j=0;j<symnum;j++)
								nxtlev[j]=false;	/*语句结束无补救集合*/
								test(fsys,nxtlev,19);/*检测语句结束的正确性*/
							}
		
	
	return ptx;
}

/*
*表达式处理
*/
int expression(boolean[] fsys,int ptx,int lev)
{
	symbol addop;int i;                    /*用于保存正负号*/
	boolean[] nxtlev=new boolean[symnum];
	if(sym==symbol.plus||sym==symbol.minus)             /*开头的正负号,此时当前表达式被看作一个正的或负的项*/
	{
		addop=sym;                    /*保存开头的正负号*/
		getsym();
		for(int j=0;j<symnum;j++)
			nxtlev[j]=fsys[j];
	
		nxtlev[symbol.plus.ordinal()]=true;
		nxtlev[symbol.minus.ordinal()]=true;
		ptx=term(nxtlev,ptx,lev);                /*处理项*/
		if(addop==symbol.minus)
		{
			gen(fct.opr,0,1);                   /*如果开头为负号生成取负指令*/
		}
/*这里*/
else if (sym==symbol.dplus || sym==symbol.dminus)
	{
        addop=sym; //  printf("这是2");                 
		getsym();
        if (sym==symbol.ident)
		{
           i=position(id,ptx);
           if (i==0)error(11);
           else
		   {
              if (table[i].kind==object.variable)
            	  gen(fct.lod,lev-table[i].level,table[i].adr);
              else error(25);
              gen(fct.lit,0,1);
              if (addop==symbol.dplus) gen(fct.opr,0,2);
              if (addop==symbol.dminus) gen(fct.opr,0,3);
              gen(fct.sto,lev-table[i].level,table[i].adr);
              gen(fct.lod,lev-table[i].level,table[i].adr);
              getsym();
           }
        }
       else error(25);
   }

	}
	else                             /*此时表达式被看作项的加减*/
	{  for(int j=0;j<symnum;j++)
		nxtlev[j]=fsys[j];
		nxtlev[symbol.plus.ordinal()]=true;
		nxtlev[symbol.minus.ordinal()]=true;
		ptx=term(nxtlev,ptx,lev);            /*处理项*/
	}
	while(sym==symbol.plus||sym==symbol.minus)
	{
		addop=sym;
		getsym();
		 for(int j=0;j<symnum;j++)
				nxtlev[j]=fsys[j];
		
		nxtlev[symbol.plus.ordinal()]=true;
		nxtlev[symbol.minus.ordinal()]=true;
		ptx=term(nxtlev,ptx,lev);              /*处理项*/
		if(addop==symbol.plus)
		{
			gen(fct.opr,0,2);                    /*生成加法指令*/
		}
		else
		{
			 gen(fct.opr,0,3);                /*生成减法指令*/
		}
	}
	return ptx;
}
/*
*项处理
*/
int term(boolean[]fsys,int ptx,int lev)
{
    symbol mulop;               /*用于保存乘除法符号*/
    boolean[] nxtlev=new boolean[symnum];
    for(int j=0;j<symnum;j++)
    	nxtlev[j]=fsys[j];
   
    nxtlev[symbol.times.ordinal()]=true;
    nxtlev[symbol.slash.ordinal()]=true;
    ptx=factor(nxtlev,ptx,lev);       /*处理因子*/
    while(sym==symbol.times||sym==symbol.slash)
    {
		mulop=sym;
        getsym();
        ptx=factor(nxtlev,ptx,lev);
        if(mulop==symbol.times)
        {
            gen(fct.opr,0,4);          /*生成乘法指令*/
        }
        else
        {
            gen(fct.opr,0,5);           /*生成除法指令*/
        }
    }
     return ptx;
}
/*
*因子处理
*/
int factor(boolean[] fsys,int ptx,int lev)
 {
    int i;//,isvar=0;
    boolean isvar=false;
    boolean[] nxtlev=new boolean[symnum];
    test(facbegsys,fsys,24);           /*检测因子的开始符好号*/
    while(inset(sym.ordinal(),facbegsys))          /*循环直到不是因子开始符号*/
    {
        if(sym==symbol.ident)                   /*因子为常量或者变量*/
        {
            i=position(id,ptx);        /*查找名字*/
            if(i==0)
            {
                error(11);               /*标识符未声明*/
            }
            else
            {
				switch(table[i].kind)
				{
					case constant:                                      /*名字为常量*/
						gen(fct.lit,0,table[i].val);                       /*直接把常量的值入栈*/
						break;
					case variable:                                      /*名字为变量*/
						gen(fct.lod,lev-table[i].level,table[i].adr); 
						isvar=true;     /*找到变量地址并将其值入栈*/
						break;
					case procedur:                                      /*名字为过程*/
						error(21);                                       /*不能为过程*/
						break;
				}
			}
			getsym();//这里
			if (isvar && (sym==symbol.dplus || sym==symbol.dminus))
			{
              if (i==0)  error(11);
              else{
                  // if (table[i].kind==variable)
					   gen(fct.lod,lev-table[i].level,table[i].adr);
                   //else {printf("这是3\n");error(25);}
                   gen(fct.lit,0,1);
                   if (sym==symbol.dplus) 
                	   gen(fct.opr,0,2);
                   if (sym==symbol.dminus)
                	   gen(fct.opr,0,3);
                   gen(fct.sto,lev-table[i].level,table[i].adr);
                 }
             getsym();
			}

		}
		else
		{
			if(sym==symbol.number)                                             /*因子为数*/
			{
				if(num>amax)
				{
					error(31);
					num=0;
				}
				gen(fct.lit,0,num);
				getsym();
				if ( (sym==symbol.dplus || sym==symbol.dminus)){
					//System.out.printf("这是4");
					//getchar();
                   gen(fct.lit,0,1);
                   if (sym==symbol.dplus)gen(fct.opr,0,2);
                   if (sym==symbol.dminus) gen(fct.opr,0,3);
                   getsym();
                }

			}
			else
			{
				if(sym==symbol.lparen)                                           /*因子为表达式*/
				{
					getsym();
					for(int j=0;j<symnum;j++)
						nxtlev[j]=fsys[j];
					
					nxtlev[symbol.rparen.ordinal()]=true;
					ptx=expression(nxtlev,ptx,lev);
					if(sym==symbol.rparen)
					{
						getsym();
					}
					else
					{
						error(22);                                       /*缺少右括号*/
					}
				}
				test(fsys,facbegsys,23);                        /*银子后有非法符号*/
			}
		}
	}
	return ptx;
}
/*
 条件处理*/
int condition(boolean[] fsys,int ptx,int lev)
{
    symbol relop;
    boolean[] nxtlev=new boolean[symnum];
    if(sym==symbol.oddsym)                        /*准备按照odd运算处理*/
   	{
		getsym();
		ptx=expression(fsys,ptx,lev);
		gen(fct.opr,0,6);                              /*生成odd指令*/
    }
    else
    {for(int j=0;j<symnum;j++)
    	nxtlev[j]=fsys[j];
		nxtlev[symbol.eql.ordinal()]=true;
		nxtlev[symbol.neq.ordinal()]=true;
		nxtlev[symbol.lss.ordinal()]=true;
		nxtlev[symbol.leq.ordinal()]=true;
		nxtlev[symbol.gtr.ordinal()]=true;
		nxtlev[symbol.geq.ordinal()]=true;
		ptx=expression(nxtlev,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(fsys,ptx,lev);
			switch(relop)
			{
				case eql:
					gen(fct.opr,0,8);
					break;
				case neq:
					gen(fct.opr,0,9);
					break;
				case lss:
					gen(fct.opr,0,10);
					break;
				case geq:
					gen(fct.opr,0,11);
					break;
				case gtr:
					gen(fct.opr,0,12);
					break;
				case leq:
					gen(fct.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.printf("%d",s[t-1]);
					//	fprintf(fa2,"%d",s[t-1]);
						t--;
						break;
					case 15:
						System.out.printf("\n");
						//fprintf(fa2,"\n");
						break;
					case 16:
						System.out.printf("?");
						//fprintf(fa2,"?");
						Scanner scanner = new Scanner(System.in); 
                        s[t]=scanner.nextInt();
						//fprintf(fa2,"%d\n",s[t]);
						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);
}
/*通过过程基址求上1层过程的基址*/
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 + -