📄 pl0 in c.c
字号:
/*-------------pl/0 program in c---------- */
/*-------------only for reading.----------------------------------*/
//#include <iostream.h>
//#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//#include "stdich.c"
/* #include <string.h> */
/*-------------------------define constant------------------------*/
# define norw 16
# define txmax 100
# define al 10
# define nmax 14
# define amax 2047
# define levmax 3
# define cxmax 200
# define stacksize 500
/*-----------------------type define-----------------------------*/
typedef char alfa[10];
typedef struct { int level, adr, size, val, foot;
alfa name, kind; } tbl;
typedef struct { char f[5];
int l,a; } instruction;
typedef struct { alfa sy[30]; } symset;
/*------------------------------variable declaration------------------------*/
int ll,cc,listswitch,err,ch,num,kk,cx,line[81],s[stacksize];
alfa id,sym,a,fname;
instruction code[cxmax+1];
tbl table[txmax+1];
FILE *finf;
alfa word[norw+1]={"0","begin","call","const","do","else","end",
"if","odd","procedure","read","repeat","then",
"until","var","while","write"};
alfa wsym[norw+1]={"0","beginsym","callsym","constsym",
"dosym","elsesym","endsym","ifsym","oddsym",
"procsym","readsym","repeatsym","thensym","untilsym","varsym",
"whilesym","writesym"};
alfa ssym[52]={"period","lss","lparen","plus","4","5","6","7","8",
"9","10","11","12","13","14","15","16","times","rparen",
"semicolon","20","minus","slash","23","24","25","26",
"27","28","29","30","31","comma","33","34","35","36",
"37","38","39","40","41","42","43","44","45","46",
"colon","neq","49","50","eql"};
symset declbegsys={"constsym","varsym","procsym","*"};
symset statbegsys={"beginsym","callsym","ifsym","repeatsym","whilesym","*"};
symset facbegsys={"ident","number","lparen","*"};
symset fsysa={"period","constsym","varsym","procsym",
"beginsym","callsym","ifsym","whilesym","repeat","*"};
/*-----------------------------main( )-----------------------------------*/
void main()
{
printf("input file ?");
scanf("%s", fname);
printf("%s\n", fname);
finf=fopen(fname,"r");
//printf(fopen(fname, "r"));
printf("list code ? ");
scanf("%s", fname);
printf("%s\n", fname);
if (fname[0]=='y')
listswitch=1;
else
listswitch=0;
err=cc=ll=cx=0;
kk=10;
ch=' ';
getsym( );
block(0,0,fsysa);
if (strcmp(sym,"period"))
error(9);
if (err==0)
interpret( );
else
printf("error in pl/0 program !\n");
}
/*------------------------------block (lev, tx, fsys)-----------------------------*/
block(lev,tx,fsys)
symset fsys;
int lev,tx;
{
int tx0,tx1,cx0,dx;
symset fsys1;
dx=3;
tx0=tx;
table[tx].adr=cx;
gen("jmp",0,0);
if (lev>levmax)
error(32);
do
{
if (strcmp(sym,"constsym")==0)
{
getsym( );
do
{
constdeclaration(&dx,&tx,lev);
while (strcmp(sym,"comma")==0)
{
getsym( );
constdeclaration(&dx,&tx,lev);
}
if (strcmp(sym,"semicolon")==0)
getsym( );
else
error(5);
} while (strcmp(sym,"ident")==0);
}
if (strcmp(sym,"varsym")==0)
{
getsym( );
do
{
vardeclaration(&dx,&tx,lev);
while (strcmp(sym,"comma")==0)
{
getsym();
vardeclaration(&dx,&tx,lev);
}
if (strcmp(sym,"semicolon")==0)
getsym( );
else
error(5);
} while (strcmp(sym,"ident")==0);
}
while (strcmp(sym,"procsym")==0)
{
getsym();
if (strcmp(sym,"ident")==0)
{
enter("procedure",&dx,&tx,lev);
getsym( );
}
else
error(4);
if (strcmp(sym,"semicolon")==0)
getsym( );
else
error(5);
insert("semicolon",fsys,&fsys1);
block(lev+1,tx,fsys1);
if (strcmp(sym,"semicolon")==0)
{
getsym( );
insert("ident",statbegsys,&fsys1);
insert("procsym",fsys1,&fsys1);
test(fsys,fsys1,6);
}
else
error(5);
}
insert("ident",statbegsys,&fsys1);
test(fsys1,declbegsys,7);
} while (in(sym,declbegsys));
code[table[tx0].adr].a=cx;
table[tx0].adr=cx;
table[tx0].size=dx;
cx0=cx;
gen("int",0,dx);
insert("semicolon",fsys,&fsys1);
insert("endsym",fsys1,&fsys1);
statement(fsys1,tx,lev);
gen("opr",0,0);
test(fsys,fsys,8);
listcode(cx0);
}
/*-----------------------------------statement (fsys, tx, lev)---------------------*/
statement(fsys,tx,lev)
symset fsys;
int tx,lev;
{
symset fsys1;
int i,cx1,cx2;
if (strcmp(sym,"ident ")==0)
{
i=position(id,tx);
if (i==0)
error(11);
else
if (strcmp(table[i].kind,"variable")!=0)
{
error(12);
i=0;
}
//i=ifarr(fsys,tx,lev,i); //add
getsym( );
if (strcmp(sym,"becomes")==0)
getsym( );
else
error(13);
expression(fsys,tx,lev);
if (i!=0)
gen("sto",lev-table[i].level,table[i].adr);
}
else
if (strcmp(sym,"readsym")==0)
{
getsym( );
if (strcmp(sym,"lparen")!=0)
error(34);
else
do
{
getsym ( );
//if (strcmp (sym, "lparen")== 0)
// error (34);
if (strcmp(sym,"ident")==0)
i=position(id,tx);
else
i=0;
if (i==0)
error(35);
else
{
//i=ifarr(fsys,tx,lev,i); //add
gen("opr",0,16);
gen("sto",lev-table[i].level,table[i].adr);
}
getsym( );
} while (strcmp(sym,"comma")==0);
if (strcmp(sym,"rparen")!=0)
{
error(33);
while (in(sym,fsys)==0)
getsym( );
}
else
getsym();
}
else
if (strcmp(sym,"writesym")==0)
{
getsym();
if (strcmp(sym,"lparen")==0)
{
do
{
getsym( );
insert("rparen",fsys,&fsys1);
insert("comma",fsys1,&fsys1);
expression(fsys1,tx,lev);
gen("opr",0,14);
} while (strcmp(sym,"comma")==0);
if (strcmp(sym,"rparen")!=0)
error(33);
else
getsym( );
}
gen("opr",0,15);
}
else
if (strcmp(sym,"callsym")==0)
{
getsym( );
if (strcmp(sym,"ident")!=0)
error(14);
else
{
i=position(id, tx);
if (i==0)
error(11);
else
if (strcmp(table[i].kind,"procedure"))
error(15);
else
gen("cal",lev-table[i].level,table[i].adr);
getsym( );
}
}
else
if (strcmp(sym,"ifsym")==0)
{
getsym( );
insert("thensym",fsys,&fsys1);
condition(fsys1,tx,lev);
if (strcmp(sym,"thensym")==0)
getsym( );
else
error(16);
cx1=cx;
gen("jpc",0,0);
//insert("elsesym",fsys,&fsys1);//add
statement(fsys,tx,lev);
//if (strcmp(sym,"elsesym")!=0)//add
code[cx1].a=cx;
/*else //
{//
cx2=cx;//
gen("jmp",0,0);//
code[cx1].a=cx;//
getsym();//
statement(fsys,tx,lev);//
code[cx2].a=cx;//
}//*/
}
else
if (strcmp(sym,"beginsym")==0)
{
getsym( );
insert("semicolon",fsys,&fsys1);
insert("endsym",fsys1,&fsys1);
statement(fsys1,tx,lev);
while (in(sym,statbegsys) || (strcmp(sym,"semicolon")==0))
{
if (strcmp(sym,"semicolon")==0)
getsym( );
else
error(10);
statement(fsys1,tx,lev);
}
if (strcmp(sym,"endsym")==0)
getsym( );
else
error(17);
}
else
if (strcmp(sym,"whilesym")==0)
{
cx1=cx;
getsym( );
insert("dosym",fsys,&fsys1);
condition(fsys1,tx,lev);
cx2=cx;
gen("jpc",0,0);
if (strcmp(sym,"dosym")==0)
getsym( );
else
error(18);
statement(fsys,tx,lev);
gen("jmp",0,cx1); /* has been changed */
code[cx2].a=cx;
}
//add begin
/*else
if (strcmp(sym,"repeatsym")==0)
{
getsym();
cx1=cx;
insert("semicolon",fsys,&fsys1);
insert("untilsym",fsys1,&fsys1);
statement(fsys1,tx,lev);
while (in(sym,statbegsys)||(strcmp(sym,"semicolon")==0))
{
if (strcmp(sym,"semicolon")==0)
getsym();
else
error(60);
statement(fsys1,tx,lev);
}
if (strcmp(sym,"untilsym")==0)
getsym();
else
error(61);
insert("semicolon",fsys,&fsys1);
condition(fsys1,tx,lev);
gen("jpc",0,cx1);
}*/
//add end
test(fsys,fsys,19);
}
/*----------------------condition (fsys, tx, lev)----------------------*/
condition(fsys,tx,lev)
symset fsys;
int tx,lev;
{
alfa relop;
symset fsys1;
if (strcmp(sym,"oddsym")==0)
{
getsym( );
expression(fsys,tx,lev);
gen("opr",0,6);
}
else
{
insert("eql",fsys,&fsys1);
insert("neq",fsys1,&fsys1);
insert("lss",fsys1,&fsys1);
insert("leq",fsys1,&fsys1);
insert("gtr",fsys1,&fsys1);
insert("geq",fsys1,&fsys1);
expression(fsys1,tx,lev);
if ((strcmp(sym,"eql")!=0) && (strcmp(sym,"neq")!=0)
&& (strcmp(sym,"lss")!=0) && (strcmp(sym,"leq")!=0)
&&(strcmp(sym,"gtr")!=0) && (strcmp(sym,"geq")!=0))
error(20);
else
{
strcpy(relop,sym);
getsym( );
expression(fsys,tx,lev);
if (strcmp(relop,"eql")==0) gen("opr",0,8);
if (strcmp(relop,"neq")==0) gen("opr",0,9);
if (strcmp(relop,"lss")==0) gen("opr",0,10);
if (strcmp(relop,"leq")==0) gen("opr",0,11);
if (strcmp(relop,"gtr")==0) gen("opr",0,12);
if (strcmp(relop,"geq")==0) gen("opr",0,13);
}
}
}
/*-------------------expression (fsys, tx, lev)----------------------*/
expression(fsys,tx,lev)
symset fsys;
int tx,lev;
{
alfa addop;
symset fsys1;
insert("plus",fsys,&fsys1);
insert("minus",fsys1,&fsys1);
if ((strcmp(sym,"plus")==0) || (strcmp(sym,"minus")==0))
{
strcpy(addop,sym);
getsym( );
term(fsys1,tx,lev);
if (strcmp(addop,"minus")==0)
gen("opr",0,1);
}
else term(fsys1,tx,lev);
while ((strcmp(sym,"plus")==0) || (strcmp(sym,"minus")==0))
{
strcpy(addop,sym);
getsym( );
term(fsys1,tx,lev);
if (strcmp(addop,"plus")==0)
gen("opr",0,2);
else
gen("opr",0,3);
}
}
/*-----------------term (fsys, tx, lev)-----------------------*/
term(fsys,tx,lev)
symset fsys;
int tx,lev;
{
alfa mulop;
symset fsys1;
insert("times",fsys,&fsys1);
insert("slash",fsys1,&fsys1);
factor(fsys1,tx,lev);
while ((strcmp(sym,"times")==0) || (strcmp(sym,"slash")==0))
{
strcpy(mulop,sym);
getsym( );
factor(fsys1,tx,lev);
if (strcmp(mulop,"times")==0)
gen("opr",0,4);
else gen("opr",0,5);
}
}
/*------------------factor (fsys, tx, lev)--------------------*/
expression(fsys,tx,lev);
// Int ifarr(fsys,tx,lev,tt);
factor(fsys,tx,lev)
symset fsys;
int tx,lev;
{
symset fsys1;
int i;
test(facbegsys,fsys,24);
while (in(sym,facbegsys)==1)
{
if (strcmp(sym,"ident")==0)
{
i=position(id,tx);
if (i==0) error(11);
else
{
if (strcmp(table[i].kind,"constant")==0)
gen("lit",0,table[i].val);
if (strcmp(table[i].kind,"variable")==0)
{
//i=ifarr(fsys,tx,lev,i); //add
gen("lod",lev-table[i].level,table[i].adr);
}
if (strcmp(table[i].kind,"procedure")==0)
error(21);//getsym( );
}
getsym();//
}
else if (strcmp(sym,"number")==0)
{
if (num>amax)
{
error(31);
num =0;
}
gen("lit",0,num);
getsym( );
}
else if (strcmp(sym,"lparen")==0)
{
getsym();
insert("rparen",fsys,&fsys1);
expression(fsys1,tx,lev);
if (strcmp(sym,"rparen")==0)
getsym();
else error(22);
}
/* { if (num>amax)
{ error (31);
num=0;
}
gen ("lit",0, num);
getsym ( );
}
else if (strcmp (sym, "lparen")== 0)
{
if (num > amax)
{ error (31);
num=0;
}
gen ("lit", 0, num);
getsym ( );
}
else if (strcmp (sym, "lparen")== 0)
{ getsym ();
insert ("rparen", fsys, &fsys1);
expression (fsys1, tx, lev);
if (strcmp (sym, "rparen")== 0)
getsym( );
else error (22);
}*/
test(fsys,facbegsys,23);
}
}
/*-------------------vardeclaration (&dx, &tx, lev)---------------------*/
vardeclaration(dx,tx,lev) //very different with paper
int *dx,*tx,lev;
{
if (strcmp(sym,"ident")==0)
{
enter("variable",dx,tx,lev);
getsym();
}
else error(4);
}
/* ---------vardeclaration(&dx,&tx,lev)-------------*/
/*vardeclaration(dx,tx,lev)
int *dx,*tx,lev;
{
int i;
if (strcmp(sym,"ident")==0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -