[符号表]函数实现

您所在的位置:网站首页 符号表实现 [符号表]函数实现

[符号表]函数实现

2024-07-09 10:57| 来源: 网络整理| 查看: 265

    符号表的实现方法可以多种多样,只要通过了测试基本上就没啥问题了。在这里给出一个参考实现。

    首先是符号表相关的结构体,这东西最好放到 datastruct.h 中

/* 变量单元,存放符号表中注册的变量信息 */ struct VarCell { char* ident; // 标识符 int addr; // 基地址 AcceptType type; // 类型 int nrDim; // 维数 int* dims; // 每一维偏移 }; /* * varList: 存放变量的链表,表中每一项是一个 VarCell* * * baseAddr: 符号表中首项的地址偏移值 * * used: 符号表中所有变量总大小 */ struct SymbolTable { struct LinkedList varList; int baseAddr; int used; };

    然后是函数实现

#include struct SymbolTable* newSymbolTable(int base) { struct SymbolTable* table = (struct SymbolTable*) allocate(sizeof(struct SymbolTable)); table->baseAddr = base; table->used = 0; initLinkedList(&(table->varList)); return table; } void finalizeSymbolTable(struct SymbolTable* table) { struct Iterator* i; struct VarCell* v; // 释放全部变量单元 for_each (i, &(table->varList)) { v = (struct VarCell*)(i->current(i)); revert(v->ident); if (0 != v->nrDim) { revert(v->dims); } revert(v); } table->varList.finalize(&(table->varList)); revert(table); } SymbolTableError regVar(struct SymbolTable* table, char* ident, AcceptType type, int nrDim, int* dims) { struct Iterator* i; struct VarCell* v; // 查找是否当前符号表中已经有该符号了 for_each (i, &(table->varList)) { v = (struct VarCell*)(i->current(i)); if (0 == strcmp(v->ident, ident)) { i->terminate(i); return SymTab_MultiDef; } } struct VarCell* toAdd = (struct VarCell*)allocate(sizeof(struct VarCell)); toAdd->addr = table->baseAddr + table->used; toAdd->type = type; int varSize = INTEGER == type ? INT_SIZE : REAL_SIZE, used = varSize; // INT_SIZE 和 REAL_SIZE 表示两类变量所占的内存大小,为了方便可以就定义为 sizeof(int) 和 sizeof(double) toAdd->nrDim = nrDim; if (0 != toAdd->nrDim) { toAdd->dims = (int*)allocate(sizeof(int) * nrDim); int j, k,* ptr; // 传入的 dims 是每一维大小,这里根据它计算每一维的偏移 for (j = 0; j < toAdd->nrDim; ++j) { toAdd->dims[j] = varSize; used *= dims[j]; for (k = 0; k < j; ++k) { toAdd->dims[j] *= dims[k]; } } } else { toAdd->dims = NULL; } toAdd->ident = (char*)allocate(sizeof(char) * (1 + strlen(ident))); strcpy(toAdd->ident, ident); // 加入符号表,并计算符号表中现在总大小 table->varList.add(&(table->varList), toAdd); table->used += used; // MAX_VAR_IN_STACK 常量表示栈内最大允许的变量总大小 if (MAX_VAR_IN_STACK used + table->baseAddr) { table->used -= varSize; int j; for (j = 0; j < toAdd->nrDim; ++j) { toAdd->dims[j] = 1; } return SymTab_SizeExceeded; } return SymTab_OK; } SymbolTableError getVarType(struct SymbolTable* table, char* ident, AcceptType* ret) { struct Iterator* i; struct VarCell* v; for_each (i, &(table->varList)) { v = (struct VarCell*)(i->current(i)); if (0 == strcmp(v->ident, ident)) { *ret = v->type; i->terminate(i); return SymTab_OK; } } return SymTab_NotDef; } SymbolTableError getVarAddr(struct SymbolTable* table, char* ident, int* ret) { struct Iterator* i; struct VarCell* v; for_each (i, &(table->varList)) { v = (struct VarCell*)(i->current(i)); if (0 == strcmp(v->ident, ident)) { *ret = v->addr; i->terminate(i); return SymTab_OK; } } return SymTab_NotDef; } SymbolTableError getVarNrDim(struct SymbolTable* table, char* ident, int* ret) { struct Iterator* i; struct VarCell* v; for_each (i, &(table->varList)) { v = (struct VarCell*)(i->current(i)); if (0 == strcmp(v->ident, ident)) { *ret = v->nrDim; i->terminate(i); return SymTab_OK; } } return SymTab_NotDef; } SymbolTableError getVarDimSize(struct SymbolTable* table, char* ident, int* ret, int index) { struct Iterator* i; struct VarCell* v; for_each (i, &(table->varList)) { v = (struct VarCell*)(i->current(i)); if (0 == strcmp(v->ident, ident)) { i->terminate(i); if (0 nrDim) { *ret = v->dims[index]; return SymTab_OK; } else { *ret = -1; return SymTab_ArrDimOutOfRange; } } } return SymTab_NotDef; }

MAX_VAR_IN_STACK 可以设计成一个宏,放在 const.h 中,不要太小就行了。Jerry是没有数据段的,所有声明的变量都在栈内,MAX_VAR_IN_STACK 这个值就直接决定(限制)了可以声明的变量的数量。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3