📄 symbol.c
字号:
/* * JOOS is Copyright (C) 1997 Laurie Hendren & Michael I. Schwartzbach * * Reproduction of all or part of this software is permitted for * educational or research use on condition that this copyright notice is * included in any copy. This software comes with no warranty of any * kind. In no event will the authors be liable for any damages resulting from * use of this software. * * email: hendren@cs.mcgill.ca, mis@brics.dk */#include <stdio.h>#include <string.h>#include "memory.h"#include "error.h"#include "symbol.h"extern char *currentfile;int Hash(char *str){ unsigned int hash = 0; while (*str) hash = (hash << 1) + *str++; return hash % HashSize;}SymbolTable *initSymbolTable(){ SymbolTable *t; int i; t = NEW(SymbolTable); for (i=0; i < HashSize; i++) t->table[i] = NULL; t->next = NULL; return t;}SymbolTable *scopeSymbolTable(SymbolTable *s){ SymbolTable *t; t = initSymbolTable(); t->next = s; return t;}SYMBOL *putSymbol(SymbolTable *t, char *name, SymbolKind kind){ int i = Hash(name); SYMBOL *s; 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 = Hash(name); SYMBOL *s; for (s = t->table[i]; s; s = s->next) { if (strcmp(s->name,name)==0) return s; } if (t->next==NULL) return NULL; return getSymbol(t->next,name);} int defSymbol(SymbolTable *t, char *name){ int i = Hash(name); SYMBOL *s; for (s = t->table[i]; s; s = s->next) { if (strcmp(s->name,name)==0) return 1; } return 0;}int subClass(CLASS *sub, CLASS *super){ if (sub==NULL) return 0; if (strcmp(sub->name,super->name)==0) return 1; if (sub->parent==NULL) return 0; return subClass(sub->parent,super);}SYMBOL *lookupHierarchy(char *name, CLASS *start){ SYMBOL *s; if (start==NULL) return NULL; s = getSymbol(start->localsym,name); if (s!=NULL) return s; if (start->parent==NULL) return NULL; return lookupHierarchy(name,start->parent);}CLASS *lookupHierarchyClass(char *name, CLASS *start){ SYMBOL *s; if (start==NULL) return NULL; s = getSymbol(start->localsym,name); if (s!=NULL) return start; if (start->parent==NULL) return NULL; return lookupHierarchyClass(name,start->parent);}void symPROGRAM(PROGRAM *p){ classlib = initSymbolTable(); symInterfacePROGRAM(p,classlib); symInterfaceTypesPROGRAM(p,classlib); symImplementationPROGRAM(p);}void symInterfacePROGRAM(PROGRAM *p, SymbolTable *sym){ if (p!=NULL) { symInterfacePROGRAM(p->next,sym); currentfile = p->name; symInterfaceCLASSFILE(p->classfile,sym); }}void symInterfaceCLASSFILE(CLASSFILE *c, SymbolTable *sym){ if (c!=NULL) { symInterfaceCLASSFILE(c->next,sym); symInterfaceCLASS(c->class,sym); }}void symInterfaceCLASS(CLASS *c, SymbolTable *sym){ SYMBOL *s; if (defSymbol(sym,c->name)) { reportStrError("class name %s already defined",c->name,c->lineno); } else { s = putSymbol(sym,c->name,classSym); s->val.classS = c; c->localsym = initSymbolTable(); symInterfaceFIELD(c->fields,c->localsym); symInterfaceCONSTRUCTOR(c->constructors,c->name,c->localsym); symInterfaceMETHOD(c->methods,c->localsym); }}void symInterfaceFIELD(FIELD *f, SymbolTable *sym){ SYMBOL *s; if (f!=NULL) { symInterfaceFIELD(f->next,sym); s = putSymbol(sym,f->name,fieldSym); s->val.fieldS = f; }}void symInterfaceCONSTRUCTOR(CONSTRUCTOR *c, char *classname, SymbolTable *sym){ if (c!=NULL) { symInterfaceCONSTRUCTOR(c->next,classname,sym); if (!strcmp(classname,c->name)==0) { reportStrError("constructor name %s different from class name", c->name,c->lineno); } }}void symInterfaceMETHOD(METHOD *m, SymbolTable *sym){ SYMBOL *s; if (m!=NULL) { symInterfaceMETHOD(m->next,sym); if (defSymbol(sym,m->name)) { reportStrError("Redefinition of an identifier: method name %s already defined",m->name,m->lineno); } else { s = putSymbol(sym,m->name,methodSym); s->val.methodS = m; } } }void symInterfaceTypesPROGRAM(PROGRAM *p, SymbolTable *sym){ if (p!=NULL) { symInterfaceTypesPROGRAM(p->next,sym); currentfile = p->name; symInterfaceTypesCLASSFILE(p->classfile,sym); }}void symInterfaceTypesCLASSFILE(CLASSFILE *c, SymbolTable *sym){ if (c!=NULL) { symInterfaceTypesCLASSFILE(c->next,sym); symInterfaceTypesCLASS(c->class,sym); }}void symInterfaceTypesCLASS(CLASS *c, SymbolTable *sym){ SYMBOL *s; if (c!=NULL) { if (c->parentname!=NULL) { s = getSymbol(sym,c->parentname); if (s==NULL) { reportStrError("no such parent class %s",c->parentname,c->lineno); c->parent = NULL; } else { c->parent = s->val.classS; } } else { c->parent = NULL; } symInterfaceTypesCONSTRUCTOR(c->constructors,sym); symInterfaceTypesMETHOD(c->methods,sym); }}void symInterfaceTypesCONSTRUCTOR(CONSTRUCTOR *c, SymbolTable *sym){ if (c!=NULL) { symInterfaceTypesCONSTRUCTOR(c->next,sym); symInterfaceTypesFORMAL(c->formals,sym); }}void symInterfaceTypesMETHOD(METHOD *m, SymbolTable *sym){ if (m!=NULL) { symInterfaceTypesMETHOD(m->next,sym); symTYPE(m->returntype,sym); symInterfaceTypesFORMAL(m->formals,sym); }}void symTYPE(TYPE *t, SymbolTable *sym){ SYMBOL *s; if (t!=NULL) { switch (t->kind) { case intK: case boolK: case charK: case voidK: case polynullK: break; case refK: s = getSymbol(sym,t->name); if (s==NULL) { reportStrError("type identifier %s not declared", t->name, t->lineno); } else { if (s->kind!=classSym) { reportStrError("type %s must be a class",t->name,t->lineno); } else t->class = s->val.classS; } } }}void symInterfaceTypesFORMAL(FORMAL *f, SymbolTable *sym){ if (f!=NULL) { symInterfaceTypesFORMAL(f->next,sym); symTYPE(f->type,sym); }}void symImplementationPROGRAM(PROGRAM *p){ if (p!=NULL) { symImplementationPROGRAM(p->next); currentfile = p->name; symImplementationCLASSFILE(p->classfile); }}void symImplementationCLASSFILE(CLASSFILE *c){ if (c!=NULL) { symImplementationCLASSFILE(c->next); symImplementationCLASS(c->class); }}void symImplementationCLASS(CLASS *c){ SymbolTable *sym; sym = scopeSymbolTable(classlib); symImplementationFIELD(c->fields,sym); symImplementationCONSTRUCTOR(c->constructors,c,sym); symImplementationMETHOD(c->methods,c,sym);}void symImplementationFIELD(FIELD *f, SymbolTable *sym)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -