📄 pl0.cpp
字号:
gen(OPR,0,6);
}
else
{
expression(tmp,tx,lev);
if(tmp.find(sym)==tmp.end())
error(20);
else
{
relop= sym;
getsym();
expression(fsys,tx,lev);
switch(relop)
{
case EQL: gen(OPR,0,8);
break;
case NEQ: gen(OPR,0,9);
break;
case LSS: gen(OPR,0,10);
break;
case GEQ: gen(OPR,0,11);
break;
case GTR: gen(OPR,0,12);
break;
case LEQ: gen(OPR,0,13);
break;
}
}
}
}//condition end
void PL0::statement(symset fsys,int tx,int lev)
{
if(sourceEnd)
return;
int i,cx1,cx2;
if(sym ==IDENT)
{
i= position(id,tx);
if (i == 0)
error(11);
else if (table[i].kind!=VARIABLE)
{
error(12);
i= 0;
}
getsym();
if(sym ==BECOMES)
getsym();
else
error(13);
expression(fsys,tx,lev);
if(sym!=SEMICOLON)
error(10);
if( i!= 0)
gen(STO,lev-table[i].other.inOther.level,table[i].other.inOther.adr);
}
else if( sym==READSYM)
{
getsym();
if( sym!=LPAREN)
error(34);
else
do{
getsym();
if (sym==IDENT)
i=position(id,tx);
else
i=0;
if( i==0 )
error(35);
else
{
gen(OPR,0,16);
gen(STO,lev-table[i].other.inOther.level,table[i].other.inOther.adr);
}
getsym();
}while(sym==COMMA);
if (sym!=RPAREN)
{
error(33);
while (fsys.find(sym)!=fsys.end()) getsym();
}
else
getsym();
}
else if( sym==WRITESYM)
{
getsym();
if (sym==LPAREN)
{
do{
getsym();
symset tmp=fsys;
for(int t=RPAREN;t<=COMMA;t++)
tmp.insert((symbol)t);
expression(tmp,tx,lev);
gen(OPR,0,14);
}while(sym==COMMA);
if (sym!=RPAREN)
error(33);
else
getsym();
}
gen(OPR,0,15);
}
else if( sym ==CALLSYM)
{
getsym();
if( sym!=IDENT)
error(14);
else
{
i= position(id,tx);
if (i == 0)
error(11);
else if (table[i].kind = PROCEDURE)
gen(CAL,lev-table[i].other.inOther.level,table[i].other.inOther.adr);
else
error(15);
getsym();
}
}
else if( sym ==IFSYM)
{
getsym();
symset tmp=fsys;
for(int i=THENSYM;i<=DOSYM;i++)
tmp.insert((symbol)i);
condition(tmp,tx,lev);
if( sym == THENSYM)
getsym();
else
error(16);
cx1= cx;
gen(JPC,0,0);
statement(fsys,tx,lev);
code[cx1].a= cx;
}
else if( sym ==BEGINSYM)
{
getsym();
symset tmp=fsys;
for(int i=SEMICOLON;i<=ENDSYM;i++)
tmp.insert((symbol)i);
statement(tmp,tx,lev);
tmp=statbegsys;
tmp.insert(SEMICOLON);
while( tmp.find(sym)!=tmp.end())
{
if(sourceEnd)return;
if (sym ==SEMICOLON||sym ==ENDSYM)
getsym();
else if(sym=PERIOD)
{
error(26);
getsym();
}
else
error(10);
tmp=fsys;
for(i=SEMICOLON;i<=ENDSYM;i++)
tmp.insert((symbol)i);
if(sourceEnd)return;
if(sym==ENDSYM)
break;
statement(tmp,tx,lev);
}
if( sym ==ENDSYM)
getsym();
else if(!sourceEnd)
error(17);
}
else if(sym ==WHILESYM)
{
cx1= cx;
getsym();
symset tmp=fsys;
tmp.insert(DOSYM);
condition(tmp,tx,lev);
cx2= cx;
gen(JPC,0,0);
if(sym ==DOSYM)
getsym();
else
error(18);
statement(fsys,tx,lev);
gen(JMP,0,cx1);
code[cx2].a= cx;
}
symset setT;
test(fsys,setT,19);
}//statement end
void PL0::block(int lev,int tx,symset fsys)
{
if(sourceEnd)
return;
int dx;//data allocation index
int tx0;//initial table index
int cx0;//initial code index
dx= 3;
tx0= tx;
table[tx].other.inOther.adr= cx;
gen(JMP,0,0);
if( lev>levmax)
error(32);
do{
if( sym ==CONSTSYM)
{
getsym();
do{
constdeclaration(tx,dx,lev);
while (sym ==COMMA)
{
getsym();
constdeclaration(tx,dx,lev);
}
if (sym ==SEMICOLON)
getsym();
else
error(5);
}while(sym==IDENT);
}
if( sym ==VARSYM)
{
getsym();
do{
vardeclaration(tx,dx,lev);
while( sym ==COMMA){
getsym();
vardeclaration(tx,dx,lev);
}
if( sym ==SEMICOLON)
getsym();
else
error(5);
}while(sym==IDENT);
}
while( sym ==PROCSYM)
{
getsym();
if (sym ==IDENT)
{
enter(PROCEDURE,tx,dx,lev);
getsym();
}
else
error(4);
if( sym ==SEMICOLON)
getsym();
else
error(5);
symset tmp=fsys;
tmp.insert(SEMICOLON);
block(lev+1,tx,tmp);
if (sym ==SEMICOLON){
getsym();
symset tmp=statbegsys;
for(int i=IDENT;i<=PROCSYM;i++)
tmp.insert((symbol)i);
test(tmp,fsys,6);
}
else
error(5);
}
symset tmp=statbegsys;
tmp.insert(IDENT);
test(tmp,declbegsys,7);
}while(declbegsys.find(sym)!=declbegsys.end());
code[table[tx0].other.inOther.adr].a= cx;
table[tx0].other.inOther.adr= cx;// start adr of code
table[tx0].other.inOther.size=dx;
cx0= cx;
gen(INT,0,dx);
symset tmp=statbegsys;
for(int i=SEMICOLON;i<=ENDSYM;i++)
tmp.insert((symbol)i);
statement(tmp,tx,lev);
gen(OPR,0,0);// return
symset s2;
test(fsys,s2,8);
listcode(cx0);
}// block end
int PL0::base(int l,int b,int s[])
{
int b1;
b1= b;//find base l levels down
while(l>0){
b1= s[b1];
l= l-1;
}
return b1;
}
void PL0::interpret()
{
int err1=errorString.size();
if(err1>0)
{
cout<<"存在%d个错误:"<<err1<<endl;
for(int i=0;i<err1;i++)
cout<<errorString[i]<<endl;
return;
}
const stacksize = 500;
int p=0,b=1,t=0;//program-,base-,topstack-registers
instruction i;// instruction register
int s[stacksize+1]={0};// datastore
cout<<" Start PL/0\n";
do{
i= code[p];
p= p+1;
switch(i.f)
{
case LIT:
t= t+1;
s[t]= i.a;
break;
case OPR:
switch(i.a) //operator
{
case 0:// return
t= b-1;
p= s[t+3];
b= s[t+2];
break;
case 1:
s[t]= -s[t];
break;
case 2:
t= t-1;
s[t]= s[t]+s[t+1];
break;
case 3:
t= t-1;
s[t]= s[t]-s[t+1];
break;
case 4:
t= t-1;
s[t]= s[t]*s[t+1];
break;
case 5:
t= t-1;
s[t]= s[t] / s[t+1];
break;
case 6:
if(s[t]%2)
s[t]=1;
else
s[t]=0;
break;
case 8:
t= t-1;
if(s[t]==s[t+1])
s[t]=1;
else
s[t]=0;
break;
case 9:
t= t-1;
if(s[t]==s[t+1])
s[t]=0;
else
s[t]=1;
break;
case 10:
t= t-1;
if(s[t]<s[t+1])
s[t]=1;
else
s[t]=0;
break;
case 11:
t= t-1;
if(s[t]>=s[t+1])
s[t]= 1;
else
s[t]=0;
break;
case 12:
t= t-1;
if(s[t]>s[t+1])
s[t]= 1;
else
s[t]=0;
break;
case 13:
t= t-1;
if(s[t]<=s[t+1])
s[t]= 1;
else
s[t]=0;
break;
case 14:
cout<<" "<<s[t];
t=t-1;
break;
case 15:
cout<<endl;
break;
case 16:
t=t+1;
cout<<"?";
s[t]=0;
cin>>s[t];
break;
};
break;
case LOD:
t= t+1;
s[t]= s[base(i.l,b,s)+i.a];
break;
case STO:
s[base(i.l,b,s)+i.a]= s[t];
t= t-1;
break;
case CAL://generate new block mark
s[t+1]= base(i.l,b,s);
s[t+2]= b;
s[t+3]= p;
b= t+1;
p=i.a;
break;
case INT:
t= t+i.a;
break;
case JMP:
p= i.a;
break;
case JPC:
if (s[t] == 0)
p= i.a;
t= t-1;
break;
}//switch end
}while(p!=0);
cout<<" End PL/0\n";
}//interpret end
void PL0::SaveCode()
{
if(fout)
for (int i=0;i<cx;i++)
fprintf(fout,"%d %s %d %d\n ",i,mnemonic[code[i].f],code[i].l,code[i].a);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -