📄 symbol.cpp
字号:
/* pxdscript symbol.c
*
* History:
*/
#include "stdafx.h"
#include <string.h>
#include "symbol.h"
#include "memory.h"
#include "error.h"
/* The hash-code function */
int Hash(char *str)
{ unsigned int hash = 0;
while (*str) hash = (hash << 1) + *str++;
return hash % HashSize;
}
/* Create and initialize an empty symbol table. */
SymbolTable *initSymbolTable()
{ SymbolTable *t;
int i;
t = NEW(SymbolTable);
for (i=0; i < HashSize; i++) t->table[i] = NULL;
t->parent = NULL;
return t;
}
/* Add a empty child symbol table to the linked list of symbol tables. This
is done when entering a new scope level */
SymbolTable *scopeSymbolTable(SymbolTable *parent)
{ SymbolTable *t;
t = initSymbolTable();
t->parent = parent;
return t;
}
SYMBOL *putSymbol(SymbolTable *t, char *name, SymbolKind kind)
{
int i;
SYMBOL *s;
i = Hash(name);
for (s = t->table[i]; s; s = s->next) {
if (strcmp(s->name,name)==0) return s;
}
s = NEW(SYMBOL);
s->name = name;
s->kind = kind;
s->next = t->table[i];
t->table[i] = s;
return s;
}
SYMBOL *getSymbol(SymbolTable *t, char *name)
{ int i;
SYMBOL *s;
i = Hash(name);
for (s = t->table[i]; s; s = s->next) {
if (strcmp(s->name,name)==0) return s;
}
if (t->parent==NULL) return NULL;
return getSymbol(t->parent,name);
}
int defSymbol(SymbolTable *t, char *name)
{ int i;
SYMBOL *s;
i = Hash(name);
for (s = t->table[i]; s; s = s->next) {
if (strcmp(s->name,name)==0) return 1;
}
return 0;
}
/* the functions that build the symboltable */
/* The main function for the symbol checking phase. */
void symSCRIPTCOLLECTION(SCRIPTCOLLECTION *s)
{
sym1PassSCRIPTCOLLECTION(s);
/* call errorCheck to make sure that parsetree is valid */
errorCheck();
sym2PassSCRIPTCOLLECTION(s);
}
/*** First pass: ***/
void sym1PassSCRIPTCOLLECTION(SCRIPTCOLLECTION *s)
{
s->sym = initSymbolTable();
if (s->toplevels != NULL)
sym1PassTOPLEVEL(s->toplevels, s->sym);
}
void sym1PassTOPLEVEL(TOPLEVEL *t, SymbolTable *sym)
{
switch (t->kind) {
case functionK:
sym1PassFUNCTION(t->val.functionT, sym);
break;
case programK:
sym1PassPROGRAM(t->val.programT, sym);
break;
case simpledeclK: /* chenhongyu, 2004-9-17. */
sym1PassSIMPLEDECL(t->val.decl, sym);
break;
}
if (t->next != NULL)
sym1PassTOPLEVEL(t->next, sym);
}
void sym1PassFUNCTION(FUNCTION *f, SymbolTable *sym)
{
struct SYMBOL *symbol;
if (defSymbol(sym, f->name)) {
reportError(f->lineno, "Duplicate declaration of function '%s'", f->name);
} else {
symbol = putSymbol(sym, f->name, functionSym);
symbol->val.functionS = f;
f->sym = scopeSymbolTable(sym);
if (f->formals != NULL)
sym1PassDECL(f->formals, f->sym);
if (f->stms != NULL)
sym1PassSTM(f->stms, f->sym);
}
}
void sym1PassPROGRAM(PROGRAM *s, SymbolTable *sym)
{
struct SYMBOL *symbol;
if (defSymbol(sym, s->name)) {
reportError(s->lineno, "Duplicate declaration of program '%s'", s->name);
} else {
symbol = putSymbol(sym, s->name, programSym);
symbol->val.programS = s;
s->sym = scopeSymbolTable(sym);
if (s->stms != NULL)
sym1PassSTM(s->stms, s->sym);
}
}
/* chenhongyu, 2004-9-17. */
void sym1PassSIMPLEDECL(DECL *d, SymbolTable *sym)
{
struct SYMBOL *symbol;
if (d->val.simplevarD.initialization != NULL)
sym1PassEXP(d->val.simplevarD.initialization, sym);
if (defSymbol(sym, d->val.simplevarD.name))
reportError(d->lineno, "Duplicate declaration of variable '%s'", d->val.simplevarD.name);
else {
symbol = putSymbol(sym, d->val.simplevarD.name, declSym);
symbol->val.declS = d;
}
}
void sym1PassDECL(DECL *d, SymbolTable *sym)
{
struct SYMBOL *symbol;
switch (d->kind) {
case formalK:
if (defSymbol(sym, d->val.formalD.name))
reportError(d->lineno, "Duplicate declaration of formal '%s'", d->val.formalD.name);
else {
symbol = putSymbol(sym, d->val.formalD.name, declSym);
symbol->val.declS = d;
}
break;
case variableK:
/* Recurse on initialization first, so the variable declared is not used there.
(Otherwise int i = i; would be valid) */
if (d->val.variableD.initialization != NULL)
sym1PassEXP(d->val.variableD.initialization, sym);
sym1PassIDENTIFIER(d->val.variableD.identifiers, d, sym);
d->val.variableD.symbol = getSymbol(sym, d->val.variableD.identifiers->name);
break;
case simplevarK:
/* Recurse on initialization first, so the variable declared is not used there. */
if (d->val.simplevarD.initialization != NULL)
sym1PassEXP(d->val.simplevarD.initialization, sym);
if (defSymbol(sym, d->val.simplevarD.name))
reportError(d->lineno, "Duplicate declaration of variable '%s'", d->val.simplevarD.name);
else {
symbol = putSymbol(sym, d->val.simplevarD.name, declSym);
symbol->val.declS = d;
}
break;
}
if (d->next != NULL)
sym1PassDECL(d->next, sym);
}
void sym1PassFORINIT(FORINIT *f, SymbolTable *sym)
{
switch (f->kind) {
case declforinitK:
sym1PassDECL(f->val.declforinitF, sym);
break;
case expforinitK:
sym1PassEXP(f->val.expforinitF, sym);
break;
}
if (f->next != NULL)
sym1PassFORINIT(f->next, sym);
}
void sym1PassSTM(STM *s, SymbolTable *sym)
{
switch (s->kind) {
case skipK:
break;
case expK:
sym1PassEXP(s->val.expS, sym);
break;
case declstmK:
sym1PassDECL(s->val.declstmS, sym);
break;
case returnK:
if(s->val.returnS.exp != NULL)
sym1PassEXP(s->val.returnS.exp, sym);
break;
case ifK:
sym1PassEXP(s->val.ifS.condition, sym);
sym1PassSTM(s->val.ifS.body, sym);
break;
case ifelseK:
sym1PassEXP(s->val.ifelseS.condition, sym);
sym1PassSTM(s->val.ifelseS.thenpart, sym);
sym1PassSTM(s->val.ifelseS.elsepart, sym);
break;
case whileK:
sym1PassEXP(s->val.whileS.condition, sym);
sym1PassSTM(s->val.whileS.body, sym);
break;
case forK:
sym1PassFORINIT(s->val.forS.inits, sym);
sym1PassEXP(s->val.forS.condition, sym);
sym1PassEXP(s->val.forS.updates, sym);
sym1PassSTM(s->val.forS.body, sym);
break;
case sequenceK:
sym1PassSTM(s->val.sequenceS.first, sym);
sym1PassSTM(s->val.sequenceS.second, sym);
break;
case scopeK:
/* Create an empty symbol table, add to the list and call on the statements inside
the scope with the new, empty symbol table. */
s->val.scopeS.sym = scopeSymbolTable(sym);
sym1PassSTM(s->val.scopeS.stm, s->val.scopeS.sym);
break;
case setintK:
sym1PassEXP(s->val.setintS.modelname, sym);
sym1PassEXP(s->val.setintS.nr, sym);
sym1PassEXP(s->val.setintS.val, sym);
break;
case sleepK:
sym1PassEXP(s->val.sleepS.time, sym);
break;
}
}
void sym1PassIDENTIFIER(IDENTIFIER *i, DECL *decl, SymbolTable *sym)
{
struct SYMBOL *symbol;
if (defSymbol(sym, i->name)) {
reportError(i->lineno, "Duplicate declaration of variable '%s'", i->name);
} else {
symbol = putSymbol(sym, i->name, declSym);
symbol->val.declS = decl;
}
if (i->next != NULL)
sym1PassIDENTIFIER(i->next, decl, sym);
}
void sym1PassEXP(EXP * e, SymbolTable *sym)
{
if (e == NULL)
return;
switch (e->kind) {
case intconstK:
break;
case boolconstK:
break;
case stringconstK:
break;
case uminusK:
sym1PassEXP(e->val.uminusE, sym);
break;
case notK:
sym1PassEXP(e->val.notE.exp, sym);
break;
case lvalueK:
sym1PassLVALUE(e->val.lvalueE, sym);
break;
case assignmentK:
sym1PassLVALUE(e->val.assignmentE.left, sym);
sym1PassEXP(e->val.assignmentE.right, sym);
break;
case equalsK:
sym1PassEXP(e->val.equalsE.left, sym);
sym1PassEXP(e->val.equalsE.right, sym);
break;
case nequalsK:
sym1PassEXP(e->val.nequalsE.left, sym);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -