📄 yy.cpp
字号:
#include "cifa.h"
#include "iostream.h"
#include "stdlib.h"
# define FALSE false
# define TRUE true
//FILE *fp1;
//fp1=fopen("sour.txt","r");
cifa c1(fopen("sour.txt","r"));
int qiantao=0;//钱掏变量
struct errorType
{
int ErrorNumber;//语法语义错误代码
int ErrorAddress;//语义错误对应二元式的地址
};
struct yujutype
{
int Etyp;
int Evalue;
int TC;
int FC;
int Code;
};
struct idtype //标识符表
{
char name[20];//名字
int typ;//类型1:integer,2:real,3:program or procedure name
int kind;//属性1:简单变量,2:临时变量,3:值参变量,4:变参变量
int addr;//地址
};
struct leveltype //层次表
{
char name[20];//名字
int outern;//外层
int lnum;//层次号
int parnum;//参数个数
int varnum;//变量个数
int pointer;//标识符表首址
int recl;//活动记录长度
int temp;//临时变量首址
int lnp;//入口
};
struct temptype //
{
bool used;//
int typ;//
int taddr;//
};
struct argtype //
{
int fl;//类型1:常数2:指令入口3:临时变量4:直接访问变量5:间接访问变量6+i:第i外层变量
int flvalue;//值 常数值|指令地址|相对地址
};
struct quadtype //四元式表
{
int op;//操作
argtype arg1;//操作数
argtype arg2;//操作数
argtype result;//结果
};
struct quanjutype //变量
{
int lasent;//标识符表长度指针
int lastbl;//层次表长度指针
int currbl;//当前层指针
int tempp;//变量表藏度指针
int nxq;//四元式表长度指针
};
errorType errorvalue;
yujutype yujuvalue;
CifaResult yy_tCifa[500];
char yy_QuadOpCodeTable[30][10];
char yy_tErrorMessage[100][30];
int yy_pCurSym=0;
void coutgen();
void coutty();
int merge(int,int,int);
int newtemp(int);
int lookupp(char *);
int lookupv_onelevel(char *,int);
void backpatch(int,int,int,int);
void addid(char *,int,int,int);
quanjutype quanjuvalue;
void gen(char *,int,int,int,int,int,int);
idtype idtab[10000];
leveltype leveltab[100];
temptype temptab[100];
quadtype quad[10000];
int yy_nErrorAddress;
int yy_nErrorNum;
CifaResult GetNextSym();
void NextSym();
CifaResult GetCurSym();
void initial();
int s_GuanXi();
int s_GuanXiBiaoDaShi();
int s_BuErBiaoDaShi();
int s_YingZi();
int s_Xiang();
int s_BiaoDaShi();
int s_XunHuanYuJu();
int s_TiaoJianYuJu();
int s_FuZhiYuJu();
int s_FuHeYuJu();
int s_YuJu();
int s_YuJuChuan();
int s_XingChan();
int s_XingChanBuFeng();
int s_JianBianShuoMing();
int s_ShuoMing();
int s_ShuoMingChuan();
int s_ChengXuTi();
int s_ChengXu();
void gen(char * op,int a1,int a2,int a3,int a4,int a5,int a6)
{
if (quanjuvalue.nxq>=1000-1) return;
int r=29;
for (int i=0;i<1000;i++)
{
if (!stricmp(yy_QuadOpCodeTable[i],op))
{
r=i;break;
}
}
quad[quanjuvalue.nxq].op=r;
quad[quanjuvalue.nxq].arg1.fl=a1;
quad[quanjuvalue.nxq].arg1.flvalue=a2;
quad[quanjuvalue.nxq].arg2.fl=a3;
quad[quanjuvalue.nxq].arg2.flvalue=a4;
quad[quanjuvalue.nxq].result.fl=a5;
quad[quanjuvalue.nxq].result.flvalue=a6;
quanjuvalue.nxq++;
}
void addid(char * name, int typ, int kind, int addr)
{
if (quanjuvalue.lasent>=1000-1) return;
::strcpy(idtab[quanjuvalue.lasent].name,name);
idtab[quanjuvalue.lasent].typ=typ;
idtab[quanjuvalue.lasent].kind=kind;
idtab[quanjuvalue.lasent].addr=addr;
quanjuvalue.lasent++;
}
void backpatch(int link, int point, int v1, int v2)
{
if (link==0) return;
switch (point)
{
case 2:
backpatch(quad[link].arg1.fl,point,v1,v2);
quad[link].arg1.fl=v1;
quad[link].arg1.flvalue=v2;
break;
case 3:
backpatch(quad[link].arg2.fl,point,v1,v2);
quad[link].arg2.fl=v1;
quad[link].arg2.flvalue=v2;
break;
case 4:
backpatch(quad[link].result.fl,point,v1,v2);
quad[link].result.fl=v1;
quad[link].result.flvalue=v2;
break;
default:
return;
}
}
int lookupp(char * id)
{
for (int i=0;i<quanjuvalue.lastbl;i++)
if (!::stricmp(id,leveltab[i].name)) return i;
return -1;
}
int lookupv_onelevel(char * idname, int idlevel)//
{
if (!::stricmp(idname,leveltab[idlevel].name)) return -1;
int n=leveltab[idlevel].varnum+leveltab[idlevel].parnum;
int pointer=leveltab[idlevel].pointer;
for (int i=pointer;i<(pointer+n);i++)
if (!::stricmp(idname,idtab[i].name)) return i;
return 0;
}
int lookupv_alllevel(char * name, int & level)
{
int i=level;
int r;
while(1)
{
if (i<0) return 0;
r=lookupv_onelevel(name,i);
switch (r)
{
case -1:
level=i;
return -1;
case 0:
i--;
break;
default:
level=i;
return r;
}
}
}
CifaResult GetCurSym()
{
return yy_tCifa[yy_pCurSym];
}
void NextSym()
{
yy_pCurSym++;
}
CifaResult GetNextSym()
{
return yy_tCifa[yy_pCurSym+1];
}
int YuYiFengXi()
{
quanjuvalue.currbl=0;
quanjuvalue.lasent=0;
quanjuvalue.lastbl=0;
quanjuvalue.nxq=0;
quanjuvalue.tempp=0;
gen("",0,0,0,0,0,0);//idtab start from 1
addid("",0,0,0);//idtab start from 1
yy_pCurSym=0;
if(!s_ChengXu()) return FALSE;
gen("_End_",0,0,0,0,0,0);//end note
return 1;
}
int s_ChengXu()
{
switch (GetCurSym().type)
{
case 3://program
break;
default:
yy_nErrorNum=3;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
switch (GetCurSym().type)
{
case 1://id
break;
default:
yy_nErrorNum=4;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
//yy
//对层次的副直
leveltab[quanjuvalue.currbl].lnp=quanjuvalue.nxq+1;
//cout<<"fasdfas乱七八糟 "<<leveltab[quanjuvalue.currbl].lnp<<endl;
leveltab[quanjuvalue.currbl].lnum=0;
strcpy(leveltab[quanjuvalue.currbl].name,GetCurSym().text);
leveltab[quanjuvalue.currbl].outern=0;
leveltab[quanjuvalue.currbl].parnum=0;
leveltab[quanjuvalue.currbl].pointer=quanjuvalue.lasent;
leveltab[quanjuvalue.currbl].recl=5;
leveltab[quanjuvalue.currbl].varnum=0;
leveltab[quanjuvalue.currbl].temp=quanjuvalue.tempp;
quanjuvalue.lastbl++;
gen("call",1,0,1,0,2,2);
int link=quanjuvalue.nxq;
gen("in",0,0,0,0,0,0);
//yy end
NextSym();
switch (GetCurSym().type)
{
case 30://;
break;
default:
yy_nErrorNum=5;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
if (!s_ChengXuTi()) return FALSE;
//yy
// printf("饿我我哦我外哦我哦我我忘我欧文\n");
backpatch(link,2,2,leveltab[quanjuvalue.currbl].recl);
gen("out",0,0,0,0,0,0);
gen("ret",0,0,0,0,0,0);
quanjuvalue.currbl=leveltab[quanjuvalue.currbl].outern;
quanjuvalue.tempp=leveltab[quanjuvalue.currbl].temp;
//yy end
switch (GetCurSym().type)
{
case 31://.
break;
default:
yy_nErrorNum=6;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
return TRUE;
}
int s_ChengXuTi()
{
switch (GetCurSym().type)
{
case 14://integer
case 15://real
// case 5://procedure程序不要过程
if (!s_ShuoMingChuan()) return FALSE;
switch (GetCurSym().type)
{
case 30://;
break;
default:
yy_nErrorNum=5;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
break;
case 6://begin
break;
default:
yy_nErrorNum=7;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
switch (GetCurSym().type)
{
case 6://begin
break;
default:
yy_nErrorNum=8;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
if (!s_YuJuChuan()) return FALSE;
//cout<<"我爱我爱我爱我爱"<<endl;
switch (GetCurSym().type)
{
case 7://end
break;
default:
yy_nErrorNum=10;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
return TRUE;
}
int s_ShuoMingChuan()
{
if (!s_ShuoMing()) return FALSE;
while (GetCurSym().type==30
&& GetNextSym().type!=6)//; begin
{
NextSym();
if (!s_ShuoMing()) return FALSE;
}
return TRUE;
}
int s_ShuoMing()
{
switch (GetCurSym().type)
{
case 14://integer
case 15://real
if (!s_JianBianShuoMing()) return FALSE;
break;
//case 5://procedure
//if (!s_GuoChengShuoMing()) return FALSE;
// break;
default:
yy_nErrorNum=11;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
return TRUE;
}
int s_JianBianShuoMing()
{
int typ;//yy
switch (GetCurSym().type)
{
case 14://integer
typ=1;//yy
break;
case 15://real
typ=2;//yy
break;
default:
yy_nErrorNum=12;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
switch (GetCurSym().type)
{
case 1://id
break;
default:
yy_nErrorNum=14;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
//yy
switch (lookupv_onelevel(GetCurSym().text,quanjuvalue.currbl))
{
case -1:
yy_nErrorNum=31;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
case 0:
addid(GetCurSym().text,typ,1,leveltab[quanjuvalue.currbl].recl);
leveltab[quanjuvalue.currbl].varnum++;
leveltab[quanjuvalue.currbl].recl+=typ;
break;
default:
yy_nErrorNum=32;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
//yy end
NextSym();
while (GetCurSym().type==32) //,
{
NextSym();
switch (GetCurSym().type)
{
case 1://id
break;
default:
yy_nErrorNum=14;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
//yy
switch (lookupv_onelevel(GetCurSym().text,quanjuvalue.currbl))
{
case -1:
yy_nErrorNum=31;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
case 0:
addid(GetCurSym().text,typ,1,leveltab[quanjuvalue.currbl].recl);
leveltab[quanjuvalue.currbl].varnum++;
leveltab[quanjuvalue.currbl].recl+=typ;
break;
default:
yy_nErrorNum=32;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
//yy end
NextSym();
}
return TRUE;
}
int s_YuJuChuan()
{
if (!s_YuJu()) return FALSE;
while (GetCurSym().type==30)//;
{
NextSym();
if (!s_YuJu()) return FALSE;
}
cout<<"语句串结束"<<endl;
return TRUE;
}
int s_YuJu()
{
switch (GetCurSym().type)
{
case 6://begin
if (!s_FuHeYuJu()) return FALSE;
break;
case 1://id
if (!s_FuZhiYuJu()) return FALSE;
break;
case 8://if
if (!s_TiaoJianYuJu()) return FALSE;
break;
case 11://while
if (!s_XunHuanYuJu()) return FALSE;
break;
// case 13://call
// if (!s_GuoChengYuJu()) return FALSE;
// break;
default:
yy_nErrorNum=9;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
return TRUE;
}
int s_FuHeYuJu()
{
switch (GetCurSym().type)
{
case 6://begin
break;
default:
yy_nErrorNum=8;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
if (!s_YuJuChuan()) return FALSE;
switch (GetCurSym().type)
{
case 7://end
break;
default:
yy_nErrorNum=10;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
return TRUE;
}
int s_FuZhiYuJu()
{
switch (GetCurSym().type)
{
case 1://id
break;
default:
yy_nErrorNum=20;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
//yy
int idlevel=quanjuvalue.currbl;
int idpoint=lookupv_alllevel(GetCurSym().text,idlevel);
if (idpoint==0)
{
yy_nErrorNum=33;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
if (idpoint==-1)
{
yy_nErrorNum=34;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
int t1=idtab[idpoint].typ;
int k1=idtab[idpoint].addr;
int i1;
if (idlevel==quanjuvalue.currbl)
{
if (idtab[idpoint].kind==4) i1=5;
else i1=4;
}
else
{
i1=idlevel+6;
}
//yy end
NextSym();
switch (GetCurSym().type)
{
case 29://:=
break;
default:
yy_nErrorNum=21;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
if (!s_BiaoDaShi()) return FALSE;
//yy
int t2;
int k2;
int i2=yujuvalue.Etyp;
int j2=yujuvalue.Evalue;
if (i2==1)
{
k2=j2;
t2=1;
}
else if (i2==2)
{
k2=temptab[j2].taddr;
t2=temptab[j2].typ;
i2=3;
}
else
{
k2=idtab[j2].addr;
t2=idtab[j2].typ;
i2+=1;
}
if (t1<t2)
{
yy_nErrorNum=35;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
if (t1==1) gen(":=I",i1,k1,i2,k2,0,0);
else gen(":=R",i1,k1,i2,k2,0,0);
if (i2==3) temptab[j2].used=FALSE;
//yy end
return TRUE;
}
int s_TiaoJianYuJu()
{
switch (GetCurSym().type)
{
case 8://if
break;
default:
yy_nErrorNum=22;
yy_nErrorAddress=yy_pCurSym;
return FALSE;
}
NextSym();
if (!s_BuErBiaoDaShi()) return FALSE;
//yy
int TCexit=yujuvalue.TC;
int FCexit=yujuvalue.FC;
backpatch(TCexit,4,2,quanjuvalue.nxq);
// cout<<"if语句的真出口"<<quanjuvalue.nxq<<endl;
//yy end
switch (GetCurSym().type)
{
case 9://then
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -