📄 lab3.c
字号:
/*
* file: lab3.c
*----------------------------------
* this file implements the functions in lab3.h
*/
#include "lab3.h"
#include "lab3.tab.h"
/*
* function: separator
* usage: separator()
* -------------------------
* just print out a separator
*/
void separator(void)
{
printf("===========================================================\n");
}
/*
* function: hashpjw
* usage: h = hashpjw(s, size)
* ----------------------------
* use 's' to hash
* the size of hash table is 'size'
*/
unsigned hashpjw(char *s, int size)
{
char *p;
unsigned h = 0, g;
for (p = s; *p != '\0'; p++) {
h = (h << 4) + (*p);
if (g = h & 0xf0000000) {
h = h ^ (g >> 24);
h = h ^ g;
}
}
return (h % size);
}
/*
* function: InsertID
* usage: s = InsertID(name)
* ----------------------------
* insert identifier 'name' to id_hash_table
*/
char *InsertID(char *name)
{
unsigned h = hashpjw(name, HASHTABLESIZE);
struct id_entry *p = id_hash_table[h];
while (p && strcmp(p->id, name) != 0) {
p = p->next;
}
if (p) {
return (p->id);
}
p = (struct id_entry *)malloc(sizeof(struct id_entry));
if (0 == p) {
printf("malloc for id: %s error\n", name);
exit(1);
}
p->id = (char *)malloc(strlen(name) + 1);
if (0 == p->id) {
printf("malloc for id name: %s error\n", name);
exit(1);
}
strcpy(p->id, name);
p->next = id_hash_table[h];
id_hash_table[h] = p;
return (p->id);
}
/*
* function: InsertFun
* usage: s = InsertFun(name, returntype)
* ----------------------------
* insert function 'name' to funtable
* the type of function's return value is 'returntype'
*/
char *InsertFun(char *name, int returntype)
{
unsigned h = hashpjw(name, FUNCTIONSIZE);
struct fun *p = funtable[h];
while (p && strcmp(p->funame, name) != 0) {
p = p->next;
}
if (p) {
return (0);
}
p = (struct fun *)malloc(sizeof(struct fun));
if (0 == p) {
printf("malloc for fun id: %s error\n", name);
exit(1);
}
p->funame = name;
p->retype = returntype;
p->count = typecount;
p->type = argtemp.temp;
p->next = funtable[h];
funtable[h] = p;
if (debug) {
separator();
printf("insert function: %s in funtable[%u]\n", name, h);
printf("argument:");
for (returntype = 0; returntype < typecount; returntype++) {
switch (p->type[returntype]) {
case VOID:
printf(" void");
break;
case INT:
printf(" int");
break;
case CHAR:
printf(" char");
break;
case VOID+100:
printf(" void*");
break;
case INT+100:
printf(" int*");
break;
case CHAR+100:
printf(" char*");
break;
default:
printf(" %d",p->type[returntype]);
break;
}
}
printf("\n");
separator();
}
return (p->funame);
}
/*
* function: LookUpFun
* usage: type = LookUpFun(name)
* ----------------------------
* lookup function 'name'
* check up the afferent arguments
* return the type value of function 'name'
*/
int LookUpFun(char *name)
{
unsigned h = hashpjw(name, FUNCTIONSIZE);
struct fun *p;
int i;
if (debug) {
separator();
printf("lookup function: %s in funtable[%u] and check arguments\n", name, h);
separator();
}
for (p = funtable[h]; p; p = p->next) {
if (p->funame == name) {
if (typecheck < p->count) {
printf("line %3d error: %s : too few actual parameters\n", lineno, name);
right = 0;
}
for (i = 0; i < typecheck; i++) {
if (p->type[i] == ELLIPSIS) {
break;
}
if (p->type[i] != arg_in.temp[i]) {
printf("line %3d error: %s : different types for formal and actual parameter %d\n", lineno, name, i+1);
right = 0;
}
}
return (p->retype);
}
}
return (0);
}
/*
* function: MakeTable
* usage: tp = MakeTable(previous, level)
* ----------------------------
* make a new table which previous table is 'previous'
* its depth is 'level'
* return the table'
*/
struct table *MakeTable(struct table *previous, int level)
{
int i;
struct table *p = (struct table *)malloc(sizeof(struct table));
if (0 == p) {
printf("malloc for symbol table error\n");
exit(1);
}
p->previous = previous;
p->level = level;
for (i = 0; i < BUCKETSIZE; i++) {
p->buckets[i] = 0;
}
return (p);
}
/*
* function: InsertSym
* usage: sym = InsertSym(name, tp)
* ----------------------------
* insert the symbol 'name' to table 'tp'
*/
symbol *InsertSym(char *name, struct table *tp)
{
unsigned h = hashpjw(name, BUCKETSIZE);
struct table *qt = tp;
struct sym_entry *p;
if (debug) {
separator();
printf("qt->level=%d level=%d insert_symbol_name=%s potential_symboltable[%d]\n", qt->level, level, name, tablelen-1);
}
if (qt->level < level) {
if (debug) {
printf("maketable symboltable[%d]\n",tablelen);
}
qt = MakeTable(tp, level);
symboltable[tablelen] = qt;
tablelen++;
}
if (debug) {
printf("actually insert symboltable[%d]\n", tablelen-1);
separator();
}
for (p = qt->buckets[h]; p; p = p->next) {
if (0 == strcmp(p->sym.name, name)) {
return (0);
}
}
if (0 == (p = (struct sym_entry *)malloc(sizeof(struct sym_entry)))) {
printf("malloc for symbol entry error\n");
exit(1);
}
p->sym.name = name;
p->sym.scope = level;
p->sym.type = 0;
p->next = qt->buckets[h];
qt->buckets[h] = p;
return (&p->sym);
}
/*
* function: LookUp
* usage: sym = LookUp(name, tp)
* ----------------------------
* find the symbol 'name' in table 'tp'
*/
symbol *LookUp(char *name, struct table *tp)
{
struct sym_entry *p;
unsigned h = hashpjw(name, BUCKETSIZE);
int i = tablelen - 1;
do {
if (debug) {
if (i == tablelen -1) {
separator();
printf("lookup id: %s in symboltable[%d] hash h=%u\n", name, i--, h);
} else {
printf("lookup id: %s in symboltable[%d]\n", name, i--);
}
}
for (p = tp->buckets[h]; p; p= p->next) {
if (debug) {
printf("tp->buckets[%u]->sym.name=%s\n", h, p->sym.name);
}
if (name == p->sym.name) {
if (debug) {
printf("I find it\n");
separator();
}
return (&p->sym);
}
}
} while (tp = tp->previous);
if (debug) {
printf("not find\n");
separator();
}
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -