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)
31
{
case eql:
case neq: gendo(opr,0,8); break; }
} return 0; }
void interpret() {
int p,b,t;
struct instruction i; int s[stacksize]; printf(\t=0; b=0; p=0;
s[0]=s[1]=s[2]=0; do {
i=code[p];
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;
}
32
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;
33
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-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(\fprintf(fa2,\t--; break; case 15: printf(\fprintf(fa2,\break; case 16: printf(\fprintf(fa2,\scanf(\fprintf(fa2,\
34
t++; break; }
break; case lod:
s[t]=s[base(i.l,s,b)+i.a]; t++; break; case sto: t--;
s[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) {
35
int b1; b1=b; while(l>0) {
b1=s[b1]; l--; }
return b1; }
五、 实验结果
1.输入PL/0源程序 const a=10; var b,c; procedure p begin c:=b+a end; begin read (b); while b#0 do begin call p; write(2*c); read(b) end end.
2. 输入分别输入b值的结果 当b=2; 输出结果为24 当b=3;输出结果为26 当b=1;出结果为22 当b=0;结束程序
六、 实验体会
通过该实验,本人学会了应用C语言调试和扩充PL/0编译程序的能力,此实验完成了PL/0词法分析、语法分析、语义分析、代码生成和代码优化等功能,并在此基础上实现了PL/0语言的扩充能力,从实际的应用中深刻领悟了编译程序的原理,更加深刻的学习了理论知识。
36