some changes to cminus for symtab

This commit is contained in:
2025-12-01 03:35:09 +09:00
parent a9855535cb
commit 1204abb4f9
3 changed files with 173 additions and 97 deletions

View File

@@ -71,7 +71,7 @@ int main(int argc, char *argv[]) {
printTree(syntaxTree); printTree(syntaxTree);
} }
#if !NO_ANALYZE #if !NO_ANALYZE
if (!Error) { if (!Error) {
if (TraceAnalyze) fprintf(listing, "\nBuilding Symbol Table...\n"); if (TraceAnalyze) fprintf(listing, "\nBuilding Symbol Table...\n");
buildSymtab(syntaxTree); buildSymtab(syntaxTree);
if (TraceAnalyze) fprintf(listing, "\nChecking Types...\n"); if (TraceAnalyze) fprintf(listing, "\nChecking Types...\n");

View File

@@ -8,115 +8,99 @@
/* 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->name = name; l = (BucketList) malloc(sizeof(struct BucketListRec));
l->lines = (LineList) malloc(sizeof(struct LineListRec)); l->name = name;
l->lines->lineno = lineno; l->lines = (LineList) malloc(sizeof(struct LineListRec));
l->memloc = loc; l->lines->lineno = lineno;
l->lines->next = NULL; l->memloc = loc;
l->next = hashTable[h]; l->lines->next = NULL;
hashTable[h] = l; } l->next = hashTable[h];
else /* found in table, so just add line number */ hashTable[h] = l;
{ LineList t = l->lines; } else /* found in table, so just add line number */
while (t->next != NULL) t = t->next; {
t->next = (LineList) malloc(sizeof(struct LineListRec)); LineList t = l->lines;
t->next->lineno = lineno; while (t->next != NULL) t = t->next;
t->next->next = NULL; t->next = (LineList) malloc(sizeof(struct LineListRec));
} t->next->lineno = lineno;
t->next->next = NULL;
}
} /* st_insert */ } /* st_insert */
/* 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");
l = l->next;
}
} }
fprintf(listing,"\n");
l = l->next;
}
} }
}
} /* printSymTab */ } /* printSymTab */

View File

@@ -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,22 +9,116 @@
#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
*/ */
void printSymTab(FILE * listing); void printSymTab(FILE *listing);
#endif #endif