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

📄 symbol.h

📁 扩展后的mini-pl0语法编译器
💻 H
字号:
#ifndef SYMBOL_H
#define SYMBOL_H

//枚举常量定义,用来表明当前数据的类型
enum IdType{CProce,	//过程名
			VInt,	//整型变量
			VBool,	//bool变量
			VArray,	//数组类型变量
			VRecord,//记录类型变量
			DArray,	//定义的数组新类型
			DRecord,//定义的记录新类型
			CInt,	//整型常量
			CBool	//bool常量
		};

//名称:符号节点类
//作用:存储符号表中的每个节点信息及对节点的赋值操作
class symbol
{
public:
	symbol();			//构造函数
	virtual ~symbol();	//析构函数

public:
	symbol *m_next;		//指向下一个类节点,在符号表中用到

	char *m_name;		//存储变量名的指针,每次创建的时候通过new的方式,在析构函数中释放

	int m_value;		//用于存储CInt和CBool(常量)的值或者存储变量的当前层的偏移量

	IdType m_type;		//存储当前节点的类型

	int m_length;		//本节点中数据的大小,如果是定义的新类型名节点,则同样存储当前新类型的大小

	bool m_checkvar;	//标注是否是函数的参数列表,true则是参数,false则不是

	bool m_checkparam;	//函数参数是否是值参(true为“var型”,不复制,长度恒为1;
						//false则要进行复制,长度为其本身数据类型的长度)

	symbol *m_typeInfo[30];	//1、如果当前是过程名节点,则存储所有参数节点的指针,便于访问
							//2、如果当前是record新类型定义的节点,则存储所有域名的指针,域名不再符号表中 
							//3、如果当前是array新类型定义的节点,则存储该数组类型的节点的指针,如果该数组为普通类型,
							//	 则为NULL,否则在m_typeInfo[0]中存储该类型的节点的指针
							//4、如果是变量节点,如果是新类型的变量,则用m_typeInfo[0]存储新类型的节点的指针,否则为空

	IdType arrayType;		//array新类型中的内容类型
	int arraystart,arrayend;//数组的起点和终点

public:
	//过程名,psymbol为参数节点信息数组
	symbol* create(const char* name,symbol** psymbol);
	//int和bool型变量的插入
	symbol* create(const char* name, IdType type);
	//array新类型名(定义)的插入,type为数组中存放的内容的类型,
	//如果不是int或bool,则存放新类型,类型节点为psymbol
	symbol* create(const char* name, const int start, const int end ,IdType type, symbol* psymbol);
	//record新类型名的插入,length为此类型的长度
	symbol* create(const char* name, int length);
	//新类型的变量的插入,插入的变量的类型为type(VArray或VRecord),
	//psymbol中存放新类型名的信息(psymbol为DArray或DRecord的定义)
	symbol* create(const char* name, IdType type,  symbol* psymbol);
	//初始化过程参数的节点
	symbol* create(const char* name, IdType type, int length, symbol* psymbol, bool checkparam);
	//返回m_value的值
	int GetValue();
	//设置m_value的值
	void SetSimpleValue(int value);
};

#define BUCKET_SIZE 211				// prime number

//名称:符号表的类
//作用:一张符号表存储在一个类对象中,一个过程一张符号表,即一个类对象。
//		中间有符号节点的插入操作,查找符号的操作,子符号表的插入等操作。
//		有访问临近符号表及父子符号表的数据结构
class symboltable 
{
public:
	int m_lever;				//当前过程所处的层次

	int codebegin;				//过程定义第一行,用于过程调用时的回填
	
	symbol* m_procesymbol;		//过程名节点,是独立节点,存储过程的基本信息
	
	symbol* m_tempsymbol;		//调用search函数后,临时存储查找到的节点的指针
	
	symboltable* m_childtable;	//指向第一个子节点
	symboltable* m_parenttable;	//指向父节点
	symboltable* m_siblingtable;//指向兄弟节点

	symbol* symbolList[30];		//保留数据结构,现在还没用到
	int m_listindex;			//相对应上面指针数组的下标

public:
	//构造函数,创建过程,lever为当前过程所处的层次,parent指向父亲节点,sibling指向兄弟节点
	symboltable(int lever, symboltable* parent ,symboltable* sibling);
	//析构函数,释放有些动态内存,回收资源
	virtual ~symboltable();
	
protected:
	//符号表数组,符号表用散列的形式存储
	symbol* m_bucket[BUCKET_SIZE];	

protected:
	//散列的形式查找要插入的位置
	int hash(const char* name) const;

public:
	//插入过程名或插入record的新类型名
	symbol* install(const char* name, symbol** psymbol,IdType type);
	//插入普通变量int和bool型
	symbol* install(const char* name,IdType type);
	//插入array的新类型名
	symbol* install(const char* name, const int start, const int end,IdType type, symbol* psymbol);
	//插入的变量的类型为新类型
	symbol* install(const char* name,IdType type, symbol* q);	
	//插入过程中的参数节点
	symbol* install(const char* name,IdType type, int length, symbol* psymbol, bool checkparam);
	
	//查找变量,返回找到的变量名所在的符号表的指针,没找到则返回空
	symboltable* search(char* name);
	
	//创建并插入儿子(符号表),name为新符号表的名字
	symboltable* insertchild(char* name)
	{
		m_childtable = new symboltable(m_lever+1,this,this->m_childtable);
		return m_childtable;
	}
	//删除当前符号表的所有子节点本身
	void deletechild(symboltable* p)
	{
		symboltable* temp;
		while(p)
		{
			temp = p;
			p = p->m_siblingtable;
			deletechild(temp->m_childtable);
			delete temp;
		}
	}
};

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -