Tiny語言編譯器的符號表還是很簡單的,主要的是寫了一個簡單的哈希表,共有211個桶,採用拉鍊法,用另外一個鏈表記錄了一個符號所出現的所有行號,源代碼如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "symtab.h"
#define SHIFT 4
#define SIZE 211
//哈希函數
static int hash(char* key)
{
int temp=0;
int i=0;
while(key[i]!='\0')
{
temp = ((temp<<SHIFT)+key[i])%SIZE;
i++;
}
return temp;
}
//記錄符號行號的鏈表
typedef struct LineListRec
{
int lineno;
struct LineListRec* next;
}*LineList;
//哈希表的桶定義
typedef struct BucketListRect
{
char *name;
LineList lines;
int memloc;
struct BucketListRect *next;
}*BucketList;
//哈希表
static BucketList hashTable[SIZE];
void st_insert(char* name, int lineno, int loc)
{
int h=hash(name);
BucketList l= hashTable[h];
while((l!=NULL) && (strcmp(name, l->name)!=0))
l=l->next;
//如果從未出現過該符號
if(l==NULL)
{
l=(BucketList)malloc(sizeof(struct BucketListRect));
l->name = name;
l->memloc = loc;
l->lines=(LineList)malloc(sizeof(struct LineListRec));
l->lines->lineno = lineno;
l->lines->next=NULL;
l->next = hashTable[h];
hashTable[h]=l;
}
else //已經出現過該符號了,找到相應的桶,只需要再添加一個行號,忽略name和loc
{
LineList t = l->lines;
while(t->next!=NULL) t=t->next;