?? pl0.c
字號:
if(getsym()==-1)
return -1;
}
memcpy(ts,s,sizeof(int)*SYMNUM);
if(stat(ptx,ts,lev)==-1)
return -1;
code[cx1].a=cx;
}
else if(sym==whilesym)
{
int cx1,cx2;
cx1=cx;
if(getsym()==-1)
return -1;
memcpy(ts,s,sizeof(int)*SYMNUM);
ts[dosym]=1;
if(con(ptx,ts,lev)==-1)
return -1;
cx2=cx;
if(gen(jpc,0,0)==-1)
return -1;
if(sym!=dosym)
error(31);
else
{
if(getsym()==-1)
return -1;
}
if(stat(ptx,ts,lev)==-1)
return -1;
if(gen(jmp,0,cx1)==-1)
return -1;
code[cx2].a=cx;
}
else if(sym==readsym)
{
if(getsym()==-1)
return -1;
if(sym!=lparen)
error(19);
else
{
if(getsym()==-1)
return -1;
if(sym==ident)
{
p=extable(id,*ptx);
if(p==0)
error(20);
else
{
if(tb[p].kind!=variable)
{
error(21);
p=0;
}
else
{
if(getsym()==-1)
return -1;
}
}
if(p!=0)
{
if(gen(opr,0,16)==-1||gen(sto,lev-tb[p].lev,tb[p].adr)==-1)
return -1;
}
}
else
error(21);
while(sym==comma)
{
if(getsym()==-1)
return -1;
if(sym!=ident)
error(21);
else
{
p=extable(id,*ptx);
if(p==0)
error(20);
else
{
if(tb[p].kind!=variable)
{
error(21);
p=0;
}
else
{
if(getsym()==-1)
return -1;
}
}
if(p!=0)
{
if(gen(opr,0,16)==-1||gen(sto,lev-tb[p].lev,tb[p].adr)==-1)
return -1;
}
}
}
if(sym!=rparen)
{
error(22);
while(!inset(sym,s))
{
if(getsym()==-1)
return -1;
}
}
if(getsym()==-1)
return -1;
}
}
else if(sym==writesym)
{
if(getsym()==-1)
return -1;
if(sym==lparen)
{
if(getsym()==-1)
return -1;
memcpy(ts,s,sizeof(int)*SYMNUM);
ts[rparen]=1;
ts[comma]=1;
if(exp(ptx,ts,lev)==-1)
return -1;
if(gen(opr,0,14)==-1)
return -1;
while(sym==comma)
{
if(exp(ptx,ts,lev)==-1)
return -1;
if(gen(opr,0,14)==-1)
return -1;
}
if(sym!=rparen)
error(23);
else
{
if(getsym()==-1)
return -1;
}
}
else
error(24);
if(gen(opr,0,15)==-1)
return -1;
}
else
{
memset(ts,0,sizeof(int)*SYMNUM);
if(test(s,ts,32)==-1)
return -1;
}
return 0;
}
int exp(int *ptx,int *s,int lev)
{
enum sbl tmp;
int f=0;
int ts[SYMNUM];
if(sym==plus||sym==minus)
{
if(getsym()==-1)
return -1;
if(sym==minus)
f=1;
}
memcpy(ts,s,sizeof(int)*SYMNUM);
ts[plus]=1;
ts[minus]=1;
if(term(ptx,ts,lev)==-1)
return -1;
if(f==1)
{
if(gen(opr,0,1)==-1)
return -1;
}
while(sym==plus||sym==minus)
{
tmp=sym;
if(getsym()==-1)
return -1;
memcpy(ts,s,sizeof(int)*SYMNUM);
ts[plus]=1;
ts[minus]=1;
if(term(ptx,ts,lev)==-1)
return -1;
if(tmp==plus)
{
if(gen(opr,0,2)==-1)
return -1;
}
else //if(tmp==minus)
{
if(gen(opr,0,3)==-1)
return -1;
}
}
return 0;
}
int term(int *ptx,int *s,int lev)
{
enum sbl tmp;
int ts[SYMNUM];
memcpy(ts,s,sizeof(int)*SYMNUM);
ts[times]=1;
ts[slash]=1;
if(fac(ptx,ts,lev)==-1)
return -1;
while(sym==times||sym==slash)
{
tmp=sym;
if(getsym()==-1)
return -1;
if(fac(ptx,ts,lev)==-1)
return -1;
if(tmp==times)
{
if(gen(opr,0,4)==-1)
return -1;
}
else //if(tmp==slash)
{
if(gen(opr,0,5)==-1)
return -1;
}
}
return 0;
}
int fac(int *ptx,int *s,int lev)
{
int ts[SYMNUM];
int p;
if(test(fcbsys,s,33)==-1)
return -1;
while(inset(sym,fcbsys))
{
if(sym==ident)
{
p=extable(id,*ptx);
if(p==0)
error(34);
else
{
if(tb[p].kind==constant)
{
if(gen(lit,0,tb[p].val)==-1)
return -1;
}
else if(tb[p].kind==variable)
{
if(gen(lod,lev-tb[p].lev,tb[p].adr)==-1)
return -1;
}
else //類型為過程
error(35);
}
if(getsym()==-1)
return -1;
}
else if(sym==number)
{
if(num>AMAX)
{
error(7);
num=0;
}
if(gen(lit,0,num)==-1)
return -1;
if(getsym()==-1)
return -1;
}
else
{
if(sym==lparen)
{
if(getsym()==-1)
return -1;
memcpy(ts,s,sizeof(int)*SYMNUM);
ts[rparen]=1;
if(exp(ptx,ts,lev)==-1)
return -1;
if(sym!=rparen)
error(36);
else
{
if(getsym()==-1)
return -1;
}
}
if(test(s,fcbsys,37)==-1)
return -1;
}
}
return 0;
}
int con(int *ptx,int *s,int lev)
{
int ts[SYMNUM];
if(sym==oddsym)
{
if(getsym()==-1)
return -1;
if(exp(ptx,s,lev)==-1)
return -1;
if(gen(opr,0,6)==-1)
return -1;
}
else
{
enum sbl tmp;
memcpy(ts,s,sizeof(int)*SYMNUM);
ts[eql]=1;
ts[neq]=1;
ts[lss]=1;
ts[leq]=1;
ts[gtr]=1;
ts[geq]=1;
if(exp(ptx,ts,lev)==-1)
return -1;
tmp=sym;
if(sym!=eql&&sym!=neq&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq)
error(38);
else
{
if(getsym()==-1)
return -1;
memcpy(ts,s,sizeof(int)*SYMNUM);
if(exp(ptx,ts,lev)==-1)
return -1;
if(tmp==eql)
{
if(gen(opr,0,8)==-1)
return -1;
}
else if(tmp==neq)
{
if(gen(opr,0,9)==-1)
return -1;
}
else if(tmp==lss)
{
if(gen(opr,0,10)==-1)
return -1;
}
else if(tmp==leq)
{
if(gen(opr,0,11)==-1)
return -1;
}
else if(tmp==gtr)
{
if(gen(opr,0,12)==-1)
return -1;
}
else //if(tmp==geq)
{
if(gen(opr,0,13)==-1)
return -1;
}
}
}
return 0;
}
void itp()
{
int sk[STACKSIZE]; //棧
int t=0,b=0,p=0; //t棧頂指針,b當前過程基指針,p當前指令指針
struct ins op; //當前指令
sk[0]=sk[1]=sk[2]=0;
printf("\nStart running\n");
do{
op=code[p];
p++;
if(op.f==lit) //取常數到棧頂
{
sk[t]=op.a;
t++;
}
else if(op.f==lod) //取變量
{
sk[t]=sk[base(op.l,sk,b)+op.a]; //取相對當前過程數據基地址為a的內存的值到棧頂
t++;
}
else if(op.f==sto) //棧頂值存到相對當前過程數據基地址為a的內存
{
t--;
sk[base(op.l,sk,b)+op.a]=sk[t];
}
else if(op.f==cal) //子程序調用
{
sk[t]=base(op.l,sk,b);//父過程基地址入棧
sk[t+1]=b; //本過程基地址入棧
sk[t+2]=p; //當前指令入棧
b=t; //基地址改為新過程基地址
p=op.a; //跳轉
}
else if(op.f==inte) //分配三個聯系單元及變量內存
{
t+=op.a;
}
else if(op.f==jmp) //跳轉
{
p=op.a;
}
else if(op.f==jpc) //條件跳轉
{
t--;
if(sk[t]==0)
p=op.a;
}
else if(op.f==opr)
{
if(op.a==0)
{
t=b;
b=sk[t+1];
p=sk[t+2];
}
else if(op.a==1)
{
sk[t-1]=-sk[t-1];
}
else if(op.a==2)
{
t--;
sk[t-1]=sk[t-1]+sk[t];
}
else if(op.a==3)
{
t--;
sk[t-1]=sk[t-1]-sk[t];
}
else if(op.a==4)
{
t--;
sk[t-1]=sk[t-1]*sk[t];
}
else if(op.a==5)
{
t--;
sk[t-1]=sk[t-1]/sk[t];
}
else if(op.a==6)
{
sk[t-1]=sk[t-1]%2;
}
else if(op.a==8)
{
t--;
sk[t-1]=(sk[t-1]==sk[t]);
}
else if(op.a==9)
{
t--;
sk[t-1]=(sk[t-1]!=sk[t]);
}
else if(op.a==10)
{
t--;
sk[t-1]=(sk[t-1]<sk[t]);
}
else if(op.a==11)
{
t--;
sk[t-1]=(sk[t-1]<=sk[t]);
}
else if(op.a==12)
{
t--;
sk[t-1]=(sk[t-1]>sk[t]);
}
else if(op.a==13)
{
t--;
sk[t-1]=(sk[t-1]>=sk[t]);
}
else if(op.a==14)
{
t--;
printf("%d",sk[t]);
fprintf(fa2,"%d",sk[t]);
}
else if(op.a==15)
{
printf("\n");
fprintf(fa2,"\n");
}
else if(op.a==16)
{
printf("?");
fprintf(fa2,"?");
scanf("%d",&sk[t]);
fprintf(fa2,"%d\n",sk[t]);
t++;
}
}
}while(p!=0);
}
int base(int l,int *x,int b) //通過當前過程基址求上l層的基址
{
int btmp=b;
while(l>0)
{
btmp=x[btmp];
l--;
}
return btmp;
}
main()
{
int nlev[SYMNUM];
int k;
printf("\n * * * * * * * * * * * PL0 Compiler v1.0 * * * * * * * * * * * \n");
printf("Input pl0 file name:");
scanf("%s",fname);
fin=fopen(fname,"r");
if(fin==NULL)
printf("Can't open %s!\n",fname);
else
{
printf("List object code:\n"); /*輸出虛擬機代碼*/
fa1=fopen("fa1.txt","w");
fprintf(fa1,"Input pl0 file name:");
fprintf(fa1,"%s\n",fname);
init();
err=cx=cc=ll=0;
ch=' ';
if(getsym()!=-1)
{
fa=fopen("fa.txt","w");
addset(nlev,dcbsys,stbsys,SYMNUM);
nlev[period]=1;
if(mb(0,0,nlev)==-1)
{
fclose(fa);
fclose(fa1);
fclose(fin);
printf("\n");
return 0;
}
fclose(fa1);
if(sym!=period)
error(39);
printf("\n\n");
fprintf(fa,"\n\n");
for(k=0;k<cx;k++)
{
printf("%d\t%s\t%d\t%d\n",k,mc[code[k].f],code[k].l,code[k].a);
fprintf(fa,"%d\t%s\t%d\t%d\n",k,mc[code[k].f],code[k].l,code[k].a);
}
if(err==0)
{
fa2=fopen("fa2.txt","w");
itp();
fclose(fa2);
}
else
{
printf("\n%d errors!\n",err);
fprintf(fa,"\n%d errors!\n",err);
}
}
fclose(fa);
fclose(fin);
}
printf("\n");
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -