📄 pl0.java
字号:
if(sym==Symbol.ident)
{
x=enter(Object.variable,ptx,lev,pdx);
getsym();
}
else
error(4);
return x;
}
void listcode(int cx0)
{
int i;
for(i=cx0;i<cx;i++)
{ if(code[i].f==Function.inte)
System.out.printf("%d %s %d %d\n",i,"int",code[i].l,code[i].a);
else System.out.printf("%d %s %d %d\n",i,code[i].f.name(),code[i].l,code[i].a);
}
}
int statement(int ptx,int lev)
{
int i,cx1,cx2;
if(sym==Symbol.ident)
{
i=position(token,ptx);
if(i!=0)
{
if(table[i].kind==Object.variable)
{
getsym();
if(sym==Symbol.assign)
{
getsym();
ptx=expression(ptx,lev);
}
else
error(13);
gen(Function.sto,lev-table[i].level,table[i].adr);
}
else
{
error(12);
i=0;
}
}
else error(11);
}
else if(sym==Symbol.readsym)
{
getsym();
if(sym==Symbol.lparen)
{
do{
getsym();
if(sym==Symbol.ident)
i=position(token, ptx);
else
i=0;
if(i!=0)
{
gen(Function.opr,0,16);
gen(Function.sto,lev-table[i].level,table[i].adr); //储存到变量
}
else
error(35);
getsym();
}while (sym==Symbol.comma);
}
else
error(34);
if(sym==Symbol.rparen)
getsym();
}
else if(sym==Symbol.writesym)
{
getsym();
if(sym==Symbol.lparen)
{
do{
getsym();
ptx=expression(ptx,lev);
gen(Function.opr,0,14);//生成输出指令,输出栈顶的值
}while(sym==Symbol.comma);
if(sym==Symbol.rparen)
getsym();
else
error(33);
}
gen(Function.opr,0,15); //输出换行
}
else if(sym==Symbol.callsym)
{
getsym();
if(sym==Symbol.ident)
{
i=position(token,ptx);
if(i!=0){
if(table[i].kind==Object.procedure)
gen(Function.cal,lev-table[i].level,table[i].adr); //生成call指令
else
error(15);
}
else
error(11);
getsym();
}
else error(14);
}
else if(sym==Symbol.ifsym)
{
getsym();
ptx=condition(ptx,lev);
if(sym==Symbol.thensym)
getsym();
else
error(16);
cx1=cx; //保存当前指令地址
gen(Function.jpc,0,0); //生成条件跳转指令,跳转地址暂写0
ptx=statement(ptx,lev); //处理then后的语句
code[cx1].a=cx; //地址回填,经statement处理后,cx为then后语句执行完的位置,它正是前面未定的跳转地址
}
else if(sym==Symbol.beginsym)
{
getsym();
ptx=statement(ptx,lev);
while(sym==Symbol.beginsym|sym==Symbol.callsym|sym==Symbol.ifsym|sym==Symbol.whilesym|sym==Symbol.semicolon)
{
if(sym==Symbol.semicolon)
getsym();
else
error(10);
ptx=statement(ptx,lev);
}
if(sym==Symbol.endsym)
getsym();
else
error(17);
}
else if(sym==Symbol.whilesym)
{
cx1=cx; //保存判断条件的位置
getsym();
ptx=condition(ptx,lev);
cx2=cx; //保存循环体的结束的下一个位置
gen(Function.jpc,0,0);//生成条件跳转,但跳出循环体的地址未知
if(sym==Symbol.dosym)
getsym();
else
error(18);
ptx=statement(ptx,lev);
gen(Function.jmp,0,cx1);//回头重新判断条件
code[cx2].a=cx; //回填跳出循环体的地址
}
return ptx;
}
int expression(int ptx,int lev)
{
Symbol addop;
if(sym==Symbol.plus||sym==Symbol.minus)
{
addop=sym; // 保存开头的正负号
getsym();
ptx=term(ptx,lev);
if(addop==Symbol.minus)
gen(Function.opr,0,1);//如果开头为负号生成取负指令
}
else
ptx=term(ptx,lev);
while(sym==Symbol.plus||sym==Symbol.minus)
{
addop=sym;
getsym();
ptx=term(ptx,lev);
if(addop==Symbol.plus)
gen(Function.opr,0,2);
else
gen(Function.opr,0,3);
}
return ptx;
}
int term(int ptx,int lev)
{
Symbol mulop; //用于保存乘除法符号
ptx=factor(ptx,lev);
while(sym==Symbol.multiply||sym==Symbol.divide)
{
mulop=sym;
getsym();
ptx=factor(ptx,lev);
if(mulop==Symbol.multiply)
gen(Function.opr,0,4);
else
gen(Function.opr,0,5);
}
return ptx;
}
int factor(int ptx,int lev)
{
int i;
while(sym==Symbol.ident|sym==Symbol.number|sym==Symbol.lparen)
{
if(sym==Symbol.ident)
{
i=position(token,ptx);
if(i!=0)
switch(table[i].kind)
{
case constant:
gen(Function.lit,0,table[i].val); //直接把常量的值入栈
break;
case variable:
gen(Function.lod,lev-table[i].level,table[i].adr); //找到变量地址并将其值入栈
break;
case procedure:
error(21);
break;
}
else
error(11);
getsym();
}
else if(sym==Symbol.number)
{ gen(Function.lit,0,num);
getsym();
}
else if(sym==Symbol.lparen)
{ getsym();
ptx=expression(ptx,lev);
if(sym==Symbol.rparen)
getsym();
else
error(22);
}
}
return ptx;
}
int condition(int ptx,int lev)
{
Symbol relop;
if(sym==Symbol.oddsym)
{
getsym();
ptx=expression(ptx,lev);
gen(Function.opr,0,6); //生成odd指令
}
else
{
ptx=expression(ptx,lev);
if(sym!=Symbol.eql&&sym!=Symbol.neq&&sym!=Symbol.lss&&sym!=Symbol.leq&&sym!=Symbol.gtr&&sym!=Symbol.geq)
{
error(20);
}
else
{
relop=sym;
getsym();
ptx=expression(ptx,lev);
switch(relop)
{
case eql:
gen(Function.opr,0,8);
break;
case neq:
gen(Function.opr,0,9);
break;
case lss:
gen(Function.opr,0,10);
break;
case geq:
gen(Function.opr,0,11);
break;
case gtr:
gen(Function.opr,0,12);
break;
case leq:
gen(Function.opr,0,13);
break;
}
}
}
return ptx;
}
void interpret()
{
int p,b,t;
Instruction i; //存放当前指令
int[] s=new int[stackSize];
System.out.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:
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://奇偶判断
s[t-1]=s[t-1]%2;
break;
case 8://两个数是否相等
t--;
if(s[t-1]==s[t])
s[t-1]=1;
else
s[t-1]=0;
break;
case 9://两个数是否不等
t--;
if(s[t-1]!=s[t])
s[t-1]=1;
else s[t-1]=0;
break;
case 10://第一是否小于第二个
t--;
if(s[t-1]<s[t])
s[t-1]=1;
else
s[t-1]=0;
break;
case 11://第一个数是否大于等于第二个
t--;
if(s[t-1]>=s[t])
s[t-1]=1;
else
s[t-1]=0;
break;
case 12://第一个数是否大于
t--;
if(s[t-1]>s[t])
s[t-1]=1;
else
s[t-1]=0;
break;
case 13://第一个数是否小于等于
t--;
if(s[t-1]<=s[t])
s[t-1]=1;
else s[t-1]=0;
break;
case 14://输出
System.out.print("The result is:");
System.out.printf("%d",s[t-1]);
t--;
break;
case 15://换行
System.out.printf("\n");
break;
case 16://读入
System.out.printf("Enter a integer:");
Scanner scanner = new Scanner(System.in);
s[t]=scanner.nextInt();
t++;
break;
}
break;
case lod: //取相对当前过程的数据基地址为a的内存的值到栈顶
s[t]=s[base(i.l,s,b)+i.a];
t++;
break;
case sto: //栈顶的值存到相对当前过程的数据基地址为a的内存
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; //将本过程基地址入栈,主要用于base函数
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)
{
int b1;
b1=b;
while(l>0)
{
b1=s[b1];
l--;
}
return b1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -