Tiny语言编译器之符号表

来源:互联网 发布:linux压缩文件命令 zip 编辑:程序博客网 时间:2024/05/17 06:14

 Tiny语言编译器的符号表还是很简单的,主要的是写了一个简单的哈希表,共有211个桶,采用拉链法,用另外一个链表记录了一个符号所出现的所有行号,源代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "symtab.h"
#define SHIFT 4
#define SIZE 211
//哈希函数
static int hash(charkey)
{
    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(charname, 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 l->lines;
        while(t->next!=NULL) t=t->next;
        t->next (LineList)malloc(sizeof(struct LineListRec));
        t->next->lineno lineno;
        t->next->next NULL;
    }
}


//在符号表中查找某个符号的内存地址
int st_lookup(charname)
{
    int h=hash(name);
    BucketList l= hashTable[h];
    while((l!=NULL) && (strcmp(name, l->name)!=0))
        l=l->next;
    if(l!=NULL) return l->memloc;
    return -1;
}

//打印符号表
void printSymTab(FILE* listing)
{
    int i;
    fprintf(listing, "Variable Name Location Line Number\n");
    fprintf(listing, "----------------------------------\n");
    for(i=0; i<SIZE; ++i)
    {
        if(hashTable[i]!=NULL)
        {
            BucketList hashTable[i];
            while(l!=NULL)
            {
                LineList l->lines;
                fprintf(listing, "%s-14s"l->name);
                fprintf(listing, "%-8d"l->memloc);
                while(t!=NULL)
                {
                    fprintf(listing, "%4d"t->lineno);
                    t=t->next;
                }
                fprintf(listing, "\n");
                l->next;
            }
        }
    }
}

0 0