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

📄 pl0.cpp

📁 pl0小型编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "pl0.h"	
#include <string.h>
#include <stdio.h>
#define stacksize 500	/* 解释执行时使用的栈 */ 
int main()
{

 bool nxtlev[symnum];
 printf("Input pl0 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[0]=='y'||fname[0]=='Y');
	fa1=fopen("fa1.tmp","w");
	fprintf(fa1,"Input file? ");
	fprintf(fa1,"%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(fa1);
	   fclose(fas);
    fclose(fin);
    printf("\n");
    return 0;
   }
    fclose(fa);
    fclose(fa1);
       fclose(fas);
    if(sym!=period)
	    error(9);
    if(err==0)
		 {
	  fa2=fopen("fa2.tmp","w");
	  interpret(); /* 调用解释执行程序 */
	  fclose(fa2);
		} 
  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['*']=times;
  ssym['/']=slash;
  ssym['(']=lparen;
  ssym[')']=rparen;
  ssym['=']=eql;
  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]),"end");
  strcpy(&(word[5][0]),"if");
  strcpy(&(word[6][0]),"odd");
  strcpy(&(word[7][0]),"procedure");
  strcpy(&(word[8][0]),"read");
  strcpy(&(word[9][0]),"then");
  strcpy(&(word[10][0]),"var");
  strcpy(&(word[11][0]),"while");
  strcpy(&(word[12][0]),"write");
  /* 设置保留字符号 */
  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;
  /* 设置指令名称 */
  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]),"inte");
  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;
}
int subset(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; /* 出错时当前符号已经读完,所以cc-1 */ 
   printf("****%s!%d\n",space,n);
   fprintf(fa1,"****%s!%d\n",space,n);
   err++; 
}
/* 漏掉空格,读取一个字符;每次读一行,存入line 缓冲区,line 被getsym 取空后在读一行。被函数getsym 调用 */
int getch()
{
	if(cc==ll)
	{
		if(feof(fin))
		{
			printf("program incomplete");
			return -1;
		}
		ll=0;
		cc=0;
		printf("%d",cx);
		fprintf(fa1,"%d",cx);
		ch=' ';
		while(ch!=10)
		{
			if(EOF==fscanf(fin,"%c",&ch))
			{
				line[ll]=0;
				break;
			}
			printf("%c",ch);
			fprintf(fa1,"%c",ch);
			line[ll]=ch;
			ll++;
		}
		printf("\n");
		fprintf(fa1,"\n");
	}
	ch=line[cc];
	cc++;
	return 0;
}
/* 词法分析,获取一个符号 */
int getsym()
{
   int i,j,k;
   while(ch==' '||ch==10||ch==9)	/* 忽略空格、换行和TAB */
   {
    getchdo;
   }
   if(ch>='a'&&ch<='z')	/* 名字或保留字以a..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')
    {        /* 检测是否为数字:以0..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);
    }
    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
        {
         sym=ssym[ch]; /* 当符号不满足上述条件时,全部按照单字符符号处理 */
         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)

⌨️ 快捷键说明

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