📄 pl0.cpp
字号:
if(sym==semicolon)
{
getsymdo;
}
else
{
error(10);/*缺少分号*/
}
statementdo(nxtlev,ptx,lev,tx0,hreturn);
}
if(sym==endsym)
{
getsymdo;
}
else
{
error(17); /*缺少end或分号*/
}
}
else
{
if(sym==whilesym)/*准备按照while语句处理*/
{
cx1=cx; /*保存判断条件超作的位置*/
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[dosym]=true;/*后跟符号为do*/
conditiondo(nxtlev,ptx,lev); /*调用条件处理*/
cx2=cx; /*保存循环体的结束的下一个位置*/
gendo(jpc,0,0);/*生成条件跳转,但跳出循环的地址未知*/
if(sym==dosym)
{
getsymdo;
}
else
{
error(18); /*缺少do*/
}
statementdo(fsys,ptx,lev,tx0,hreturn); /*循环体*/
gendo(jmp,0,cx1);/*回头重新判断条件*/
code[cx2].a=cx; /*反填跳出循环的地址,与if类似*/
}
else
{
if(sym==forsym)
{
bool point=false;
int cxstar,cxend;
getsymdo;
if(sym==padsym)
{
point=true;
getsymdo;
}
if(sym==ident)
{
memcpy(nxtlev,fsys,sizeof(bool)* symnum);
i=identbc(nxtlev,ptx,lev,cxstar,cxend,point);
cx1=cx;
genrp(cxstar,cxend);
ldst(lod,lev,i,point);
}
if(sym==tosym||sym==downtosym)
{
enum symbol resym=sym;
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[dosym]=true;
expressiondo(nxtlev,ptx,lev);
switch(resym)
{
case tosym:
gendo(opr,0,13);
break;
case downtosym:
gendo(opr,0,11);
break;
}
cx2=cx;
gendo(jpc,0,0);
if(sym==dosym)
{
getsymdo;
}
else
{
error(18);
}
statementdo(fsys,ptx,lev,tx0,hreturn);
switch(resym)
{
case tosym:
genrp(cxstar,cxend);
ldst(lod,lev,i,point);
gendo(lit,0,1);
gendo(opr,0,2);
ldst(sto,lev,i,point);
break;
case downtosym:
genrp(cxstar,cxend);
ldst(lod,lev,i,point);
gendo(lit,0,1);
gendo(opr,0,3);
ldst(sto,lev,i,point);
break;
}
gendo(jmp,0,cx1);
code[cx2].a=cx;
}
}
else
{
if(sym==dplus||sym==dminus)
{
dpm(fsys,0,ptx,lev,-1,false);
}
else
{
if(sym==returnsym)
{
table[tx0].retn=true;
if(hreturn==true)
{
printf("just can return one value\n");
error(66);
}
getsymdo;
hreturn=true;
expressiondo(nxtlev,ptx,lev);
if(sym!=endsym)
{
printf("return must at the last\n");
error(46);
}
}
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 point=false;
bool nxtlev[symnum];
testdo(facbegsys,fsys,24); /*检测因子的开始符好号*/
while(inset(sym,facbegsys)) /*循环直到不是因子开始符号*/
{
if(sym==padsym)
{
point=true;
getsymdo;
}
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); /*直接把常量的值入栈*/
getsymdo;
break;
case variable: /*名字为变量*/
countadr(fsys,ptx,lev,i);
ldst(lod,lev,i,point); /*找到变量地址并将其值入栈*/
dpm(fsys,i,ptx,lev,2,point);
break;
case procedur: /*名字为过程*/
error(21); /*不能为过程*/
break;
}
}
}
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); /*缺少右括号*/
}
}
else
{
if(sym==dplus||sym==dminus)
{
dpm(fsys,i,ptx,lev,1,false);
}
else if(sym==radsym)
{
getsymdo;
if(sym==ident)
{
i=position(id,*ptx); /*查找名字*/
if(i==0)
{
error(11); /*标识符未声明*/
}
else
{
if(table[i].kind!=variable)
{
error(12);
}
else
{
countadr(fsys,ptx,lev,i);
gendo(rad,lev-table[i].level,i);
}
}
}
else
{
error(12);
}
}
else
{
testdo(fsys,facbegsys,23); /*因子后有非法符号*/
}
}
}
}
}
return 0;
}
/*
条件处理*/
int condition(bool* fsys,int* ptx,int lev)
{
enum symbol relop;
bool nxtlev[symnum];
if(sym==oddsym) /*准备按照odd运算处理*/
{
getsymdo;
expressiondo(fsys,ptx,lev);
gendo(opr,0,6); /*生成odd指令*/
}
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()
{
int p,b,t,n; /*指令指针,指令基址,栈顶指针*/
int k=0,kk=0,adr,ls=0;
int s[stacksize]; /*栈*/
struct instruction i; /*存放当前指令*/
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: /*将a的值取到栈顶*/
s[t]=i.a;
t++;
break;
case opr: /*数字、逻辑运算*/
switch(i.a)
{
case 0:
ls=s[t-1];
t=b;
p=s[t+2];
b=s[t+1];
s[t]=ls;
t++;
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:
s[t-1]=s[t-1]%2;
break;
case 7:
t--;
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: /*取相对当前过程的数据基地址为a的内存的值到栈顶*/
s[t]=s[base(i.l,s,b)+i.a];
t++;
break;
case lay:
adr=table[i.a].drt;
for(k=0;k<table[i.a].drt;k++)
{
ls=s[base(i.l,s,b)+table[i.a].adr+k];
if(ls>=table[i.a].eachdrt[k]||ls<0)
{
printf("array overflow\n");
error(40);
break;
}
for(kk=k+1;kk<table[i.a].drt;kk++)
{
ls=ls*table[i.a].eachdrt[kk];
}
adr=adr+ls;
}
s[t]=s[base(i.l,s,b)+table[i.a].adr+adr];
t++;
break;
case rad:
if(table[i.a].size==1)
{
s[t]=base(i.l,s,b)+table[i.a].adr;
t++;
break;
}
else if(table[i.a].size>1)
{
adr=table[i.a].drt;
for(k=0;k<table[i.a].drt;k++)
{
ls=s[base(i.l,s,b)+table[i.a].adr+k];
if(ls>=table[i.a].eachdrt[k]||ls<0)
{
printf("array overflow\n");
error(40);
break;
}
for(kk=k+1;kk<table[i.a].drt;kk++)
{
ls=ls*table[i.a].eachdrt[kk];
}
adr=adr+ls;
}
s[t]=base(i.l,s,b)+table[i.a].adr+adr;
t++;
break;
}
case pad:
if(table[i.a].size==1)
{
s[t]=s[s[base(i.l,s,b)+table[i.a].adr]];
t++;
break;
}
else if(table[i.a].size>1)
{
adr=table[i.a].drt;
for(k=0;k<table[i.a].drt;k++)
{
ls=s[base(i.l,s,b)+table[i.a].adr+k];
if(ls>=table[i.a].eachdrt[k]||ls<0)
{
printf("array overflow\n");
error(40);
break;
}
for(kk=k+1;kk<table[i.a].drt;kk++)
{
ls=ls*table[i.a].eachdrt[kk];
}
adr=adr+ls;
}
s[t]=s[s[base(i.l,s,b)+table[i.a].adr+adr]];
t++;
break;
}
case par:
if(table[i.a].size==1)
{
t--;
s[s[base(i.l,s,b)+table[i.a].adr]]=s[t];
break;
}
else if(table[i.a].size>1)
{
adr=table[i.a].drt;
for(k=0;k<table[i.a].drt;k++)
{
ls=s[base(i.l,s,b)+table[i.a].adr+k];
if(ls>=table[i.a].eachdrt[k]||ls<0)
{
printf("array overflow\n");
error(40);
break;
}
for(kk=k+1;kk<table[i.a].drt;kk++)
{
ls=ls*table[i.a].eachdrt[kk];
}
adr=adr+ls;
}
t--;
s[s[base(i.l,s,b)+table[i.a].adr+adr]]=s[t];
break;
}
case sto: /*栈顶的值存到相对当前过程的数据基地址为a的内存*/
t--;
s[base(i.l,s,b)+i.a]=s[t];
break;
case say:
adr=table[i.a].drt;
for(k=0;k<table[i.a].drt;k++)
{
ls=s[base(i.l,s,b)+table[i.a].adr+k];
if(ls>=table[i.a].eachdrt[k]||ls<0)
{
printf("array overflow\n");
error(40);
break;
}
for(kk=k+1;kk<table[i.a].drt;kk++)
{
ls=ls*table[i.a].eachdrt[kk];
}
adr=adr+ls;
}
t--;
s[base(i.l,s,b)+table[i.a].adr+adr]=s[t];
break;
case cal: /*调用子程序*/
s[t]=base(i.l,s,b); /*将父过程基地址入栈*/
s[t+1]=b; /*将本过程基地址入栈,此两项用于base函数*/
s[t+2]=p; /*将当前指令指针入栈*/
for(n=0;n<table[i.a].n;n++)
{
s[t+3+n]=s[t-table[i.a].n+n];
}
b=t; /*改变基地址指针值为新过程的基地址*/
p=table[i.a].adr; /*跳转*/
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);
}
/*通过过程基址求上1层过程的基址*/
int base(int l,int * s,int b)
{
int b1;
b1=b;
while(l>0)
{
b1=s[b1];
l--;
}
return b1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -