📄 pl0.c
字号:
error(20);
relop= sym;
getsym();
expression(fsys);
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;
}
}
}
//语句分析
//说明:引入临时集合tempset是为了函数临时参数传递用,nullset代表空集合
//pascal中支持集合的加减,且在参数传递时可直接用集合加表达式
//为次,在c中引入tempset,先将要传递的集合表达式所代表的集合记录下来,
//然后将它作临时参数穿递给被调用函数
void statement(symset fsys)
{
symset tempset={0},nullset={0};
if (sym == ident)
{
i = position(id);
if (i <0 )
error(11);
else
if(table[i].kind != variable)
{
error(12);
i= -1;/////////////////////////////////////////////////////////////6/25
}
getsym();
if(sym ==becomes)
getsym();
else
error(13);
expression(fsys);
if (i != -1)////////////////////////////////////////////////////////////6/25
gen(sto, lev - table[i].level, table[i].adr);
}
else
if(sym == readsym)
{
getsym();
if (sym !=lparen)
error(34);
else
do
{
getsym();
if (sym ==ident)
i=position(id);
else
i= 0;
if(i==0)
error(35);
else
{
gen(opr, 0, 16);
gen(sto, lev - table[i].level, table[i].adr);
}
getsym();
}while(sym ==comma);
if(sym !=rparen)
{
error(33);
while(IN(fsys,sym)==0)
getsym();
}
else
getsym();
}
else
if(sym ==writesym)
{
getsym();
if (sym == lparen)
{
do{
getsym();
tempset=fsys;
tempset=ADD(tempset,rparen, comma);
expression(tempset);
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);
if (i == 0 ) //wrongs 14号14点 change i=0 to i==0
error(11);
else
if (table[i].kind == procedur) ///wrongs 14//14:00
gen(cal,lev-table[i].level,table[i].adr);
else
error(15);
getsym();
}
}
else
if( sym ==ifsym)
{
getsym();
tempset=fsys; //13号14:00
tempset=ADD(tempset,thensym, dosym);
condition(tempset);
if (sym == thensym)
getsym();
else
error(16);
cx1 = cx;
gen(jpc, 0, 0);
statement(fsys);
code[cx1].a=cx;
}
else
if (sym == beginsym)
{
getsym();
tempset=fsys;
tempset=ADD(tempset,semicolon, endsym);
statement(tempset);
while(sym==semicolon||IN(statbegsys,sym))
{
if (sym == semicolon)
getsym();
else
error(10);
statement(tempset);
}
if (sym == endsym)
getsym();
else
error(17); //err=1??
}
else
if( sym == whilesym)
{
cx1 = cx;
getsym();
tempset=fsys;
tempset=ADD(tempset,dosym);
condition(tempset);
cx2 = cx;
gen(jpc, 0, 0);
if (sym == dosym)
getsym();
else
error(18);
statement(fsys);
gen(jmp, 0, cx1);
code[cx2].a = cx;
}
test(fsys,nullset, 19);
}
//block 函数
void block(symset fsys)/////////////////para changes!
{
//lev++; //18/10:44
dx=3;
tx0=tx;
table[tx].adr=cx;
gen(jmp,0,0);
if(lev>levmax)
error(32);
do
{
if(sym==constsym)//常量处理
{
getsym();
do
{
constdeclaration();
while(sym==comma)
{
getsym();
constdeclaration();//
}
if(sym==semicolon)
getsym();
else
error(5);
}while(sym==ident); //12/20:40 wrong change !=to==
}
if(sym==varsym)//变量处理
{
getsym();
do
{
vardeclaration();//
while(sym==comma)
{
getsym();
vardeclaration();//
}
if(sym==semicolon)
getsym();
else
error(5);
}while(sym==ident);
}
while(sym==procsym)//过程处理
{
getsym();
if(sym==ident)
{
enter(procedur);//
getsym();
}
else
error(4);
if(sym==semicolon)
getsym();
else
error(5);
fsys=ADD(fsys,semicolon);//
lev=lev+1;//嵌套调用block前先保存局部变量
dxdx=dx;tx0tx0=tx0;cx0cx0=cx0;
txtx=tx;
block(fsys);
tx=txtx;//调用后返回调用前的值
dx=dxdx;tx0=tx0tx0;cx0=cx0cx0;
lev--;//18/10:59////////////////////////////////////////////////////
///////////////important change!
//关于lev等block局部变量的处理见说明4
if(sym==semicolon)
{
getsym();
tempset=statbegsys;
tempset=ADD(tempset,ident,procsym);
test(tempset,fsys,6);
}
else
error(5);
}
tempset=statbegsys;
tempset=ADD(tempset,ident);
test(tempset,declbegsys,7);
}while(IN(declbegsys,sym));
//语句处理
// code[table[tx0].adr].a=cx; //将这一语句用下面的语句代替
code[cx0].a=cx; //!!!!important 6月25号
table[tx0-1].adr=cx;////////////////////////////////////////////
//important change!18/11;16
table[tx0-1].size=dx;
cx0=cx;
gen(intr,0,dx);//
tempset=fsys;
tempset=ADD(tempset,semicolon,endsym);
statement(tempset); //////
gen(opr,0,0);
test(fsys,nullset,8);//
listcode();//
}
//interpret的局部变量
const stacksize=500;
int p,b,t;
struct instruction I;
int s[500];//程序运行栈
int base(int l)//注意数组下标!!!!!!!!!!!!!!!!!!1
{
int b1;
b1 = b;
while (l > 0)
{
b1 = s[b1];
l = l - 1;
}
return b1;
}
void interpret()
{
printf("start pl0\n");
t =0; //change t=0 to t=-1 15//13:00
//chang t=-1 to 0 at 18/17:37
b = 1;
p = 0;
s[1] = 0;
s[2] = 0;
s[3] = 0;
do{ //do_while start
I = code[p];
p = p + 1;
//I.a=1;
switch(I.f) //switch(I.f) start
{
case lit:
{
t = t + 1; //
s[t] = I.a;
break;
}
case opr:
{ //opr start
switch(I.a )//(* operator *) //switch(I.a) start
{ case 0:
{
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:
{
s[t] = (s[t]%2==1); ///?7
break;
}
case 8:
{
t = t - 1;
s[t] = (s[t] == s[t + 1]);
break;
}
case 9:
{
t=t-1;//18:17:22
s[t] = (s[t]!=s[t + 1]);//
break;
}
case 10:
{
t = t - 1;
s[t] = (s[t] < s[t + 1]);
break;
}
case 11:
{
t = t - 1;
s[t] = (s[t] >= s[t + 1]);
break;
}
case 12:
{
t = t - 1;
s[t] = (s[t] > s[t + 1]);
break;
}
case 13:
{
t = t - 1;
s[t] = (s[t] <= s[t + 1]);
break;
}
case 14:
{
printf("%d",s[t]);
fputc(s[t],fa2);
t = t - 1;
break;
}
case 15:
{
// writeln;//
// writeln(fa2) //
printf("%c",10);
fputc(10,fa2);
break;
}
case 16:
{
t = t + 1;
printf("?");
fputc('?',fa2);
scanf("%d",&s[t]);
fputc(s[t],fa2);
break;
}
} //switch(I.a) end
break;
} //opr end
case lod:
{
t = t + 1;
s[t] = s[base(I.l) + I.a] ;
break;
}
case sto:
{
s[base(I.l) + I.a] = s[t];
t = t - 1;
break;
}
case cal:
{
s[t + 1] = base(I.l);
s[t + 2] = b;
s[t + 3] = p;
b = t + 1;
p = I.a;
break;
}
case intr:
{
t = t + I.a;
break;
}
case jmp:
{
p = I.a;
break;
}
case jpc:
{
if (s[t] == 0)
p = I.a;
t=t-1;//?
break;
}
}//end(* with,case *)
//switch(I.f) end
//if(p==0)
// p=p+1;
}while(p!=0); //6/25////////// //do_while end
fclose(fa2);
}
//主函数
void main()
{
char filename[20]; //////////////delete the char ch
int i;
symset tempset={0};
wsym[0]=beginsym;
wsym[1]=callsym;
wsym[2]=constsym;
wsym[3]=dosym;
wsym[4]=endsym;
wsym[5]=ifsym;
wsym[6]=oddsym;
wsym[7]=procsym;
wsym[8]=readsym;
wsym[9]=thensym;
wsym[10]=varsym;
wsym[11]=whilesym;
wsym[12]=writesym;
/* mnemonic[0]=lit;
mnemonic[1]=opr;
mnemonic[2]=lod;
mnemonic[3]=sto;
mnemonic[4]=cal;
mnemonic[5]=intr;
mnemonic[6]=jmp;
mnemonic[7]=jpc;*/
declbegsys=ADD(declbegsys,constsym,varsym,procsym);
statbegsys=ADD(statbegsys,beginsym,callsym,ifsym,whilesym);
facbegsys=ADD(facbegsys,ident,number,lparen);
fa1=fopen("fa1.txt","a");
if(fa1==NULL)
{
printf("fa1.txt is not exist!");
return ;
}
printf("input file?");
fprintf(fa1,"input file?");
i=0;
while(i<20)
{
scanf("%c",&filename[i]);
if(filename[i]=='\n')
{
filename[i]='\0';
break;
}
i++;
}
for(i=0;i<8&&isalpha(filename[i]);i++)
{
ch=filename[i];
printf("%c",ch);
fputc(ch,fa1);
}
fin=fopen(filename,"r"); /**/
if(fin==NULL)
{
printf("file.txt is not exist!");
return ;
}
printf("list object code?");
fprintf(fa1,"list object code?");
scanf("%c",&ch);
if(ch=='y')
listswitch=1;
else
listswitch=0;
err=0;
cc=0;cx=0;ll=0;
ch=32;kk=al;
getsym();
fa=fopen("fa.txt","a");//
fa2=fopen("fa2.txt","a");//
tempset=ADD(tempset,period,constsym,varsym,procsym,beginsym,callsym,ifsym,whilesym);
lev=0;
tx=0;
block(tempset);
fclose(fa);
fclose(fa1);
if(sym!=period)
error(9);
if(err==0)
interpret();
else
printf("errors in pl0 program!");
fclose(fin);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -