📄 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 + -