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

📄 pl0c.txt

📁 pl0 扩展功能 包括++ -- 注释 for语句 repeat until语句 if else 语句
💻 TXT
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include "pl0.h"
#include "string.h"
#define stacksize 500
int main()
{
  bool nxtlev[symnum];
  printf("Input pl/0 file?");
  scanf("%s",fname);
  fin=fopen(fname,"r");
  if(fin)
  {
   printf("List object code? (Y/N)"); 
   scanf("%s",fname);
   listswitch=(fname[0]=='y'||fname[0]=='Y');
   printf("List symbol table? (Y/N)");
   scanf("%s",fname);
   tableswitch=(fname=='y'||fname=='Y');
   fal=fopen("fal.w","w");
   fprintf(fal,"Input pl/0 file?");
   fprintf(fal,"%s\n",fname); 
   init();
   err=0;
   cc=cx=ll=0;
   ch=' ';
   if(-1!=getsym())
   {
    fa=fopen("fa.tmp","w");
    fas=fopen("fas.tmp","w");
    addset(nxtlev,declbegsys,statbegsys,symnum);
    nxtlev[period]=true;
    if(-1==block(0,0,nxtlev))
    {
     fclose(fa);
     fclose(fal);
     fclose(fas);
     fclose(fin);
     printf("\n");
     return 0;
    }
    fclose(fa);
    fclose(fal);
    fclose(fas);
    if(sym!=period)
      {
       error(9);
	   printf("程序结尾丢了句号.\n");
      }
    if(err==0)
      {
       fa2=fopen("fa2.tmp","w");
       interpret();
       fclose(fa2);
	   scanf("%s",fname);
      }
     else
     { 
      printf("Errors in pl/0 program");
     }
    }
    fclose(fin);
   }
   else
   {
    printf("Can't open file! \n");
   }
   printf("\n");
   return 0;
}
void init()
{
   int i;
   for(i=0;i<=255;i++)
   {
    ssym[i]=nul;
   }
   ssym['+']=plus;
   ssym['-']=minus;
   ssym['*']=times;
   ssym['/']=slash;
   ssym['(']=lparen; 
   ssym[')']=rparen;
   ssym['=']=eql;
   ssym['?']=epus;
   ssym[',']=comma;
   ssym['.']=period;
   ssym['#']=neq;
   ssym[';']=semicolon;
   strcpy(&(word[0][0]),"begin");
   strcpy(&(word[1][0]),"call");
   strcpy(&(word[2][0]),"const");    
   strcpy(&(word[3][0]),"do");
   strcpy(&(word[4][0]),"dec");
   strcpy(&(word[5][0]),"diveql");
   strcpy(&(word[6][0]),"else");
   strcpy(&(word[7][0]),"end");
   strcpy(&(word[8][0]),"for");
   strcpy(&(word[9][0]),"if");
   strcpy(&(word[10][0]),"inc");
   strcpy(&(word[11][0]),"muleql");
   strcpy(&(word[12][0]),"odd");
   strcpy(&(word[13][0]),"procedure");
   strcpy(&(word[14][0]),"read");
   strcpy(&(word[15][0]),"repeat");
   strcpy(&(word[16][0]),"then");
   strcpy(&(word[17][0]),"until");
   strcpy(&(word[18][0]),"var");
   strcpy(&(word[19][0]),"while");
   strcpy(&(word[20][0]),"write");          
   wsym[0]=beginsym;
   wsym[1]=callsym;
   wsym[2]=constsym;
   wsym[3]=dosym;
   wsym[4]=decsym;
   wsym[5]=diveqlsym;
   wsym[6]=elsesym;
   wsym[7]=endsym;
   wsym[8]=forsym;
   wsym[9]=ifsym;
   wsym[10]=incsym;
   wsym[11]=muleqlsym;
   wsym[12]=oddsym;
   wsym[13]=procsym;
   wsym[14]=readsym;
   wsym[15]=repeatsym;
   wsym[16]=thensym;
   wsym[17]=untilsym;
   wsym[18]=varsym;
   wsym[19]=whilesym;
   wsym[20]=writesym;
   strcpy(&(mnemonic[lit][0]),"lit");
   strcpy(&(mnemonic[opr][0]),"opr");
   strcpy(&(mnemonic[lod][0]),"lod");
   strcpy(&(mnemonic[sto][0]),"sto");
   strcpy(&(mnemonic[cal][0]),"cal");
   strcpy(&(mnemonic[inte][0]),"int");
   strcpy(&(mnemonic[jmp][0]),"jmp");
   strcpy(&(mnemonic[jpc][0]),"jpc");
   for(i=0;i<symnum;i++)
   {
    declbegsys[i]=false;
    statbegsys[i]=false;
    facbegsys[i]=false;
   }
   declbegsys[constsym]=true;
   declbegsys[varsym]=true;
   declbegsys[procsym]=true;
   statbegsys[beginsym]=true;
   statbegsys[callsym]=true; 
   statbegsys[ifsym]=true;
   statbegsys[whilesym]=true;
   facbegsys[ident]=true;
   facbegsys[number]=true;
   facbegsys[lparen]=true;
}


int inset(int e,bool * s)
{ 
  return s[e];
}
int addset(bool * sr,bool * s1,bool * s2,int n)
{ int i;
  for(i=0;i<n;i++)
  { 
   sr[i]=s1[i]||s2[i];
  }
  return 0;
}
intsubset(bool * sr,bool * s1,bool * s2,int n)
{ 
  int i;
  for(i=0;i<n;i++)
  {
   sr[i]=s1[i]&&(!s2[i]);
  }
  return 0;
}
int mulset(bool * sr,bool * s1,bool * s2,int n)
{
  int i;
  for(i=0;i<n;i++)
  {
   sr[i]=s1[i]&&s2[i];
  }
  return 0;
}
void error(int n)
{
  char space[81];
  memset(space,32,81);
  space[cc-1]=0;
  fprintf(fal,"%d\n",space,n);
  err++;
}
int getch()
{
  if(cc==ll)
  {
   if(feof(fin))
   {
    printf("program incomplete");
    return -1;
   }
   ll=0;
   cc=0;
   printf("%d",cx);
   fprintf(fal,"%d",cx);
   ch=' ';
   while(ch!=10)
   {
    if(EOF==fscanf(fin,"%c",&ch))
    {
     line[ll];
     break;
    }
    printf("%c",ch);
    fprintf(fal,"%c",ch);
    line[ll]=ch;
    ll++;
   }
   printf("\n");
   fprintf(fal,"\n");
  }
  ch=line[cc];
  cc++;
  return 0; 
}
int getsym()
{
	int i,j,k;
	while(ch==' '||ch==10||ch==9||ch=='?')
	{
		if(ch=='?')
		{
		   getchdo;
           while(ch!='?')
		   {
             getchdo;
		   }
		   getchdo;
		}	
		else
		{
			getchdo;
		}
	}
	if(ch>='a'&&ch<='z')
	{
		k=0;
		do{
			if(k<al)
			{
				a[k]=ch;
				k++;
			}
			getchdo;
		}while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');
		a[k]=0;
		strcpy(id,a);
		i=0;
		j=norw-1;
		do{
			k=(i+j)/2;
			if(strcmp(id,word[k])<=0)
			{
				j=k-1;
			}
			if(strcmp(id,word[k])>=0)
			{
				i=k+1;
			}
		}while(i<=j);
		if(i-1>j)
		{
			sym=wsym[k];
		} 
		else
		{  
			sym=ident;
		}
	}
	else
	{
		if(ch>='0'&&ch<='9')
		{
			k=0;
			num=0;
			sym=number;
			do{
				num=10*num+ch-'0';
				k++;
				getchdo;
			}while(ch>='0'&&ch<='9');
			k--;
			if(k>nmax)
			{
				error(30);
				printf("数字位数过长\n");
			}
		}
		else
		{
			if(ch==':') 
			{
				getchdo;
				if(ch=='=')
				{
					sym=becomes;
					getchdo;
				}  
				else
				{
					sym=nul;
				}
			}
			else
			{
				if(ch=='<') 
				{
					getchdo;
					if(ch=='=')
					{
						sym=leq;
						getchdo;
					}
					else
					{
						sym=lss;
					}
				}
				else
				{
					if(ch=='>') 
					{
						getchdo;
						if(ch=='=')
						{
							sym=geq;
							getchdo;
						}
						else
						{
							sym=gtr;
						}   
					}
					else
					{
						if(ch=='+')
						{
							getchdo;
							if(ch=='+')
							{
								sym=incsym;
								getchdo;
							}
							else
							{
								sym=plus;
								
							}
						}
						else
						{
							if(ch=='-')
							{
								getchdo;
								if(ch=='-')
								{
									sym=decsym;
									getchdo;
								}
								else
								{
									sym=minus;
									
								}
							}
							else
							{
								if(ch=='*')
								{
									getchdo;
									if(ch=='=')
									{
										sym=muleqlsym;
										getchdo;
									}
									else
									{
										sym=times;
										
									}
								}
								else
								{
									if(ch=='/')
									{
										getchdo;
										if(ch=='=')
										{
											sym=diveqlsym;
											getchdo;
										}
										else
										{
											sym=slash;
											
										}
									}
									else
									{
										sym=ssym[ch];
										if(sym!=period)
										{
											getchdo;
										} 
									}
								}
							}
						}
					}
				}
			}
		}
	}
    return 0;
}
int gen(enum fct x,int y,int z)
{
  if(cx>=cxmax)
  {
   printf("Program too long");
   return -1;
  }
  code[cx].f=x;
  code[cx].l=y;
  code[cx].a=z;
  cx++;
  return 0;
}

int test(bool * s1,bool * s2,int n)
{
 if(!inset(sym,s1))
 {
  error(n);
  while((!inset(sym,s1))&&(!inset(sym,s2)))
  {
    getsymdo; 
  }
 } 
 return 0;
}
 
int block(int lev,int tx,bool * fsys)
{
 int i;
 int dx;
 int tx0,cx0;
 bool nxtlev[symnum];
 dx=3;
 tx0=tx;
 table[tx].adr=cx;
 gendo(jmp,0,0);
 if(lev>levmax)
 {
  error(32); 
  printf("read语句中括号中的标识符不是变量\n");
 }
 do{
   if(sym==constsym)
   {
    getsymdo;
    do{
      constdeclarationdo(&tx,lev,&dx);
      while(sym==comma)
      {
       getsymdo;
       constdeclarationdo(&tx,lev,&dx);
      }
      if(sym==semicolon)
      {
       getsymdo;
      }
      else
      {
       error(5);
	   printf("漏掉了,或;\n");
      }
    }while(sym==ident);
   }
   if(sym==varsym)
   {
    getsymdo;
    do{
      vardeclarationdo(&tx,lev,&dx);
      while(sym==comma)
      {
       getsymdo;
       vardeclarationdo(&tx,lev,&dx);
      }
      if(sym==semicolon)
      {
        getsymdo;   
      }
      else
      {
        error(5);
		printf("漏掉了,或;\n");
      }
    }while(sym==ident);
   }    
   while(sym==procsym)
   {
    getsymdo;
    if(sym==ident) 
    {
     enter(procedur,&tx,lev,&dx);
     getsymdo;
    }
     else
     {
      error(4);
	  printf("const,var,procedure后应为标识符\n");
     }
    if(sym==semicolon)
    {
     getsymdo;
    }
    else
    {
     error(5);
	 printf("漏掉了,或;\n");
    }
    memcpy(nxtlev,fsys,sizeof(bool)*symnum);
    nxtlev[semicolon]=true;
    if(-1==block(lev+1,tx,nxtlev))
    {
     return -1;
    }
    if(sym==semicolon)
    {
     getsymdo;
     memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);
     nxtlev[ident]=true;
     nxtlev[procsym]=true;
     testdo(nxtlev,fsys,6);
    }
    else
    {
     error(5);
	 printf("漏掉了,或;\n");
    }
   }
   memcpy(nxtlev,statbegsys,sizeof(bool));
   nxtlev[ident]=true;
   nxtlev[period]=true;
   testdo(nxtlev,declbegsys,7);
  }while(inset(sym,declbegsys));   
  code[table[tx0].adr].a=cx;
  table[tx0].adr=cx;
  table[tx0].size=dx;
  cx0=cx;
  gendo(inte,0,dx);
  if(tableswitch)
  {
   printf("TABLE:\n");
   if(tx0+1>tx)
   {
    printf("NULL\n");
   }
   for(i=tx0+1;i<=tx;i++)
   { 
    switch(table[i].kind)
    {
     case constant:
       printf("%d const %s",i,table[i].name);
       printf("val=%d\n",table[i].val);
       fprintf(fas,"%d const %s",i,table[i].name);
       fprintf(fas,"val=%d\n",table[i].val);
       break;
     case variable:
       printf("%d var %s",i,table[i].name);
       printf("lev=%d addr=%d\n",table[i].level,table[i].adr);
       fprintf(fas,"%d var %s",i,table[i].name);
       fprintf(fas,"lev=%d addr=%d\n",table[i].level,table[i].adr);
       break;
     case procedur:
       printf("%d proc %s",i,table[i].name);
       printf("lev=%d addr=%d size=%d\n",table[i].level,table[i].adr,table[i].size);
       fprintf(fas,"%d proc %s",i,table[i].name);
       fprintf(fas,"lev=%d addr=%d size=%d\n",table[i].level,table[i].adr,table[i].size);
       break;
    }
   }
    printf("\n");
   }
   memcpy(nxtlev,fsys,sizeof(bool)*symnum);
   nxtlev[semicolon]=true;
   nxtlev[endsym]=true;
   statementdo(nxtlev,&tx,lev);
   gendo(opr,0,0);
   memset(nxtlev,0,sizeof(bool)*symnum);
   testdo(fsys,nxtlev,8);
   listcode(cx0);
   return 0;
}

void enter(enum object k,int * ptx,int lev,int * pdx)
{
 (*ptx)++;
 strcpy(table[(*ptx)].name,id);
 table[(*ptx)].kind=k;
 switch(k)
 {
  case constant:
    if(num>amax)
    {
     error(31);
	 printf("数越界\n");
     num=0;
    }
    table[(*ptx)].val=num;
    break;
  case variable:
    table[(*ptx)].level=lev;
    table[(*ptx)].adr=(*pdx);
    (*pdx)++;
    break;
  case procedur:
    table[(*ptx)].level=lev;
    break;
 }
}
 
int position(char * idt,int tx)
{
 int i;
 strcpy(table[0].name,idt);
 i=tx;
 while(strcmp(table[i].name,idt)!=0)
 {
   i--;
 }
 return i;
}

int constdeclaration(int *ptx,int lev,int *pdx)
{
 if(sym==ident)
 {
   getsymdo;
   if(sym==eql||sym==becomes)
   {
    if(sym==becomes)
    {
     error(1);
	 printf("常数说明中的=写成:=\n");
    }
    getsymdo;
    if(sym==number)
    {
     enter(constant,ptx,lev,pdx);
     getsymdo;
    }
    else
    {
     error(2);
	 printf("常数说明中的=后面应是数字\n");
    }
   }
   else
   {
    error(3);
	printf("常数说明中标识符后应是=\n");
   }
 }
 else
 {
  error(4);
  printf("const,var,procedure后应为标识符\n");
 }
 return 0;
}

int vardeclaration(int *ptx,int lev,int pdx)
{
 if(sym==ident)
 {
   enter(variable,ptx,lev,pdx);
   getsymdo;
 }
 else
 {
  error(4);
  printf("const,var,procedure后应为标识符\n");
 }
 return 0;
} 

void listcode(int cx0)
{
 int i;
 if(listswitch)
 {
  for(i=cx0;i<cx;i++)
  {
   printf("%d%s%d%d\n",i,mnemonic[code[i].f],code[i].l,code[i].a);
   fprintf(fa,"%d%s%d%d\n",i,mnemonic[code[i].f],code[i].l,code[i].a);
  }
 }
}

int statement(bool * fsys,int *ptx,int lev)
{
 static int i,cx1,cx2,cx3,cx4;
 bool nxtlev[symnum];
 if(sym==ident)
 {

⌨️ 快捷键说明

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