用c with class寫一個符號表

參考C++ Program to implement Symbol Table
寫此代碼是爲了方便語法分析器的完成,代碼與參考很接近,特點是全部使用c完成,對語法分析器兼容性強。

以下是代碼:

  • 頭文件:
$ cat SymbolTable.h
#define MAX 1000
  
typedef struct node { 
  
    char *identifier, *scope, *type; 
    int lineNo; 
    struct Node *next; 
    void (*print)(struct Node *p);
}Node;

Node *newNode();
Node *newNodeWith(char *key, char *value, char *type, int lin);

static void print(Node *p);

typedef struct symbolTable
{
    struct Node *head[MAX]; 
    int (*hashf)(char* id);
    int (*insert)(struct symbolTable* s,char* id,char* scope,char* type,int lineno);
    char* (*find)(struct symbolTable* s,char* id);
    int (*deleteRecord)(struct symbolTable* s,char* id);
    int (*modify)(struct symbolTable* s,char* id,char* scope,char* type,int lineno);
}SymbolTable;

SymbolTable *newSymbolTable();

static int hashf(char* id);
static int insert(SymbolTable* s,char* id,char* scope,char* type,int lineno);
static char* find(SymbolTable* s,char* id);
static int deleteRecord(SymbolTable* s,char* id);
static int modify(SymbolTable* s,char* id,char* scope,char* type,int lineno);
  • 主文件
$ cat SymbolTable.c 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"SymbolTable.h"
Node *newNode()
{
        Node *p = (Node *)malloc(sizeof(*p));
        if(p==NULL){
                return NULL;
        }
        p->next = NULL; 
        p->print = &print;
        
        return p;
}
Node *newNodeWith(char* key, char* value, char* type, int lineNo)
{
        Node *p = (Node *)malloc(sizeof(*p));
        if(p==NULL){
                return NULL;
        }
        
        p->identifier = key; 
        p->scope = value; 
        p->type = type; 
        p->lineNo = lineNo; 
        p->next = NULL; 
        p->print = &print;
        
        return p;
}
static void print(Node *p) 
{ 
        printf("Identifier's Name:%s\n",p->identifier);
        printf("Type:%s\n",p->type); 
        printf("Scope:%s\n",p->scope);
        printf("Line Number:%d\n",p->lineNo);
} 


SymbolTable *newSymbolTable()
{
        SymbolTable *p = (SymbolTable *)malloc(sizeof(*p));
        for (int i=0; i<MAX; i++) 
            p->head[i] = NULL;
    
        p->hashf = &hashf;
        p->insert = &insert;
        p->find = &find;
        p->deleteRecord = &deleteRecord;
        p->modify = &modify;

        return p;
}
static int hashf(char* id)
{
        int asciiSum = 0; 
  
        for (int i=0; i<strlen(id); i++) { 
            asciiSum = asciiSum + id[i]; 
        } 
  
        return (asciiSum % 100); 
}
static int insert(SymbolTable* s,char* id,char* scope,char* type,int lineno)
{
        int index = s->hashf(id); 
        Node* p = newNodeWith(id, scope, type, lineno); 
        if (s->head[index] == NULL) { 
            s->head[index] = p; 
            printf("id:%s inserted\n",id);
            return 1;
        }else{
            Node* start = s->head[index]; 
            while (start->next != NULL) 
                start = start->next; 
  
            start->next = p; 
            printf("id:%s inserted\n",id);
            return 1; 
        } 
  
        return 0;
}
static char* find(SymbolTable* s,char* id)
{
        int index = s->hashf(id); 
        Node* start = s->head[index]; 
  
        if (start == NULL) 
            return "-1"; 
  
        while (start != NULL) { 
  
            if (start->identifier == id) { 
                start->print(start); 
                return start->scope; 
            } 
  
            start = start->next; 
        } 
  
        return "-1";
}
static int deleteRecord(SymbolTable* s,char* id)
{
        int index = s->hashf(id); 
        Node* tmp = s->head[index]; 
        Node* par = s->head[index]; 
  
        if (tmp == NULL) { 
            return 0; 
        } 

        if (tmp->identifier == id && tmp->next == NULL) { 
            tmp->next = NULL; 
            free(tmp); 
            return 1; 
        } 
  
        while (tmp->identifier != id && tmp->next != NULL) { 
            par = tmp; 
            tmp = tmp->next; 
        } 
        if (tmp->identifier == id && tmp->next != NULL) { 
            par->next = tmp->next; 
            tmp->next = NULL; 
            free(tmp); 
            return 1; 
        }else { 
            par->next = NULL; 
            tmp->next = NULL; 
            free(tmp); 
            return 1; 
        } 
        return 0; 
}
static int modify(SymbolTable* s,char* id,char* scope,char* type,int lineno)
{
        int index = s->hashf(id); 
        Node* start = s->head[index]; 
  
        if (start == NULL) 
            return "-1"; 
  
        while (start != NULL) { 
            if (start->identifier == id) { 
                start->scope = scope; 
                start->type = type; 
                start->lineNo = lineno; 
                return 1; 
            } 
            start = start->next; 
        } 
  
        return 0;
}

int main()
{
        printf("Test Node:\n");
    
        Node *nd = newNodeWith("num","int","all",2);
        nd->print(nd);
    
        printf("Test SymbolTable:\n");
        
        SymbolTable *st = newSymbolTable(); 
        char* check; 
        printf("**** SYMBOL_TABLE ****\n"); 
  
        // insert 'if' 
        if (st->insert(st,"if", "local", "keyword", 4)==1)
            printf(" -successfully"); 
        else
            printf("\nFailed to insert.\n"); 
  
        // insert 'number' 
        if (st->insert(st,"number", "global", "variable", 2)) 
            printf(" -successfully\n\n"); 
        else
            printf("\nFailed to insert\n"); 
  
        // find 'if' 
        check = st->find(st,"if"); 
        if (check != "-1") 
            printf("Identifier Is present\n"); 
        else
            printf("\nIdentifier Not Present\n"); 
  
        // delete 'if' 
        if (st->deleteRecord(st,"if")) 
            printf("if Identifier is deleted\n"); 
        else
            printf("\nFailed to delete\n"); 
  
        // modify 'number' 
        if (st->modify(st,"number", "global", "variable", 3)) 
            printf("\nNumber Identifier updated\n"); 
  
        // find and print 'number' 
        check = st->find(st,"number"); 
        if (check != "-1") 
            printf("Identifier Is present\n"); 
        else
            printf("\nIdentifier Not Present"); 
        return 0;
        
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章