📄 pl0.cpp
字号:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define norw 13
#define txmax 100
#define nmax 14
#define al 10
#define amax 2047
#define levmax 3
#define cxmax 200
#define stacksize 500
enum symbol {
nul,ident,number,plus,minus,times,slash,oddsym,
eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,
semicolon,period,becomes,beginsym,endsym,ifsym,
thensym,whilesym,writesym,readsym,dosym,callsym,
constsym,varsym,procsym
};
enum object {constant,variable,procedur};
enum fct {lit,opr,lod,sto,cal,int0,jmp,jpc};
typedef char alfa[al];
typedef int symset[32];
struct instruction {
fct f;
int l;
int a;
};
struct kind_struct {
int level,adr,size;
};
union kind_union {
int val;
kind_struct vp;
};
struct table_struct {
alfa name;
object kind;
kind_union cvp;
};
FILE *fa,*fa1,*fa2,*fin,*fout;
int listswitch,num,cc,ll,kk,cx,err,flag_end;
char ch,line[81],mnemonic[8][5];
alfa id,a,fname,word[norw+1];
instruction code[cxmax+1];
symbol sym,wsym[norw+1],ssym[62];
symset declbegsys,statbegsys,facbegsys;
table_struct table[txmax+1];
void error (int);
int inchar ();
int innum ();
int insymbol (symset);
void getsym ();
int eoln (FILE*);
void getch ();
void gen (fct,int,int);
void reset (symset ss);
void additem (symset,symbol);
void mergeset (symset,symset);
void test (symset,symset,int);
void block (int,int,symset);
void enter (object,int *,int *,int);
//void enter (object k,int tx,int dx,int lev)
int position (alfa,int);
//int position (alfa id,int tx)
void constdeclaration (int *,int *,int);
//void constdeclaration (int tx,int dx,int lev)
void vardeclaration (int *,int *,int);
//void vardeclaration (int tx,int dx,int lev)
void listcode (int);
//void listcode (int cx0)
void statement(symset,int,int);
//void statement(symset fsys,int tx,int lev)
void expression (symset,int,int);
//void expression (symset fsys,int tx,int lev)
void term (symset,int,int);
//void term (symset fsys,int tx,int lev)
void factor(symset,int,int);
//void factor(symset fsys,int tx,int lev)
void condition (symset,int,int);
//void condition (symset fsys,int tx,int lev)
void interpret ();
int base (int,int,int []);
void error (int n)
{
int i;
printf("* * * *");
fprintf(fa1,"* * * *");
for(i=1;i<3;i++)
{
printf("%c",' ');
fprintf(fa1,"%c",' ');
}
printf("!%2d\n",n);
fprintf(fa1,"!%2d\n",n);
}
int inchar ()
{
int i,flag=0;
for(i='a';i<='z';i++)
if(ch==i) flag=1;
return flag;
}
int innum ()
{
int i,flag=0;
for(i='0';i<='9';i++)
if(ch==i) flag=1;
return flag;
}
int insymbol (symset ss)
{
int i,flag=0;
for(i=0;i<=31;i++)
if(ss[sym]) flag=1;
return flag;
}
int line_end_of_dot()
{
int i=0;
while(i<81)
{
if(line[i]=='.')
return 1;
i++;
}
return 0;
}
void getsym ()
{
int i,j,k;
while (ch==' ')
getch();
if(inchar())
{
k=0;
//if(line[3]!='.')
//{
// strcpy(a,"end ");
// a[9]=' ';
//}
//else
do
{
if(k<al)
{
a[k]=ch;
k++;
}
getch();//&&line[3]!='.'
if(line_end_of_dot()&&!flag_end)
{
flag_end=1;
break;
}
}while(inchar()||innum());//strncmp(line,"end.",4)
if(k>=kk)
kk=k;
else
do
{
kk--;
a[kk]=' ';
}while(kk!=k);
strcpy(id,a);
i=1;
j=norw;
while(i<=j)
{
k=(i+j)/2;
if(strncmp(id,word[k],10)<0)
j=k-1;
else if(strncmp(id,word[k],10)>0)
i=k+1;
else
break;
}
if(i<=j)
sym=wsym[k];
else
sym=ident;
}
else
{
if(innum())
{
k=0;
num=0;
sym=number;
do
{
num=10*num+ch-'0';
k++;
getch();
}while(innum());
if(k>nmax)
error(30);
}
else
{
if(ch==':')
{
getch();
if(ch=='=')
{
sym=becomes;
getch();
}
else
sym=nul;
}
else
{
if(ch=='<')
{
getch();
if(ch=='=')
{
sym=leq;
getch();
}
else
sym=lss;
}
else
{
if(ch=='>')
{
getch();
if(ch=='=')
{
sym=geq;
getch();
}
else
sym=gtr;
}
else
{
sym=ssym[ch];
getch();
}
}
}
}
}
}
/*
int eoln (FILE* fp)
{
long i=0;
int c;
if((c=fgetc(fp))=='\r')
{
if((c=fgetc(fp))=='\n')
return 1;
else
i++;
}
else
i++;
fseek(fp,-i,SEEK_CUR);
return 0;
}
*/
int eoln (FILE* fp)
{
long i=0;
int c;
if((c=fgetc(fp))==10)
// {
// flag_end=1;
return 1;
// }
else
// {
// flag_end=0;
i++;
// }
fseek(fp,-i,SEEK_CUR);
return 0;
}
void getch ()
{
int i;
if(cc==ll)
{
if(feof(fin))
{
printf("program incomplete\n");
fclose(fin);
printf("\n");
exit(0);
}
ll=0;
cc=0;
// printf("%4d ",cx);
// fprintf(fa1,"%4d ",cx);
for(i=0;i<81;i++)
line[i]=' ';
while(!eoln(fin))
{
ch=fgetc(fin);
// if(ch=='.')
// flag_end=1;
printf("%c",ch);
fprintf(fa1,"%c",ch);
line[ll]=ch;
ll++;
}
printf("\n");
// ll++;
// line[ll]=fgetc(fin);
fprintf(fa1,"\n");
}
ch=line[cc];
cc++;
}
/*
void getch ()
{
int i,flag_end=0;
if(cc==ll)
{
if(feof(fin))
{
printf("program incomplete\n");
fclose(fin);
printf("\n");
exit(0);
}
ll=0;
cc=0;
// printf("%4d ",cx);
// fprintf(fa1,"%4d ",cx);
for(i=0;i<81;i++)
line[i]=' ';
while(!eoln(fin))
{
ch=fgetc(fin);
if(ch=='.')
flag_end=1;
// if(ch=='.')
// flag_end=1;
printf("%c",ch);
fprintf(fa1,"%c",ch);
line[ll]=ch;
ll++;
}
printf("\n");
// ll++;
// line[ll]=fgetc(fin);
fprintf(fa1,"\n");
}
if(flag_end)
ch=' ';
else
ch=line[cc];
cc++;
}
*/
void gen (fct x,int y,int z)
{
if(cx>cxmax)
{
printf("program too long\n");
fclose(fin);
printf("\n");
exit(0);
}
code[cx].f=x;
code[cx].l=y;
code[cx].a=z;
cx++;
}
void reset (symset ss)
{
int i;
for(i=0;i<=31;i++)
ss[i]=0;
}
void additem (symset ss,symbol sb)
{
ss[sb]=1;
}
void mergeset (symset s1,symset s2)
{
int i;
for(i=0;i<=31;i++)
if(s2[i]&&!s1[i])
s1[i]=1;
}
void test (symset s1,symset s2,int n)
{
symset sstemp;
if(!insymbol(s1))
{
error(n);
if(s1==facbegsys)
{
reset(sstemp);
mergeset(sstemp,s1);
mergeset(sstemp,s2);
while(!insymbol(sstemp))
getsym();
}
else
{
mergeset(s1,s2);
while(!insymbol(s1))
getsym();
}
}
}
void block (int lev,int tx,symset fsys)
{
int dx,tx0,cx0;
symset ss;
dx=3;
tx0=tx;
table[tx].cvp.vp.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(procedur,&tx,&dx,lev);
getsym();
}
else
error(4);
if(sym==semicolon)
getsym();
else
error(5);
reset(ss);
additem(ss,semicolon);
mergeset(ss,fsys);
block(lev+1,tx,ss);
if(sym==semicolon)
{
getsym();
reset(ss);
additem(ss,ident);
additem(ss,procsym);
mergeset(ss,statbegsys);
test(ss,fsys,6);
}
else
error(5);
}
reset(ss);
additem(ss,ident);
mergeset(ss,statbegsys);
test(ss,declbegsys,7);
}while(insymbol(declbegsys));
code[table[tx0].cvp.vp.adr].a=cx;
table[tx0].cvp.vp.adr=cx;
table[tx0].cvp.vp.size=dx;
cx0=cx;
gen(int0,0,dx);
reset(ss);
additem(ss,semicolon);
additem(ss,endsym);
mergeset(ss,fsys);
statement(ss,tx,lev);
gen(opr,0,0);
reset(ss);
test(fsys,ss,8);
listcode(cx0);
}
void enter (object k,int *tx,int *dx,int lev)
{
(*tx)++;
strcpy(table[*tx].name,id);
table[*tx].kind=k;
switch(k)
{
case constant:
if(num>amax)
{
error(31);
num=0;
}
table[*tx].cvp.val=num;
break;
case variable:
table[*tx].cvp.vp.level=lev;
table[*tx].cvp.vp.adr=*dx;
(*dx)++;
break;
case procedur:
table[*tx].cvp.vp.level=lev;
}
}
int position (alfa id,int tx)
{
int i;
strcpy(table[0].name,id);
i=tx;
while(strncmp(table[i].name,id,10))
i--;
return i;
}
void constdeclaration (int *tx,int *dx,int lev)
{
symset ss;
if(sym==ident)
{
getsym();
reset(ss);
additem(ss,eql);
additem(ss,becomes);
if(insymbol(ss))
{
if(sym==becomes)
error(1);
getsym();
if(sym==number)
{
enter(constant,tx,dx,lev);
getsym();
}
else
error(2);
}
else
error(3);
}
else
error(4);
}
void vardeclaration (int *tx,int *dx,int lev)
{
if(sym==ident)
{
enter(variable,tx,dx,lev);
getsym();
}
else
error(4);
}
void listcode (int cx0)
{
int i;
if(listswitch)
{
for(i=cx0;i<cx;i++)
{
printf("%3d %s%3d%5d\n",i,mnemonic[code[i].f],code[i].l,code[i].a);
fprintf(fa,"%3d %s%3d%5d\n",i,mnemonic[code[i].f],code[i].l,code[i].a);
}
}
}
void statement(symset fsys,int tx,int lev)
{
int i,cx1,cx2;
symset ss;
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(i!=0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -