参考C++ Program to implement Symbol Table
写此代码是为了方便语法分析器的完成,代码与参考很接近,特点是全部使用c完成,对语法分析器兼容性强。
以下是代码:
- 头文件:
$ cat SymbolTable.h
#define MAX 100
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;
}
网友评论