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