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

📄 pl0v4.c

📁 C语言写的PL0文法编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
  } else
  if (sym==callsym) {
    getsym();
    if (sym!=ident) error(14); else
    { i=position(id, ptx); 
      if(i==0) error(11); else
      {
      getsym();
      if (sym==lparen) {getsym(); aparam(lev,ptx); 
        if (sym==rparen) getsym(); else error(89);
      }
      if (table[i].kind==procedure) gen(cal,lev-table[i].level, table[i].adr);
      else error(15); 
      }
    }
  } else
  if (sym==ifsym) {
     getsym(); condition(lev,ptx);
     if (sym==thensym) getsym(); else error(16);
     cx1=cx; gen(jpc,0,0);
     statement(lev, ptx); code[cx1].a=cx; 
  } else
  if (sym==beginsym) {
    getsym();
    statement(lev,ptx);
    while((sym==semicolon)||(sym==beginsym)||
          (sym==ifsym)||(sym==whilesym)||
          (sym==callsym)||(sym==writesym)||  
          (sym==dspsym)) {
      if(sym==semicolon) getsym(); else error(10);
      statement(lev,ptx);
    }
    if (sym==endsym) getsym(); else error(17);
  } else
  if (sym==whilesym) {
    cx1=cx; getsym(); condition(lev,ptx);
    cx2=cx; gen(jpc,0,0);
    if (sym==dosym) getsym(); else error(18);
    statement(lev,ptx); gen(jmp,0,cx1); code[cx2].a=cx;
  } else
  if (sym==writesym) {
    getsym(); 
    if (sym!=lparen) error(98); else {
      getsym(); expression(lev, ptx); gen(wrt,0,0);
      if (sym!=rparen) error(99); else getsym(); 
    }
  }
  if (sym==dspsym) {
    getsym(); 
    if (sym!=lparen) error(98); else {
      getsym(); expression(lev, ptx); gen(dsp,0,0);
      if (sym!=rparen) error(99); else getsym(); 
    }
  }
  if (sym==colorsym) {
    getsym(); 
    if (sym!=lparen) error(98); else {
      getsym(); expression(lev,ptx); gen(clr,0,0);
      if (sym!=rparen) error(99); else getsym(); 
    }
  }
  if (sym==drawsym) {
    getsym(); 
    if (sym!=lparen) error(98); else {
      getsym(); expression(lev, ptx); 
      getsym(); expression(lev, ptx); 
      if (sym!=rparen) error(99); else getsym(); 
      gen(drw,0,0);
    }
  }
  if (sym==erasesym) {
    getsym(); 
    if (sym!=lparen) error(98); else {
      getsym(); expression(lev, ptx); 
      getsym(); expression(lev, ptx); 
      if (sym!=rparen) error(99); else getsym(); 
      gen(ers,0,0);
    }
  }
}
fparam(lev,ptx,pdx)
  int lev, *ptx,*pdx; 
{   
	if (sym==varsym) {flag=1; getsym();} else flag=0;
	if(sym==ident)vardeclaration(lev,ptx,pdx); else error(81);
    flag=0;
	while (sym==comma){
   getsym();if (sym==varsym) {flag=1; getsym();} else flag=0;
   vardeclaration(lev,ptx,pdx); flag=0;
   }  
   if(sym!=rparen) error(82);
}
aparam(lev,ptx)
  int lev, *ptx;
{
 int pnum=0; int adr,level;
 if(sym==amper) {
	 getsym(); if(sym!=ident) error(70);
	 i=position(id,ptx); adr=table[i].adr; level=table[i].level;
	 gen(lda,lev-level,adr); getsym();} 
     else expression(lev,ptx);
	 pnum++;
 while (sym==comma){ 
	 getsym(); 
	 if(sym==amper){
		 getsym(); if (sym!=ident) error(70);
		 i=position(id,ptx); adr=table[i].adr; level=table[i].level;
		 gen(lda,lev-level,adr); getsym();}
	     else expression(lev,ptx);
		 pnum++;  
 }
 while(pnum>0){gen(stp,0,3); pnum--;}
}
block(lev, tx)
int lev;
int tx;
{
  int dx, tx0, cx0;
  dx=3; tx0=tx; table[tx].adr=cx; gen(jmp,0,0);
  if (lev>levmax) error(32);
  do {
    if (sym==constsym) {
      getsym();
      do {
        constdeclaration(lev,&tx,&dx);
        while(sym==comma) {
          getsym(); constdeclaration(lev,&tx,&dx);
        }
        if(sym==semicolon)getsym(); else error(5);
      } while (sym==ident);
    }
    if (sym==varsym) {
      getsym();
      do { vardeclaration(lev,&tx,&dx);
        while (sym==comma) {
          getsym(); vardeclaration(lev,&tx,&dx);
        }
      if(sym==semicolon) getsym(); else error(5);
      } while(sym==ident);
    }
    if (sym==lparen) {
      getsym(); fparam(lev,&tx,&dx);
      if (sym==rparen) getsym(); else error(88);
    }
    while(sym==procsym) {
      getsym();
      if(sym==ident){
        enter(procedure,&tx,&dx,lev); getsym();
	  } else error(4);
      if (sym==semicolon) getsym(); else if 
        (sym==lparen); else error(5);
      block(lev+1, tx);
      if(sym==semicolon) {
        getsym();
      } else error(5);
    }
  }while ((sym==constsym)||(sym==varsym)||(sym==procsym));
  code[table[tx0].adr].a=cx;
  table[tx0].adr=cx;
  cx0=cx; gen(inc,0,dx);
  statement(lev,&tx);
  gen(opr,0,0);
}
int base(l,b)
  int l,b;
{  
  int b1; //find base l levels down
  b1=b; 
   while (l>0) {
    b1=s[b1]; l--;
   }
  return b1;
}
interpret()
{
  int stacksize=500;
  int p,b,t; //program-, base-, topstack-registers
  int i; // instruction register
  printf("start PL/0\n");
  t=0; b=1; p=0;
  s[1]=0; s[2]=0; s[3]=0;
  do {
    i=code[p].f; 
    switch (i) {
      case 1: t++; s[t]=code[p].a; p++; break; //lit
      case 2:
      switch (code[p].a) {
        case 0: { /* return */ t=b-1; p=s[t+3]; b=s[t+2];
                 break;}
        case 1: s[t]=-s[t]; p++; break;
        case 2: t--; s[t]=s[t]+s[t+1]; p++; break;
        case 3: t--; s[t]=s[t]-s[t+1]; p++; break;
        case 4: t--; s[t]=s[t]*s[t+1]; p++; break;
        case 5: t--; s[t]=s[t]/s[t+1]; p++; break;
        case 6: if ((s[t]%2)==1) s[t]=1; else s[t]=0; p++; break; 
        case 7: p++; break;
        case 8: t--; s[t]=(s[t]==s[t+1]); p++; break;
        case 9: t--; s[t]=(s[t]!=s[t+1]); p++; break;
        case 10: t--; s[t]=(s[t]<s[t+1]); p++; break;
        case 11: t--; s[t]=(s[t]<=s[t+1]); p++; break;
        case 12: t--; s[t]=(s[t]>s[t+1]); p++; break;
        case 13: t--; s[t]=(s[t]>=s[t+1]); p++; break;
      } break;
      case 3: t++; s[t]=s[base(code[p].l,b)+code[p].a]; p++; break;
      case 4: s[base(code[p].l,b)+code[p].a]=s[t];   
              p++; t--; break;
      case 5: /* generate new block mark */
         s[t+1]=base(code[p].l,b); s[t+2]=b; s[t+3]=p+1;
         b=t+1; p=code[p].a; break;
      case 6: t=t+code[p].a; p++; break;
      case 7: p=code[p].a; break;
      case 8: if (s[t]==0) p=code[p].a; else p++;
              t--; break;
      case 9: printf("%d\n",s[t]); t--; p++; break;
      case 10: s[t+3]=s[t]; t--; p++; break;
      case 11: t++; s[t]=s[s[base(code[p].l,b)+code[p].a]];p++; break;
      case 12: t++; s[t]=base(code[p].l,b)+code[p].a;p++;break;
      case 13: s[s[base(code[p].l,b)+code[p].a]]=s[t]; p++; t--; break;
      case 14: disp(s[t],s[t]); p++; t--; break;
      case 15: point(1,s[t-1],s[t]); p++; t--; t--; break;
      case 16: point(-1,s[t-1],s[t]); p++; t--; t--; break;
      case 17: setcolor(s[t]); p++; t--; break;
	}
//	printf("%d  ",p);
//	for(ii=1;ii<=t;ii++)printf("%d ", s[ii]);
//	getchar();
  } while (p!=0);
  printf(" END PL/0\n");
}
disp(ix,iy)
int ix,iy;
{
   d=XOpenDisplay((getenv("DISPLAY") != NULL)?getenv( "DISPLAY"):":0");
   f=XLoadFont(d,"r14");
   black = BlackPixel(d, 0);
   white = WhitePixel(d, 0);
   cmap=DefaultColormap(d,0);
   XAllocNamedColor(d,cmap,"red",&red,&c0);
   XAllocNamedColor(d,cmap,"green",&green,&c0);
   XAllocNamedColor(d,cmap,"blue",&blue,&c0);
   w=XCreateSimpleWindow(d,DefaultRootWindow(d),0,0,ix,iy,5,
   black, white);
   XSelectInput(d,w,ButtonPressMask|ButtonReleaseMask|ButtonMotionMask);
   XMapWindow(d,w);
   gc=XCreateGC(d,w,0,0);
   XSetFont(d,gc,f);
   XSetLineAttributes(d, gc, 2, LineSolid, CapRound, JoinRound);
//   XSetForeground(d, gc, black);
   XFlush(d);
}
setcolor(k)
int k;
{ 
  original=k;
  switch (k) {
    case 0: XSetForeground(d,gc,white); break;
    case 1: XSetForeground(d,gc,black); break;
    case 2: XSetForeground(d,gc,red.pixel); break;
    case 3: XSetForeground(d,gc,green.pixel); break;
    case 4: XSetForeground(d,gc,blue.pixel); break;
  }
  XFlush(d);
};
point(k,x,y)
int k,x,y;
{
  int temp;
//  if (k>0) XSetForeground(d,gc,red.pixel);
//      else XSetForeground(d,gc,white);
  temp=original;
  if (k<0) {
      XSetForeground(d,gc,white);
      XDrawPoint(d,w,gc,x,y);
      setcolor(temp);
  } else
  XDrawPoint(d,w,gc,x,y);
  XFlush(d);
}
main(argc,argv)
int argc;
char *argv[];
{

word[1]="begin"; word[2]="call"; word[3]="const"; word[4]="do";
word[5]="end"; word[6]="if"; word[7]="odd"; word[8]="procedure";
word[9]="then"; word[10]="var"; word[11]="while"; word[12]="write";
word[13]="display"; word[14]="draw"; word[15]="erase"; word[16]="color";
wsym[1]=beginsym; wsym[2]=callsym; wsym[3]=constsym; wsym[4]=dosym;
wsym[5]=endsym; wsym[6]=ifsym; wsym[7]=oddsym; wsym[8]=procsym;
wsym[9]=thensym; wsym[10]=varsym; wsym[11]=whilesym; wsym[12]=writesym;
wsym[13]=dspsym; wsym[14]=drawsym; wsym[15]=erasesym; wsym[16]=colorsym;
ssym['+']=plus; ssym['-']=minus; ssym['*']=mult; ssym['/']=slash;
ssym['(']=lparen; ssym[')']=rparen; ssym['=']=eql; ssym[',']=comma;
ssym['.']=period; ssym['#']=neq; ssym['<']=lss; ssym['>']=gtr;
ssym['$']=leq; ssym['%']=geq; ssym[';']=semicolon; ssym['&']=amper;
//scanf("%s",fname);
f=fopen(*++argv,"r");
kk=al;
cc=0; ll=0; ch=' '; cx=0;
getsym();
block(0,0);
getchar();
getchar();
for (i=0;i<=cx-1;i++) {
  if (i<10) printf(" ");
  printf("%d ",i);
  switch (code[i].f) {
    case 1: printf("lit "); break;
    case 2: printf("opr "); break;
    case 3: printf("lod "); break;
    case 4: printf("sto "); break;
    case 5: printf("cal "); break;
    case 6: printf("inc "); break;
    case 7: printf("jmp "); break;
    case 8: printf("jpc "); break;
    case 9: printf("wrt "); break;
    case 10: printf("stp "); break;
    case 11: printf("lid "); break;
    case 12: printf("lda "); break;
    case 13: printf("sid "); break;
    case 14: printf("dsp "); break;
    case 15: printf("drw "); break;
    case 16: printf("ers "); break;
    case 17: printf("clr "); break;
  }
  printf("%d ", code[i].l);
  printf("%d ", code[i].a);
  printf("\n");
//  getchar();
}
if (sym!=period) error(9);
getchar();
interpret();
getchar();
getchar();
}

⌨️ 快捷键说明

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