📄 symbol.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 + -