📄 expressanalysis.h
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "WordAnalysis.h"
#define L2MAX 10
#define L1MAX 5
#define FH_NONE 0
#define FH_PRONAME 1
#define FH_XC 2
#define FH_VAR 3
#define FH_CONST 4
#define FIND_ALL 1
#define FIND_ONE 0
#define TRUE 1
#define FALSE 0
#define OP_NOT 1
#define OP_ADD 2
#define OP_SUB 3
#define OP_MUL 4
#define OP_DIV 5
#define OP_LESS 6
#define OP_LESSQ 7
#define OP_MORE 8
#define OP_MOREQ 9
#define OP_EQUAL 10
#define OP_NOEQUAL 11
#define OP_ODD 12
#define OP_RETURN 13
typedef struct opfhdis
{//用来标示符号表,函数的Display表
int pre;//调用该子函数的函数在fhdis中的位置,若是program自己,则pre=-1
int go;//函数在符号表入口地址
}opfhdis;
typedef struct opfhinfo
{//符号表中的信息项
int address;
int type;//类型:1过程名 2形参 3内部变量 4常量
int value;//常量的值,type为常量时有效
}opfhinfo;
typedef struct opaddfh
{
int type;//类型:1过程名 2形参 3内部变量 4常量
char mgc[L2MAX];//若插入的是函数名,表示包围该函数最内层的函数名
int value;//常量的值,type为常量时有效
}opaddfh;
typedef struct opfindfh
{
int type;//类型:0没找到 1过程名 2形参 3内部变量 4常量
int depth;//相对层数
int address;//相对地址
int value;//常量的值,type为常量时有效
}opfindfh;
typedef struct opfh
{
char name[L2MAX];//符号name
int pre;//在同一函数中,下一个符号在符号表中的位置,若是最后一个,记为-1
struct opfhinfo info;
}opfh;
typedef struct opfour
{
char op[L1MAX];
char arg1[L2MAX];
char arg2[L2MAX];
char result[L2MAX];
/* int retype;
union
{
int integer;
char str[L2MAX];
}result;*/
}opfour;
typedef struct opcode
{
char op[L1MAX];//操作类型
int arg1;//参数1
int arg2;//参数2
int line;//三元码所对应代码的行号
}opcode;
opfour four[100];
opfh fh[100];
opfhdis fhdis[50];
opcode code[100];
int stack[200];//数据栈
opcode nowcode;//当前的指令
int nextcode;//下一条指令的地址
int datatop;//指向数据栈栈顶
int database;//当前运行过程的数据区在STACK中的起始地址
char error[100];
opwords tempword;
class ExpressAnalysis
{
private:
int gennum,nowvar;
int fhdistop;
int fhtop;
int dtop;//符号表里的info项的address
int codenum;
char strtemp[L2MAX];
char tempmhs[L2MAX];
char savemhs[L2MAX];
WordAnalysis was;
opaddfh tempaddfh;
opfindfh tempfindfh;
public:
/* ExpressAnalysis(char *s1) { WordAnalysis was(text);}*/
int Get_forLen()
{
return gennum;
}
int Get_FhTop()
{
return fhtop;
}
int Get_FhdisTop()
{
return fhdistop;
}
int Get_codLen()
{
return codenum;
}
int FindMGC(char *data)
{//返回过程在符号display表中的下标,若过程是Program,返回0,若过程不存在,返回-1
int i;
if(strcmp(data,"program")==0) return 0;
for(i=1;i<fhdistop;i++)
{
if(strcmp(data,fh[fhdis[i].go-1].name)==0) return i;
}
return -1;
}
int FindFhOnegc(char *data,char *mgc,int *num)
{//查找data在同一个过程体里是否已经存在,若存在,返回TRUE,否则返回FALSE
int t,i;
t=FindMGC(mgc);
if(t==-1) {sprintf(error,"第%d行 过程定义有误",tempword.line);return FALSE;}
for(i=fhdis[t].go;fh[i].pre!=-1;i++)
{
if(0==strcmp(data,fh[i].name))
{
return TRUE;
*num=i;
}
}
*num=-1;
return TRUE;
}
int FindFh(char *data,char *mgc,opfindfh *findfh)
{ //若单词在符号表中存在,找出相对地址、层数的信息放在findfh里,并返回TRUE
//否则返回FALSE
int t,p,i,q;
q=t=FindMGC(mgc);
if(t==-1) {sprintf(error,"第%d行 过程定义有误",tempword.line);return FALSE;}
(*findfh).depth=0;
do
{ //找到的是常量/变量/形参
for(i=fhdis[t].go;fh[i].pre!=-1;i++)
{
if(0==strcmp(data,fh[i].name))
{
(*findfh).address=fh[i].info.address;
(*findfh).type=fh[i].info.type;
if(fh[i].info.type==FH_CONST)
(*findfh).value=fh[i].info.value;
return TRUE;
}
}
t=fhdis[t].pre;
(*findfh).depth++;
}while(t!=-1);
(*findfh).depth=0;
p=FindMGC(data);
if(p==-1) {sprintf(error,"第%d行 该标示符未被定义",tempword.line);return FALSE;}
for(i=p;i!=-1;i=fhdis[i].pre)
{
if(q==i)
{
(*findfh).address=fh[fhdis[p].go-1].info.address;
(*findfh).type=fh[fhdis[p].go-1].info.type;
return TRUE;
}
(*findfh).depth++;
}
(*findfh).type=FH_NONE;
sprintf(error,"第%d行 该标示符未被定义",tempword.line);
return FALSE;
}
int AddFh(char *data,opaddfh addfh)
{
int t,p;
if(addfh.type!=FH_PRONAME)
{ //加入符号表的不是过程名
if(FALSE==FindFhOnegc(data,addfh.mgc,&t)) return FALSE;
if(t!=-1)
{
sprintf(error,"第%d行 该标示符被重复定义",tempword.line);
return FALSE;
}
strcpy(fh[fhtop].name,data);
fh[fhtop].pre=fhtop+1;
fh[fhtop].info.type=addfh.type;
if(addfh.type==FH_CONST) fh[fhtop].info.value=addfh.value;
else fh[fhtop].info.address=++dtop;
fhtop++;
return TRUE;
}
else
{ //加入符号表的是过程名
t=FindMGC(data);
if(t!=-1)
{
sprintf(error,"第%d行 该过程被重复定义",tempword.line);
return FALSE;
}
p=FindMGC(addfh.mgc);
if(-1==p)
{
sprintf(error,"第%d行 过程定义有误",tempword.line);
return FALSE;
}
fhdis[fhdistop].pre=p;
fhdis[fhdistop].go=fhtop+1;
fhdistop++;
strcpy(fh[fhtop].name,data);
fh[fhtop].pre=-1;
fh[fhtop].info.address=codenum;
fh[fhtop].info.type=addfh.type;
fhtop++;
return TRUE;
}
}
void GenCode(char *op,int arg1,int arg2)
{ //产生机器码
strcpy(code[codenum].op,op);
code[codenum].arg1=arg1;
code[codenum].arg2=arg2;
if(tempword.type==SIGN_END) code[codenum].line=tempword.line-1;
else if(tempword.type==SIGN_PROCEDURE) code[codenum].line=tempword.line-1;
else if(tempword.type==SIGN_BEGIN) code[codenum].line=tempword.line-1;
else code[codenum].line=tempword.line;
if(strcmp(op,"LIT")==0)
{
datatop++;
}
else if(strcmp(op,"OPR")==0)
{
datatop--;
}
else if(strcmp(op,"LOD")==0)
{
datatop++;
}
else if(strcmp(op,"STO")==0)
{
datatop--;
}
else if(strcmp(op,"INT")==0)
{
datatop+=arg2;
}
else if(strcmp(op,"CAL")==0)
{
// datatop--;
}
else if(strcmp(op,"WRT")==0)
{
datatop--;
}
codenum++;
}
char *IntToStr(int num)
{ //整数转化为字符串
int t,wei=0;
t=num;
if(0==t)
{
strtemp[0]='0';
strtemp[1]='\0';
return strtemp;
}
else
{
while(t>0) {t/=10;wei++;}
strtemp[wei]='\0';
while(wei>0)
{
wei--;
strtemp[wei]=num%10+'0';
num=num/10;
}
return strtemp;
}
}
int MainAction(CString cstext)
{ //主要过程
char text[1000];
int len,i;
strcpy(text,cstext);
len=strlen(text);
text[len]='#';//结束符
text[len+1]='\0';
codenum=10;//三元码从10号地址开始
nowvar=1;
fhdistop=fhtop=0;//符号表,符号display表初始化
dtop=2;//任何变量、形参、常量的相对地址是从3开始的
for(i=0;i<100;i++)
fh[i].pre=-1;//符号表初始化
was.SetText(text);
tempword=was.GetOneWord();
if(tempword.type!=SIGN_NONE) return GetProg();
return TRUE;
}
int Match(opwords word,int type)
{ //若匹配,返回1,否则返回0
if(word.type!=type)
{
switch(type)
{
case SIGN_NAME:
sprintf(error,"第%d行 缺少变量",tempword.line);
break;
case SIGN_EVAL:
sprintf(error,"第%d行 缺少赋值号",tempword.line);
break;
case SIGN_EQUAL:
sprintf(error,"第%d行 缺少=",tempword.line);
break;
case SIGN_BEGIN:
sprintf(error,"第%d行 缺少begin",tempword.line);
break;
case SIGN_PROGRAM:
sprintf(error,"第%d行 缺少program",tempword.line);
break;
case SIGN_END:
sprintf(error,"第%d行 缺少end",tempword.line);
break;
case SIGN_THEN:
sprintf(error,"第%d行 缺少then",tempword.line);
break;
case SIGN_DO:
sprintf(error,"第%d行 缺少do",tempword.line);
break;
case SIGN_SEMI:
sprintf(error,"第%d行 缺少分号",tempword.line);
break;
case SIGN_COMMA:
sprintf(error,"第%d行 缺少逗号",tempword.line);
break;
case SIGN_LEFTBRA:
sprintf(error,"第%d行 缺少左括弧",tempword.line);
break;
case SIGN_RIGHTBRA:
sprintf(error,"第%d行 缺少右括弧",tempword.line);
break;
case SIGN_DECIMAL:
sprintf(error,"第%d行 缺少.",tempword.line);
break;
}
return 0;
}
else return 1;
}
int Match(opwords word,int type1,int type2)
{ //若匹配,返回1,否则返回0
if(!(word.type==type1 || word.type==type2))
{
if(type1==SIGN_COMMA && type2==SIGN_RIGHTBRA)
{
sprintf(error,"第%d行 缺少逗号或右括弧",tempword.line);
}
else if(type1==SIGN_RIGHTBRA && type2==SIGN_COMMA)
{
sprintf(error,"第%d行 缺少逗号或右括弧",tempword.line);
}
else if(type1==SIGN_COMMA && type2==SIGN_SEMI)
{
sprintf(error,"第%d行 缺少逗号或分号",tempword.line);
}
else if(type1==SIGN_SEMI && type2==SIGN_COMMA)
{
sprintf(error,"第%d行 缺少逗号或分号",tempword.line);
}
else if(type1==SIGN_END && type2==SIGN_SEMI)
{
sprintf(error,"第%d行 缺少end或分号",tempword.line);
}
else if(type1==SIGN_SEMI && type2==SIGN_END)
{
sprintf(error,"第%d行 缺少end或分号",tempword.line);
}
return 0;
}
else return 1;
}
int GetProg()
{ //Prog的规约 <prog>→program <id>;<block>.
if(FALSE==Match(tempword,SIGN_PROGRAM)) return FALSE;//匹配program关键字
strcpy(tempmhs,tempword.data);
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;//匹配主过程名
fhdis[fhdistop].pre=-1;
fhdis[fhdistop++].go=0;
GenCode("INT",0,3);//为主过程的返回地址、静态链、动态链开辟空间
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_SEMI)) return FALSE;//匹配;
tempword=was.GetOneWord();
if(FALSE==GetBlock()) return FALSE;//分析block
if(FALSE==Match(tempword,SIGN_DECIMAL)) return FALSE;
return TRUE;
}
int GetConst()
{ //Const的规约 <const>→<id>=<integer>
char str[L2MAX];
if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;//匹配标示符
strcpy(str,tempword.data);
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_EQUAL)) return FALSE;//匹配=
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_INTEGER)) return FALSE;//匹配整数
tempaddfh.type=FH_CONST;
tempaddfh.value=atoi(tempword.data);
strcpy(tempaddfh.mgc,tempmhs);
if(FALSE==AddFh(str,tempaddfh)) return FALSE;//往符号表里添加该常量
tempword=was.GetOneWord();
return TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -