some changes to cminus for symtab
This commit is contained in:
82
src/symtab.c
82
src/symtab.c
@@ -8,74 +8,57 @@
|
|||||||
/* Kenneth C. Louden */
|
/* Kenneth C. Louden */
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
|
|
||||||
|
#include "symtab.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "symtab.h"
|
|
||||||
|
|
||||||
/* SIZE is the size of the hash table */
|
|
||||||
#define SIZE 211
|
|
||||||
|
|
||||||
/* SHIFT is the power of two used as multiplier
|
/* SHIFT is the power of two used as multiplier
|
||||||
in hash function */
|
in hash function */
|
||||||
#define SHIFT 4
|
#define SHIFT 4
|
||||||
|
|
||||||
/* the hash function */
|
/* the hash function */
|
||||||
static int hash ( char * key )
|
static int hash(char *key) {
|
||||||
{ int temp = 0;
|
int temp = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (key[i] != '\0')
|
while (key[i] != '\0') {
|
||||||
{ temp = ((temp << SHIFT) + key[i]) % SIZE;
|
temp = ((temp << SHIFT) + key[i]) % SYMTAB_SIZE;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the list of line numbers of the source
|
Scope curr_scope(void) {
|
||||||
* code in which a variable is referenced
|
if (top_stack == -1) {
|
||||||
*/
|
return NULL;
|
||||||
typedef struct LineListRec
|
} else {
|
||||||
{ int lineno;
|
return scope_stack[top_stack];
|
||||||
struct LineListRec * next;
|
}
|
||||||
} * LineList;
|
}
|
||||||
|
|
||||||
/* The record in the bucket lists for
|
|
||||||
* each variable, including name,
|
|
||||||
* assigned memory location, and
|
|
||||||
* the list of line numbers in which
|
|
||||||
* it appears in the source code
|
|
||||||
*/
|
|
||||||
typedef struct BucketListRec
|
|
||||||
{ char * name;
|
|
||||||
LineList lines;
|
|
||||||
int memloc ; /* memory location for variable */
|
|
||||||
struct BucketListRec * next;
|
|
||||||
} * BucketList;
|
|
||||||
|
|
||||||
/* the hash table */
|
|
||||||
static BucketList hashTable[SIZE];
|
|
||||||
|
|
||||||
/* Procedure st_insert inserts line numbers and
|
/* Procedure st_insert inserts line numbers and
|
||||||
* memory locations into the symbol table
|
* memory locations into the symbol table
|
||||||
* loc = memory location is inserted only the
|
* loc = memory location is inserted only the
|
||||||
* first time, otherwise ignored
|
* first time, otherwise ignored
|
||||||
*/
|
*/
|
||||||
void st_insert( char * name, int lineno, int loc )
|
void st_insert(char *name, int lineno, int loc) {
|
||||||
{ int h = hash(name);
|
int h = hash(name);
|
||||||
BucketList l = hashTable[h];
|
BucketList l = hashTable[h];
|
||||||
while ((l != NULL) && (strcmp(name, l->name) != 0))
|
while ((l != NULL) && (strcmp(name, l->name) != 0))
|
||||||
l = l->next;
|
l = l->next;
|
||||||
if (l == NULL) /* variable not yet in table */
|
if (l == NULL) /* variable not yet in table */
|
||||||
{ l = (BucketList) malloc(sizeof(struct BucketListRec));
|
{
|
||||||
|
l = (BucketList) malloc(sizeof(struct BucketListRec));
|
||||||
l->name = name;
|
l->name = name;
|
||||||
l->lines = (LineList) malloc(sizeof(struct LineListRec));
|
l->lines = (LineList) malloc(sizeof(struct LineListRec));
|
||||||
l->lines->lineno = lineno;
|
l->lines->lineno = lineno;
|
||||||
l->memloc = loc;
|
l->memloc = loc;
|
||||||
l->lines->next = NULL;
|
l->lines->next = NULL;
|
||||||
l->next = hashTable[h];
|
l->next = hashTable[h];
|
||||||
hashTable[h] = l; }
|
hashTable[h] = l;
|
||||||
else /* found in table, so just add line number */
|
} else /* found in table, so just add line number */
|
||||||
{ LineList t = l->lines;
|
{
|
||||||
|
LineList t = l->lines;
|
||||||
while (t->next != NULL) t = t->next;
|
while (t->next != NULL) t = t->next;
|
||||||
t->next = (LineList) malloc(sizeof(struct LineListRec));
|
t->next = (LineList) malloc(sizeof(struct LineListRec));
|
||||||
t->next->lineno = lineno;
|
t->next->lineno = lineno;
|
||||||
@@ -86,32 +69,33 @@ void st_insert( char * name, int lineno, int loc )
|
|||||||
/* Function st_lookup returns the memory
|
/* Function st_lookup returns the memory
|
||||||
* location of a variable or -1 if not found
|
* location of a variable or -1 if not found
|
||||||
*/
|
*/
|
||||||
int st_lookup ( char * name )
|
int st_lookup(char *name) {
|
||||||
{ int h = hash(name);
|
int h = hash(name);
|
||||||
BucketList l = hashTable[h];
|
BucketList l = hashTable[h];
|
||||||
while ((l != NULL) && (strcmp(name, l->name) != 0))
|
while ((l != NULL) && (strcmp(name, l->name) != 0))
|
||||||
l = l->next;
|
l = l->next;
|
||||||
if (l == NULL) return -1;
|
if (l == NULL) return -1;
|
||||||
else return l->memloc;
|
else
|
||||||
|
return l->memloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Procedure printSymTab prints a formatted
|
/* Procedure printSymTab prints a formatted
|
||||||
* listing of the symbol table contents
|
* listing of the symbol table contents
|
||||||
* to the listing file
|
* to the listing file
|
||||||
*/
|
*/
|
||||||
void printSymTab(FILE * listing)
|
void printSymTab(FILE *listing) {
|
||||||
{ int i;
|
int i;
|
||||||
fprintf(listing, "Variable Name Location Line Numbers\n");
|
fprintf(listing, "Variable Name Location Line Numbers\n");
|
||||||
fprintf(listing, "------------- -------- ------------\n");
|
fprintf(listing, "------------- -------- ------------\n");
|
||||||
for (i=0;i<SIZE;++i)
|
for (i = 0; i < SYMTAB_SIZE; ++i) {
|
||||||
{ if (hashTable[i] != NULL)
|
if (hashTable[i] != NULL) {
|
||||||
{ BucketList l = hashTable[i];
|
BucketList l = hashTable[i];
|
||||||
while (l != NULL)
|
while (l != NULL) {
|
||||||
{ LineList t = l->lines;
|
LineList t = l->lines;
|
||||||
fprintf(listing, "%-14s ", l->name);
|
fprintf(listing, "%-14s ", l->name);
|
||||||
fprintf(listing, "%-8d ", l->memloc);
|
fprintf(listing, "%-8d ", l->memloc);
|
||||||
while (t != NULL)
|
while (t != NULL) {
|
||||||
{ fprintf(listing,"%4d ",t->lineno);
|
fprintf(listing, "%4d ", t->lineno);
|
||||||
t = t->next;
|
t = t->next;
|
||||||
}
|
}
|
||||||
fprintf(listing, "\n");
|
fprintf(listing, "\n");
|
||||||
|
|||||||
120
src/symtab.h
120
src/symtab.h
@@ -1,9 +1,7 @@
|
|||||||
/****************************************************/
|
/****************************************************/
|
||||||
/* File: symtab.h */
|
/* File: symtab.h */
|
||||||
/* Symbol table interface for the TINY compiler */
|
/* Symbol table interface for the CMINUS COMPILER */
|
||||||
/* (allows only one symbol table) */
|
/* Modified by Yenru0 */
|
||||||
/* Compiler Construction: Principles and Practice */
|
|
||||||
/* Kenneth C. Louden */
|
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
|
|
||||||
#ifndef _SYMTAB_H_
|
#ifndef _SYMTAB_H_
|
||||||
@@ -11,19 +9,113 @@
|
|||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
/* Procedure st_insert inserts line numbers and
|
/* SYMTAB_SIZE is the size of the hash table */
|
||||||
* memory locations into the symbol table
|
#define SYMTAB_SIZE 211
|
||||||
* loc = memory location is inserted only the
|
|
||||||
* first time, otherwise ignored
|
|
||||||
*/
|
|
||||||
void st_insert( char * name, int lineno, int loc );
|
|
||||||
|
|
||||||
/* Function st_lookup returns the memory
|
/* the list of line numbers of the source
|
||||||
* location of a variable or -1 if not found
|
* code in which a variable is referenced
|
||||||
*/
|
*/
|
||||||
int st_lookup ( char * name );
|
typedef struct LineListRec {
|
||||||
|
int lineno;
|
||||||
|
struct LineListRec *next;
|
||||||
|
} *LineList;
|
||||||
|
|
||||||
/* Procedure printSymTab prints a formatted
|
/* The record in the bucket lists for
|
||||||
|
* each variable, including name,
|
||||||
|
* assigned memory location, and
|
||||||
|
* the list of line numbers in which
|
||||||
|
* it appears in the source code
|
||||||
|
*/
|
||||||
|
typedef struct BucketListRec {
|
||||||
|
char *name;
|
||||||
|
TreeNode *treeNode;
|
||||||
|
LineList lines;
|
||||||
|
ExpType type;
|
||||||
|
int memloc; /* memory location for variable */
|
||||||
|
struct BucketListRec *next;
|
||||||
|
} *BucketList;
|
||||||
|
|
||||||
|
typedef struct ScopeListRec {
|
||||||
|
char *name;
|
||||||
|
int depth;
|
||||||
|
struct ScopeListRec *parent;
|
||||||
|
BucketList hashTable[SYMTAB_SIZE];
|
||||||
|
} *Scope;
|
||||||
|
|
||||||
|
Scope scope_global;
|
||||||
|
|
||||||
|
static Scope scope_list[SYMTAB_SIZE];
|
||||||
|
static int size_list = 0;
|
||||||
|
|
||||||
|
static Scope scope_stack[SYMTAB_SIZE];
|
||||||
|
static int top_stack = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new scope with given name
|
||||||
|
* @param scope_name: name of the scope
|
||||||
|
* @return the created scope
|
||||||
|
*/
|
||||||
|
Scope scope_new(char *scope_name);
|
||||||
|
/**
|
||||||
|
* pop the current scope from the scope stack
|
||||||
|
*/
|
||||||
|
void pop_scope(void);
|
||||||
|
/**
|
||||||
|
* push a scope into the scope stack
|
||||||
|
* @param scope: the scope to be pushed
|
||||||
|
*/
|
||||||
|
void push_scope(Scope scope);
|
||||||
|
/**
|
||||||
|
* insert a scope into the scope list
|
||||||
|
*/
|
||||||
|
void insert_scope_to_list(Scope scope);
|
||||||
|
/**
|
||||||
|
* get the top of the scope stack
|
||||||
|
* @return the current scope or NULL if the stack is empty
|
||||||
|
*/
|
||||||
|
Scope curr_scope(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert a variable into the symbol table
|
||||||
|
* or update a variable if it already exists
|
||||||
|
* @param scope_name name of the scope
|
||||||
|
* @param name name of the variable
|
||||||
|
* @param type type of the variable
|
||||||
|
* @param treeNode syntax tree node
|
||||||
|
* @param lineno line number of the variable
|
||||||
|
* @param loc memory location of the variable
|
||||||
|
* @return 0 if success, -1 if failure
|
||||||
|
*/
|
||||||
|
int st_try_insert(
|
||||||
|
char *scope_name,
|
||||||
|
char *name,
|
||||||
|
ExpType type,
|
||||||
|
TreeNode *treeNode,
|
||||||
|
int loc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lookup a variable in the current scope
|
||||||
|
* @param name name of the variable to lookup
|
||||||
|
* @return the bucket list entry of the variable or NULL if not found
|
||||||
|
*/
|
||||||
|
BucketList st_lookup_current(char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lookup a variable from the given scope
|
||||||
|
* @param name name of the variable to lookup
|
||||||
|
* @return the bucket list entry of the variable or NULL if not found
|
||||||
|
*/
|
||||||
|
BucketList st_lookup(char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find a scope from the scope list
|
||||||
|
* @param scope_name name of the scope to find
|
||||||
|
* @return the scope or NULL if not found
|
||||||
|
*/
|
||||||
|
Scope find_scope(char *scope_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procedure printSymTab prints a formatted
|
||||||
* listing of the symbol table contents
|
* listing of the symbol table contents
|
||||||
* to the listing file
|
* to the listing file
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user