[符号表]関数の実装
シンボル表の実現方法は様々ですが、テストに合格すれば大丈夫です.ここでは一つの参照的実現を示した.
まず、符号表に関する構造体です.これはdatastruct.hの中に置いたほうがいいです.
まず、符号表に関する構造体です.これは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<string.h>
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 <= table->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 <= index && index < v->nrDim) {
*ret = v->dims[index];
return SymTab_OK;
} else {
*ret = -1;
return SymTab_ArrDimOutOfRange;
}
}
}
return SymTab_NotDef;
}
MAX_VER_IN_STACKはマクロとして設計できます.const.hの中に置いて、あまり小さくしないでください.Jerryはデータの段がないので、すべての声明の変数はすべて倉庫の中で、MAX_VER_IN_STACK この値は宣言できる変数の数を直接決定(制限)します.