⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbol.cpp

📁 c语言的简化编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* 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 + -