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

📄 pl0.c

📁 使用C语言实现的PL0编译器。 扩充了++ -- 以及添加注释功能
💻 C
字号:
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);
     }
     getsymdo;
     if(sym==number){
      enter(constant,ptx,lev,pdx);
      getsymdo;
     }
     else{
      error(2);
     }
    }
    else{
     error(3);
    }
}
else{
    error(4);
}
return 0;
}

int vardeclaration(int *ptx, int lev, int *pdx)
{
if(sym==ident){
    enter(variable,ptx,lev,pdx);
    getsymdo;
}
else{
    error(4);
}
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)
{
int i,cx1,cx2;
bool nxtlev[symnum];

if(sym==ident){
    i=position(id,*ptx);
    if(i==0){
     error(11);
    }
    else{
     if(table[i].kind!=variable){
      error(12);
      i=0;
     }
     else{
      getsymdo;
      if(sym==becomes){
       getsymdo;
      }
      else{
       error(13);
      }
      memcpy(nxtlev,fsys,sizeof(bool)*symnum);
      expressiondo(nxtlev,ptx,lev);
      if(i!=0){
       gendo(sto,lev-table[i].level,table[i].adr);
      }
     }
    }
}
else{
    if(sym==readsym){
     getsymdo;
     if(sym!=lparen){
      error(34);
     }
     else{
      do{
       getsymdo;
       if(sym==ident){
        i=position(id,*ptx);
       }
       else{
        i=0;
       }
       if(i==0){
        error(35);
       }
       else{
        gendo(opr,0,16);
        gendo(sto,lev-table[i].level,table[i].adr);
       }
       getsymdo;
      }while(sym==comma);
     }
     if(sym!=rparen){
      error(33);
      while(!inset(sym,fsys)){
       getsymdo;
      }
     }
     else{
      getsymdo;
     }
    }
    else{
     if(sym==writesym){
      getsymdo;
      if(sym==lparen){
       do{
        getsymdo;
        memcpy(nxtlev,fsys,sizeof(bool)*symnum);
        nxtlev[rparen]=true;
        nxtlev[comma]=true;
        expressiondo(nxtlev,ptx,lev);
        gendo(opr,0,14);
       }while(sym==comma);
       if(sym!=rparen){
        error(33);
       }
       else{
        getsymdo;
       }
      }
      gendo(opr,0,15);
     }
     else{
      if(sym==callsym){
       getsymdo;
       if(sym!=ident){
        error(14);
       }
       else{
        i=position(id,*ptx);
        if(i==0){
         error(11);
        }
        else{
         if(table[i].kind==procedur){
          gendo(cal,lev-table[i].level,table[i].adr);
         }
         else{
          error(15);
         }
        }
        getsymdo;
       }
      }
      else{
       if(sym==ifsym){
        getsymdo;
        memcpy(nxtlev,fsys,sizeof(bool)*symnum);
        nxtlev[thensym]=true;
        nxtlev[dosym]=true;
        conditiondo(nxtlev,ptx,lev);
        if(sym==thensym){
         getsymdo;
        }
        else{
         error(16);
        }
        cx1=cx;
        gendo(jpc,0,0);
        statementdo(fsys,ptx,lev);
        code[cx1].a=cx;
       }
       else{
        if(sym==beginsym){
         getsymdo;
         memcpy(nxtlev,fsys,sizeof(bool)*symnum);
         nxtlev[semicolon]=true;
         nxtlev[endsym]=true;
         statementdo(nxtlev,ptx,lev);
         while(inset(sym,statbegsys)||sym==semicolon){
          if(sym==semicolon){
           getsymdo;
          }
          else{
           error(10);
          }
          statementdo(nxtlev,ptx,lev);
         }
         if(sym==endsym){
          getsymdo;
         }
         else{
          error(17);
         }
        }
        else{
         if(sym==whilesym){
          cx1=cx;
          getsymdo;
          memcpy(nxtlev,fsys,sizeof(bool)*symnum);
          nxtlev[dosym]=true;
          conditiondo(nxtlev,ptx,lev);
          cx2=cx;
          gendo(jpc,0,0);
          if(sym==dosym){
           getsymdo;
          }
          else{
           error(18);
          }
          statementdo(fsys,ptx,lev);
          gendo(jmp,0,cx1);
          code[cx2].a=cx;
         }
         else{
          memset(nxtlev,0,sizeof(bool)*symnum);
          testdo(fsys,nxtlev,19);
         }
        }
       }
      }
     }
    }
}
return 0;
}
  
int expression(bool *fsys, int *ptx, int lev)
{
enum symbol addop;
bool nxtlev[symnum];

if(sym==plus||sym==minus){
    addop=sym;
    getsymdo;
    memcpy(nxtlev,fsys,sizeof(bool)*symnum);
    nxtlev[plus]=true;
    nxtlev[minus]=true;
    termdo(nxtlev,ptx,lev);
    if(addop==minus){
     gendo(opr,0,1);
    }
}
else{
    memcpy(nxtlev,fsys,sizeof(bool)*symnum);
    nxtlev[plus]=true;
    nxtlev[minus]=true;
    termdo(nxtlev,ptx,lev);
}
while(sym==plus||sym==minus){
    addop=sym;
    getsymdo;
    memcpy(nxtlev,fsys,sizeof(bool)*symnum);
    nxtlev[plus]=true;
    nxtlev[minus]=true;
    termdo(nxtlev,ptx,lev);
    if(addop==plus){
     gendo(opr,0,2);
    }
    else{
     gendo(opr,0,3);
    }
}
return 0;
}

int term(bool *fsys, int *ptx, int lev)
{
enum symbol mulop;
bool nxtlev[symnum];
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[times]=true;
nxtlev[slash]=true;
factordo(nxtlev,ptx,lev);
while(sym==times||sym==slash){
    mulop=sym;
    getsymdo;
    factordo(nxtlev,ptx,lev);
    if(mulop==times){
     gendo(opr,0,4);
    }
    else{
     gendo(opr,0,5);
    }
}
return 0;
}

int factor(bool *fsys, int *ptx, int lev)
{
int i;
bool nxtlev[symnum];

testdo(facbegsys,fsys,24);
while(inset(sym,facbegsys)){
    if(sym==ident){
     i=position(id,*ptx);
     if(i==0){
      error(11);
     }
     else{
      switch(table[i].kind){
       case constant:
        gendo(lit,0,table[i].val);
        break;
       case variable:
        gendo(lod,lev-table[i].level,table[i].adr);
        break;
       case procedur:
        error(21);
        break;
      }
     }
     getsymdo;
    }
    else{
     if(sym==number){
      if(num>amax){
       error(31);
       num=0;
      }
      gendo(lit,0,num);
      getsymdo;
     }
     else{
      if(sym==lparen){
       getsymdo;
       memcpy(nxtlev,fsys,sizeof(bool)*symnum);
       nxtlev[rparen]=true;
       expressiondo(nxtlev,ptx,lev);
       if(sym==rparen){
        getsymdo;
       }
       else{
        error(22);
       }
      }
      testdo(fsys,facbegsys,23);
     }
    }
}
return 0;
}

int condition(bool *fsys, int *ptx, int lev)
{
enum symbol relop;
bool nxtlev[symnum];

if(sym==oddsym){
    getsymdo;
    expressiondo(fsys,ptx,lev);
    gendo(opr,0,6);
}
else{
    memcpy(nxtlev,fsys,sizeof(bool)*symnum);
    nxtlev[eql]=true;
    nxtlev[neq]=true;
    nxtlev[lss]=true;
    nxtlev[leq]=true;
    nxtlev[gtr]=true;
    nxtlev[geq]=true;
    expressiondo(nxtlev,ptx,lev);
    if(sym!=eql&&sym!=neq&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq){
     error(20);
    }
    else{
     relop=sym;
     getsymdo;
     expressiondo(fsys,ptx,lev);
     switch(relop){
      case eql:
       gendo(opr,0,8);
       break;
      case neq:
       gendo(opr,0,9);
       break;
      case lss:
       gendo(opr,0,10);
       break;
      case geq:
       gendo(opr,0,11);
       break;
      case gtr:
       gendo(opr,0,12);
       break;
      case leq:
       gendo(opr,0,13);
       break;
     }
    }
}
return 0;
}

void interpret(void)
{
int p,b,t;
struct instruction i;
int s[stacksize];

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:
      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:
        t--;
        s[t-1]=s[t-1]%2;
        break;
       case 8:
        t--;
        s[t-1]=(s[t-1]==s[t]);
        break;
       case 9:
        t--;
        s[t-1]=(s[t-1]!=s[t]);
        break;
       case 10:
        t--;
        s[t-1]=(s[t-1]<s[t]);
        break;
       case 11:
        t--;
        s[t-1]=(s[t-1]>=s[t]);
        break;
       case 12:
        t--;
        s[t-1]=(s[t-1]>s[t]);
        break;
       case 13:
        t--;
        s[t-1]=(s[t-1]<=s[t]);
        break;
       case 14:
        printf("%d",s[t-1]);
        fprintf(fa2,"%d",s[t-1]);
        t--;
        break;
       case 15:
        printf("\n");
        fprintf(fa2,"\n");
        break;
       case 16:
        printf("?");
        fprintf(fa2,"?");
        scanf("%d",&(s[t]));
        fprintf(fa2,"%d\n",s[t]);
        t--;
        break;
      }
      break;
     case lod:
      s[t]=s[base(i.l,s,b)+i.a];
      t++;
      break;
     case sto:
      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;
      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);
}

int base(int l, int *s, int b)
{
int bl;
bl=b;

while(l>0){
    bl=s[bl];
    l--;
}
return bl;
}

⌨️ 快捷键说明

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