编译原理实验----符号表

1.        实验目的

了解符号表的作用、组织和数据结构,设计和实现一个符号表。

2.        实验要求

a)                  合理有效地设计符号表可存储程序语言中的各种标识符(变量、常量、数组、结构、指针、函数和过程)及其属性和作用域信息

b)                  列出关键算法的具体实现的思路

3.        实验原理及内容

1)符号表的作用

符号表用于登录名字(标识符)、相应对象的种类(常量、变量、数组、结构、文件、标号、指针、函数与过程等)、属性(整型、实型、字符型、布尔型与枚举型等)和作用域信息。

由于在编译的各个阶段都要对符号表进行频繁操作(查表和填表),在整个编译时间中占了较大比例,因此如何有效合理地组织符号表并选择好的填表和查表方式,对于提高编译器的工作效率有很大影响。

       (2)符号表的组织

源程序中的每个标识符在符号表中都有1个条目,一般由两部分组成:名字栏和信息栏。

如果一个语言对标识符的最大长度有限制,可设计名字栏的域大小为最大长度来容纳整个标识符;若该语言对标识符最大长度无限制或最大长度较大(如:32),为节省存储空间,可另用一个字符数组存储标识符,在名字栏域中存储其起始地址和长度(字符个数)。

源程序中的标识符种类繁多,不同种类的标识符所需要存储的信息不同。如:变量需存储其类型、存储地址等,数组应存储其数组维数m、数组元素类型T、各维元素个数 di、起始地址base等,指针应存储其指向对象类型的位置,函数应存储其参数及类型、返回值类型等……

源程序中的说明将标识符与具有某种类型属性的数据对象相关联。同一个标识符在不同程序位置被说明时代表不同的数据对象。当出现对一个标识符的引用时,需根据作用域规则查符号表获取正确的符号表条目。C语言采用静态作用域规则,按最近嵌套原则确定作用域。

       (3)符号表的数据结构

由于线性表的访问复杂度为O(n),效率较低,符号表常采用效率更高的哈希技术进行实现: 当出现标识符id的定义时,计算哈希函数H(id),获取其在哈希表的存储位置,如该位置为空,则直接存储,否则应用冲突消解方法来获取其存储位置;当出现对标识符id的引用时,计算哈希函数H(id),获取其在哈希表的存储位置。

4.        程序代码

C++

Microsoft Visual Studio 6.0

 

#include <iostream>

#include <string>

#include <iomanip>

 

using namespace std;

 

 

//标志符数据类型的枚举,整型、实型、字符型、布尔型与枚举型等

enum{Int, Float, Char, Bool};

 

 

#define SIZE 211

 

 

#define SHIFT 4

 

 

static int hash ( string key )

{ int temp = 0;

  int i = 0;

  while (key[i] != '\0')

  { temp = ((temp << SHIFT) + key[i]) % SIZE;

    ++i;

  }

  return temp;

}

 

 

//常量, 变量, 指针

typedef class List

{

public:

string name; //标识符名

    int type; //标识符数据类型

    long scope; //标识符作用域信息

long memloc; //内存中的位置

int flag; //常量, 变量, 指针的标志(1, 2, 3)

    List * next;

} * BucketList;

 

//数组

typedef class Array

{

public:

string name; //标识符名

    int type; //标识符数据类型

    long scope; //标识符作用域信息

long memloc; //数组首地址

    int weishu; //数组维数

    string spec; //数组大小,a[2][3]--->spec=2*3;

    Array * next;

} * ArrayList;

 

 

typedef class Param

{

public:

int type; //参数类型

string name; //参数名

Param *next;

} * ParamList;

 

//函数

typedef class Function

{

public:

string name; //函数名

int type; //返回值类型

    ParamList pl; //参数列表

    long scope; //标识符作用域信息

long memloc; //函数入口的地址

    Function * next; //异名链表指针

} * FunctionList;

 

 

static BucketList ListHash[SIZE];

static ArrayList ArrayHash[SIZE];

static FunctionList FunctionHash[SIZE];

 

 

//量的哈希表插入 

void List_insert(string name, int type, long scope, long loc, int flag)

int h = hash(name);

List *l;

l = new List;

l->name = name;

l->type = type;

l->scope = scope;

l->memloc = loc;

l->flag = flag;

l->next = ListHash[h];

ListHash[h] = l;

}

 

//量的哈希表修改 

void List_delete(string name)

{

int h = hash(name);

ListHash[h] = NULL;

}

 

//量的哈希表查找

long List_find(string name)

{

int h = hash(name);

List *l;

l = ListHash[h];

return l->memloc;

}

 

//数组的哈希表插入 

void Array_insert(string name, int type, long scope, long loc, int weishu, string spec)

{

int h = hash(name);

Array *l;

l = new Array;

l->name = name;

l->type = type;

l->scope = scope;

l->memloc = loc;

l->weishu = weishu;

l->spec = spec;

l->next = ArrayHash[h];

ArrayHash[h] = l;

}

 

//数组的哈希表修改 

void Array_delete(string name)

{

int h = hash(name);

ArrayHash[h] = NULL;

}

 

//数组的哈希表查找

long Array_find(string name)

{

int h = hash(name);

Array *l;

l = ArrayHash[h];

return l->memloc;

}

 

//函数的哈希表插入

void Function_insert(string name, int type, ParamList pl, long scope, long loc)

{

int h = hash(name);

Function *l;

l = new Function;

l->name = name;

l->type = type;

l->pl = pl;

l->scope = scope;

l->memloc = loc;

l->next = FunctionHash[h];

FunctionHash[h] = l;

}

 

//函数的哈希表插入

void Function_delete(string name)

{

int h = hash(name);

FunctionHash[h] = NULL;

}

 

//函数的哈希表查找

long Function_find(string name)

{

int h = hash(name);

Function *l;

l = FunctionHash[h];

return l->memloc;

}

 

//量的打印

void printList()

{

int i;

cout << "各种量的符号表" << endl;

cout << "Name Type Scope Memloc flag" << endl;

cout << "---------------------------------------------------" << endl;

for(i=0; i<SIZE; i++)

{

if(ListHash[i] != NULL)

{

BucketList l = ListHash[i];

while(l != NULL)

{

cout << setw(10) << l->name << setw(10) << l->type << setw(10) << l->scope << 

setw(10) << l->memloc << setw(10) << l->flag << endl;

l = l->next;

}

}

}

}

 

//数组的打印

void printArray()

{

int i;

cout << "数组的符号表" << endl;

cout << "Name Type Scope Memloc Weishu Spec" << endl;

cout << "-----------------------------------------------------------" << endl;

for(i=0; i<SIZE; i++)

{

if(ArrayHash[i] != NULL)

{

ArrayList l = ArrayHash[i];

while(l != NULL)

{

cout << setw(10) << l->name << setw(10) << l->type << setw(10) << l->scope << 

setw(10) << l->memloc << setw(10) << l->weishu << setw(10) << l->spec << endl;

l = l->next;

}

}

}

}

 

//函数的打印

void printFunction()

{

int i;

cout << "函数的符号表" << endl;

cout << "Name Type Scope Memloc" << endl;

cout << "-----------------------------------------" << endl;

for(i=0; i<SIZE; i++)

{

if(FunctionHash[i] != NULL)

{

FunctionList l = FunctionHash[i];

while(l != NULL)

{

cout << setw(10) << l->name << setw(10) << l->type << setw(10) << l->scope << setw(10) << l->memloc << endl;

l = l->next;

}

}

}

cout << "参数列表的符合表" << endl;

cout << "FunctionName type ParamName" <<endl;

cout << "----------------------------------------" << endl;

for(i=0; i<SIZE; i++)

{

if(FunctionHash[i] != NULL)

{

FunctionList l = FunctionHash[i];

while(l != NULL)

{

ParamList p = l->pl;

while(p != NULL)

{

cout << setw(10) << l->name << setw(10) << p->type << setw(10) << p->name << endl;

p = p->next;

}

l = l->next;

}

}

}

}

 

int main()

{

string name = "afa";

int type = 1;

long scope = 101010;

long loc = 1000220;

int flag = 1;

ParamList p1, p2;

p1 = new Param;

p2 = new Param;

p1->name = "a";

p1->type = 1;

p1->next = p2;

p2->name = "b";

p2->type = 2;

p2->next = NULL;

List_insert(name, type, scope, loc, flag);

List_insert("fa", 2, 101010, 101011, 2);

Array_insert("a", 1, 101111, 112132, 2, "2*3");

Function_insert("A", 1, p1, 1010011, 11111);

printList();

printArray();

printFunction();

cout << "查找" << endl;

cout << List_find("fa") << endl;

cout << "删除" << endl;

List_delete("fa");

printList();

    return 0;

}

posted @ 2017-05-31 15:11  天涯海角路  阅读(3460)  评论(0)    收藏  举报