📄 lrsemanticor.cpp
字号:
/******************************************************************************
*模块名:LR语义处理程序
*
*功能:在LR语法分析器作归约动作时,生成相应的四元式中间代码。
*
*开始时间:2004.11.8
*
*修改时间:2004.11.8,2004.11.9,2004.11.14,2004.11.15,2004.11.20
*
*完成时间:2004.11.20
*
*作者: 宋如强
*
*
*******************************************************************************/
#include "RecurAnalyser.c"
Quatype Qualist[100]; //四元式表,不得超过200条四元式
stack<Operand> place; //变量栈
stack<int> chain; //回填链栈
stack<int> quad; //比较运算符栈
stack<int> spro; //调用子过程时,将该子过程在过程表中的序号保存
queue<Operand> part; //参数队列
int K; //临时变量序号
char* signCache[5]; //保留规约时从符号栈弹出的字符,以便语义分析时使用。
///////////////////////////////////////////////////////////////////////////////////////
int searchVTable(char *v);
void enterVTable(int flag);
void getWord();
///////////////////////////////////////////////////////////////////////////////////////
//回填模块
//参数:待回填的四元式序号,回填内容(第四元的值)
//返回值:无
void BACKPATCH(int QuaS,int QuaA)
{
Qualist[QuaS].opr3.name=NULL; //常数
Qualist[QuaS].opr3.type=1;
Qualist[QuaS].opr3.offset=QuaA;
Qualist[QuaS].opr3.rlevel=0;
}
///////////////////////////////////////////////////////////////////////////////////////
//填四元式表模块
//参数:操作码编码,3个操作数
//返回值:无
void GEN(int strOperator,Operand op1,Operand op2,Operand op3)
{
Quatype temp; //四元式
if(isTrue==false) return;
temp.strOperator=strOperator; //给四元式操作码赋值
//给四元式第一操作数赋值
temp.opr1.type=op1.type;
if(op1.type==-1) //不使用
{
temp.opr1.name=NULL;
temp.opr1.offset=-1;
temp.opr1.rlevel=-1;
}
else if(op1.type==1) //常数
{
temp.opr1.name=NULL;
temp.opr1.offset=op1.offset; //常数值
temp.opr1.rlevel=0;
}
else if(op1.type==2) //临时变量
{
temp.opr1.name=op1.name;
temp.opr1.offset=op1.offset;
temp.opr1.rlevel=0;
}
else //变量
{
temp.opr1.name=op1.name;
temp.opr1.offset=op1.offset;
temp.opr1.rlevel=op1.rlevel;
}
//给四元式第二操作数赋值
temp.opr2.type=op2.type;
if(op2.type==-1) //不使用
{
temp.opr2.name=NULL;
temp.opr2.offset=-1;
temp.opr2.rlevel=-1;
}
else if(op2.type==1) //常数
{
temp.opr2.name=NULL;
temp.opr2.offset=op2.offset; //常数值
temp.opr2.rlevel=0;
}
else if(op2.type==2) //临时变量
{
temp.opr2.name=op2.name;
temp.opr2.offset=op2.offset;
temp.opr2.rlevel=0;
}
else //变量
{
temp.opr2.name=op2.name;
temp.opr2.offset=op2.offset;
temp.opr2.rlevel=op2.rlevel;
}
//给四元式第三操作数赋值
temp.opr3.type=op3.type;
if(op3.type==-1) //不使用
{
temp.opr3.name=NULL;
temp.opr3.offset=-1;
temp.opr3.rlevel=-1;
}
else if(op3.type==1) //常数
{
temp.opr3.name=NULL;
temp.opr3.offset=op3.offset; //常数值
temp.opr3.rlevel=0;
}
else if(op3.type==2) //临时变量
{
temp.opr3.name=op3.name;
temp.opr3.offset=op3.offset;
temp.opr3.rlevel=0;
}
else //变量
{
temp.opr3.name=op3.name;
temp.opr3.offset=op3.offset;
temp.opr3.rlevel=op3.rlevel;
}
Qualist[PC++]=temp;
}
///////////////////////////////////////////////////////////////////////////////////////
//过程调用合理性检查模块
//参数:待检查的过程名
//返回值:调用失败返回-1,成功返回该过程序号
int CHECK(char *temp)
{
int i,j;
i=0;
while(strcmp(ProcTable.table[i].pname,temp)!=0&&i<20)
{
i++;
}
if(i==20) return -1; //检查是否已定义
if(ProcTable.table[i].paranum!=part.size()) return -1; //检查参数个数
j=level-ProcTable.table[i].plevel; //检查调用关系
if(j==-1) return i; //外过程调用内一层
if(j==0) return i; //同层调用(已定义)
if(j==1) //内过程调用外过程
{
j=spro.top(); //取该语句所在过程序号
if(ProcTable.table[j].outposition==i) return i;
}
return -1;
}
///////////////////////////////////////////////////////////////////////////////////////
//输出四元式模块
//参数:无
//返回值:无
void OUTQ(void)
{
char *temp;
int i;
FILE *fp;
Qualist[PC].strOperator=-1; //设置四元式表结束标志。(多输出一条无效的四元式)
fp=fopen("qualist.txt","w");
for(i=0;i<100;i++)
{
switch(Qualist[i].strOperator) //将操作码编号转换成名称
{
case 0:
temp=(char*)malloc(2*sizeof(char));
strcpy(temp,"a");
break;
case 1:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"add");
break;
case 2:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"sub");
break;
case 3:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"mul");
break;
case 4:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"div");
break;
case 5:
temp=(char*)malloc(7*sizeof(char));
strcpy(temp,"become");
break;
case 6:
temp=(char*)malloc(5*sizeof(char));
strcpy(temp,"call");
break;
case 7:
temp=(char*)malloc(7*sizeof(char));
strcpy(temp,"return");
break;
case 8:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"int");
break;
case 9:
temp=(char*)malloc(5*sizeof(char));
strcpy(temp,"stop");
break;
case 10:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"par");
break;
case 11:
temp=(char*)malloc(5*sizeof(char));
strcpy(temp,"jump");
break;
case 12:
temp=(char*)malloc(3*sizeof(char));
strcpy(temp,"j>");
break;
case 13:
temp=(char*)malloc(3*sizeof(char));
strcpy(temp,"j<");
break;
case 14:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"j>=");
break;
case 15:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"j<=");
break;
case 16:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"j<>");
break;
case 17:
temp=(char*)malloc(3*sizeof(char));
strcpy(temp,"j=");
break;
case 18:
temp=(char*)malloc(5*sizeof(char));
strcpy(temp,"read");
break;
case 19:
temp=(char*)malloc(7*sizeof(char));
strcpy(temp,"readln");
break;
case 20:
temp=(char*)malloc(6*sizeof(char));
strcpy(temp,"write");
break;
case 21:
temp=(char*)malloc(8*sizeof(char));
strcpy(temp,"writeln");
break;
case 22:
temp=(char*)malloc(5*sizeof(char));
strcpy(temp,"main");
break;
default:
temp=(char*)malloc(4*sizeof(char));
strcpy(temp,"^_^");
break;
}
printf("%2d%8s%12s,%2d,%3d,%2d%12s,%2d,%3d,%2d%12s,%2d,%3d,%2d\n",i,temp,Qualist[i].opr1.name,
Qualist[i].opr1.type,Qualist[i].opr1.offset,Qualist[i].opr1.rlevel,Qualist[i].opr2.name,
Qualist[i].opr2.type,Qualist[i].opr2.offset,Qualist[i].opr2.rlevel,Qualist[i].opr3.name,
Qualist[i].opr3.type,Qualist[i].opr3.offset,Qualist[i].opr3.rlevel);
fprintf(fp,"%2d%8s%8d,%3d,%2d%8d,%3d,%2d%8d,%3d,%2d\n",i,temp,
Qualist[i].opr1.type,Qualist[i].opr1.offset,Qualist[i].opr1.rlevel,
Qualist[i].opr2.type,Qualist[i].opr2.offset,Qualist[i].opr2.rlevel,
Qualist[i].opr3.type,Qualist[i].opr3.offset,Qualist[i].opr3.rlevel);
if(i%23==0) scanf("%c",temp); //分屏显示
if(Qualist[i].strOperator==-1)
{
fclose(fp);
return; //结束
}
}
}
///////////////////////////////////////////////////////////////////////////////////////
//LR语义处理总控模块
//参数:产生式编号
//返回值:成功返回true,失败返回false
bool LRSemanticor(int productor)
{
switch(productor)
{
char *value; //用于存放规约式的字符名
char c[4];
int num; //用于存放变量在变量表中的下标
Operand temp1,temp2,temp3; //用于存放操作数
case 1: return true;
case 2: return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -