⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expressanalysis.h

📁 一个pascal子集编译器。输入pascal原程序
💻 H
📖 第 1 页 / 共 2 页
字号:
#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 + -