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

📄 pl0.c

📁 C语言的pl/0编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
          error(20); 
        relop= sym; 
        getsym(); 
        expression(fsys); 
        switch(relop)
        {
         case eql: gen(opr, 0, 8); break;
         case neq: gen(opr, 0, 9); break;
         case lss: gen(opr, 0, 10);break; 
         case geq: gen(opr, 0, 11);break; 
         case gtr: gen(opr, 0, 12);break; 
         case leq: gen(opr, 0, 13);break; 
        }
      }
}
//语句分析
//说明:引入临时集合tempset是为了函数临时参数传递用,nullset代表空集合
//pascal中支持集合的加减,且在参数传递时可直接用集合加表达式
//为次,在c中引入tempset,先将要传递的集合表达式所代表的集合记录下来,
//然后将它作临时参数穿递给被调用函数
void statement(symset fsys)
{
    symset tempset={0},nullset={0};
    if (sym == ident)
    {
      i = position(id); 
      if (i <0 )
         error(11);
      else
        if(table[i].kind != variable)
        {
          error(12);
          i= -1;/////////////////////////////////////////////////////////////6/25
        }
      getsym(); 
      if(sym ==becomes)
        getsym(); 
      else
        error(13); 
      expression(fsys); 
      if (i != -1)////////////////////////////////////////////////////////////6/25
          gen(sto, lev - table[i].level, table[i].adr); 
   }
    else
      if(sym == readsym) 
      {
        getsym(); 
        if (sym !=lparen)
          error(34); 
        else
        do
        {
            getsym(); 
            if (sym ==ident) 
               i=position(id);            
            else
              i= 0; 
            if(i==0)
              error(35); 
            else 
            {
                gen(opr, 0, 16); 
                gen(sto, lev - table[i].level, table[i].adr); 
             }
            getsym(); 
        }while(sym ==comma); 
        if(sym !=rparen)
        {
          error(33);
          while(IN(fsys,sym)==0)
            getsym();
        }
        else
          getsym(); 
      }
      else
        if(sym ==writesym)
        {
          getsym(); 
          if (sym == lparen)
          {
          do{
              getsym(); 
              tempset=fsys;
              tempset=ADD(tempset,rparen, comma);
              expression(tempset);
              gen(opr, 0, 14);
            }while( sym ==comma); 
            if( sym!=rparen ) 
              error(33); 
            else
              getsym(); 
          }
          gen(opr, 0, 15);
         
        }
        else
          if(sym == callsym)
          {
            getsym(); 
            if (sym != ident) 
              error(14); 
            else
            {
              i = position(id); 
              if (i == 0 )    //wrongs 14号14点 change i=0 to i==0
                error(11); 
              else
                  if (table[i].kind == procedur)  ///wrongs 14//14:00
                    gen(cal,lev-table[i].level,table[i].adr); 
                  else
                    error(15);   
              getsym(); 
            }
          }
        else
          if( sym ==ifsym)
          {
            getsym();
            
            tempset=fsys;              //13号14:00
			tempset=ADD(tempset,thensym, dosym);
            condition(tempset); 
            if (sym == thensym) 
              getsym();
            else
              error(16); 
            cx1 = cx; 
            gen(jpc, 0, 0); 
            statement(fsys); 
            code[cx1].a=cx; 
          }
          else
            if (sym == beginsym) 
            {
              getsym(); 
      
              tempset=fsys;
			  tempset=ADD(tempset,semicolon, endsym);
              statement(tempset);
              while(sym==semicolon||IN(statbegsys,sym))
              {
                if (sym == semicolon) 
                  getsym(); 
                else
                  error(10); 
                statement(tempset);     
              }
              if (sym == endsym)
                getsym(); 
              else
                error(17);                 //err=1??
            }
            else
              if( sym == whilesym)
              {
                cx1 = cx; 
                getsym();
               
                tempset=fsys;
				tempset=ADD(tempset,dosym);
                condition(tempset); 
                cx2 = cx; 
                gen(jpc, 0, 0); 
                if (sym == dosym)
                  getsym(); 
                else
                  error(18); 
                statement(fsys); 
                gen(jmp, 0, cx1);
                code[cx2].a = cx; 
              }
    test(fsys,nullset, 19); 
}

//block 函数
void block(symset fsys)/////////////////para changes!
{	
//lev++;	//18/10:44
	dx=3;
	tx0=tx;
	table[tx].adr=cx;
	gen(jmp,0,0);
	if(lev>levmax)
		error(32);
	do
	{
		if(sym==constsym)//常量处理
		{
			getsym();
			do
			{
				constdeclaration();
				while(sym==comma)
				{
					getsym();
					constdeclaration();//
				}
				if(sym==semicolon)
					getsym();
				else 
					error(5);
			}while(sym==ident);           //12/20:40 wrong change !=to==
		}
		if(sym==varsym)//变量处理
		{
			getsym();
			do
			{
				vardeclaration();//
				while(sym==comma)
				{
					getsym();
					vardeclaration();//
				}
				if(sym==semicolon)
					getsym();
				else 
					error(5);
			}while(sym==ident);
		}
		while(sym==procsym)//过程处理
		{
			getsym();
			if(sym==ident)
			{
				enter(procedur);//
				getsym();
			}
			else
				error(4);
			if(sym==semicolon)
				getsym();
			else 
				error(5);
			fsys=ADD(fsys,semicolon);//
			lev=lev+1;//嵌套调用block前先保存局部变量
			dxdx=dx;tx0tx0=tx0;cx0cx0=cx0;
			txtx=tx;
			block(fsys);
			tx=txtx;//调用后返回调用前的值
			dx=dxdx;tx0=tx0tx0;cx0=cx0cx0;
			lev--;//18/10:59////////////////////////////////////////////////////
			      ///////////////important change!
			//关于lev等block局部变量的处理见说明4
			if(sym==semicolon)
			{
				getsym();
				tempset=statbegsys;
				tempset=ADD(tempset,ident,procsym);
				test(tempset,fsys,6);
			}
			else
				error(5);
		}
		tempset=statbegsys;
		tempset=ADD(tempset,ident);
		test(tempset,declbegsys,7);
	}while(IN(declbegsys,sym));
	//语句处理
//	code[table[tx0].adr].a=cx; //将这一语句用下面的语句代替
	code[cx0].a=cx;            //!!!!important  6月25号
	table[tx0-1].adr=cx;////////////////////////////////////////////
	                   //important change!18/11;16
	table[tx0-1].size=dx;
	cx0=cx;
	gen(intr,0,dx);//
	tempset=fsys;
	tempset=ADD(tempset,semicolon,endsym);
	statement(tempset);                        //////
	gen(opr,0,0);
	test(fsys,nullset,8);//
	listcode();//
}
//interpret的局部变量
const stacksize=500;
int p,b,t;
struct instruction I;
int s[500];//程序运行栈

int base(int l)//注意数组下标!!!!!!!!!!!!!!!!!!1
{
    int b1;
    b1 = b;
    while (l > 0) 
    {
      b1 = s[b1]; 
      l = l - 1; 
    }
   return b1; 
}

void interpret()
{
  printf("start pl0\n"); 
  t =0; //change t=0 to t=-1 15//13:00
        //chang t=-1 to 0 at 18/17:37
  b = 1; 
  p = 0; 
  s[1] = 0; 
  s[2] = 0;
  s[3] = 0; 
  do{										//do_while start
    I = code[p]; 
    p = p + 1; 
	//I.a=1;
    switch(I.f)								//switch(I.f) start
    {
      case lit: 
      {
          t = t + 1;   //
          s[t] = I.a;
          break;
      }
      case opr: 
      {										//opr start
         switch(I.a )//(* operator *)		//switch(I.a) start
		 {  case 0: 
            {
              t = b - 1; 
              p = s[t + 3]; 
              b = s[t + 2];
              break; 
            }
            case 1: 
            {
              s[t] = -s[t];
  		      break;
  			}
            case 2: 
            {
              t = t - 1; 
              s[t] = s[t] + s[t + 1] ;
              break;
            }
            case 3: 
            {
              t = t - 1; 
              s[t] = s[t] - s[t + 1];
              break; 
            }
            case 4: 
            {
              t = t - 1; 
              s[t] = s[t] * s[t + 1];
              break; 
            }
            case 5: 
            {
              t = t - 1; 
              s[t] = s[t]/s[t + 1];
              break; 
            }
            case 6: 
            {
         	s[t] = (s[t]%2==1); ///?7
            	break;
            }
            case 8: 
            {
              t = t - 1;
              s[t] = (s[t] == s[t + 1]);
              break; 
            }
            case 9: 
            {
				t=t-1;//18:17:22
              s[t] = (s[t]!=s[t + 1]);//
              break; 
            }
            case 10: 
            {
              t = t - 1; 
              s[t] = (s[t] < s[t + 1]);
              break; 
            }
            case 11: 
            {
              t = t - 1; 
              s[t] = (s[t] >= s[t + 1]);
              break; 
            }
            case 12: 
            {
              t = t - 1;
              s[t] = (s[t] > s[t + 1]);
              break; 
            }
            case 13: 
            {
              t = t - 1; 
              s[t] = (s[t] <= s[t + 1]);
              break; 
            }
            case 14: 
            {
              printf("%d",s[t]); 
       
			  fputc(s[t],fa2);
              t = t - 1;
              break; 
            }
            case 15: 
            {
             // writeln;// 
             // writeln(fa2) //
				printf("%c",10);
				fputc(10,fa2);
             break;
            }
            case 16: 
            {
              t = t + 1; 
              
			  printf("?");
			  fputc('?',fa2);
			  scanf("%d",&s[t]);
			  fputc(s[t],fa2);
              break;
            }
        }							//switch(I.a) end
		break;
		}							//opr end
        case lod: 
        {
          t = t + 1; 
          s[t] = s[base(I.l) + I.a] ;
          break;
        }
        case sto: 
        {
          s[base(I.l) + I.a] = s[t]; 
          t = t - 1;
          break;
        }  
        case cal: 
        {
          s[t + 1] = base(I.l); 
          s[t + 2] = b; 
          s[t + 3] = p; 
      
          b = t + 1;
          p = I.a; 
          break;
        }
        case intr: 
        {
           t = t + I.a; 
           break;
        }
        case jmp: 
        {  
           p = I.a; 
           break;
         }
        case jpc: 
        {
          if (s[t] == 0)
            p = I.a; 
		  t=t-1;//?
           break;
        }
      }//end(* with,case *)	
	  //switch(I.f) end
	  //if(p==0)
	//	  p=p+1;
  }while(p!=0);        //6/25//////////							//do_while end
  fclose(fa2); 
}
//主函数
void main()
{
	char filename[20]; //////////////delete the char ch 
	int i;
	symset tempset={0};

	wsym[0]=beginsym;
	wsym[1]=callsym;
	wsym[2]=constsym;
	wsym[3]=dosym;
	wsym[4]=endsym;
	wsym[5]=ifsym;
	wsym[6]=oddsym;
	wsym[7]=procsym;
	wsym[8]=readsym;
	wsym[9]=thensym;
	wsym[10]=varsym;
	wsym[11]=whilesym;
	wsym[12]=writesym;

/*	mnemonic[0]=lit;
	mnemonic[1]=opr;
	mnemonic[2]=lod;
	mnemonic[3]=sto;
	mnemonic[4]=cal;
	mnemonic[5]=intr;
	mnemonic[6]=jmp;
	mnemonic[7]=jpc;*/

	declbegsys=ADD(declbegsys,constsym,varsym,procsym);
	statbegsys=ADD(statbegsys,beginsym,callsym,ifsym,whilesym);
	facbegsys=ADD(facbegsys,ident,number,lparen);

	fa1=fopen("fa1.txt","a");
	if(fa1==NULL)
	{
	  printf("fa1.txt is not exist!");
	  return ;
	}
	printf("input file?");
	fprintf(fa1,"input file?");
	i=0;
	while(i<20)
	{
	  scanf("%c",&filename[i]);
	  if(filename[i]=='\n')
	  {
	    filename[i]='\0';
	    break;
	  }
	  i++;
	}

	for(i=0;i<8&&isalpha(filename[i]);i++)
	{
	  ch=filename[i];
	  printf("%c",ch);
	  fputc(ch,fa1);
	}

	fin=fopen(filename,"r");             /**/
	if(fin==NULL)
	{
	  printf("file.txt is not exist!");
	  return ;
	}
	printf("list object code?");
	fprintf(fa1,"list object code?");
	scanf("%c",&ch);
	if(ch=='y')
	  listswitch=1;
	else
	  listswitch=0;

	err=0;
	cc=0;cx=0;ll=0;
	ch=32;kk=al;
	getsym();
	fa=fopen("fa.txt","a");//
	fa2=fopen("fa2.txt","a");//
	tempset=ADD(tempset,period,constsym,varsym,procsym,beginsym,callsym,ifsym,whilesym);
	lev=0;
	tx=0;
	block(tempset);
	fclose(fa);
	fclose(fa1);
	if(sym!=period)
		error(9);
	if(err==0)
		interpret();
	else 
		printf("errors in pl0 program!");
    fclose(fin);
	
}

⌨️ 快捷键说明

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