编译实验—符号表和语义检查

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编译原理 实验三


实验名称:符号表和语义检查
班级: 学号: 姓名:

一、实验要求
(一) 符号表的接口
(一) 符号表的实现
(二) 变量检查: 先声明,后使用
(三) 测试用例及其运行结果分析
(四) make 的使用

二、实验环境
(一) Linux 平台,gcc 编程环境。
(二) 文件清单

文件 说明
lex.h 词法分析接口
lex.c 词法分析实现
symtab.h 符号表接口
symtab.c 符号表实现
parse.c 语法和语义分析程序


三、实验过程

(一) 符号表的接口
1. 数据类型
2. 函数原型

(二) 符号表的实现
1. sym_find() 函数
2. sym_insert() 函数

(三) 符号表的使用
parse.c 中,变量声明和变量使用的语义处理。

(四) 测试用例及运行结果分析
1. 符合语义
2. 不符合语义:变量 undefined。
3. 不符合语义:变量 redefined。

六、实验小结和理解
(一) 实验小结
(二) 对符号表的理解
(三) 对变量先声明、后使用的处理方法的理解

----------------
编译原理 实验三


实验名称:符号表和语义检查

一、实验要求
(一) 符号表的接口
(一) 符号表的实现
(二) 变量检查: 先声明,后使用
(三) 测试用例及其运行结果分析
(四) make 的使用

二、实验环境
(一) Linux 平台,gcc 编程环境。
(二) 文件清单

文件 说明
lex.h 词法分析接口
lex.c 词法分析实现
symtab.h 符号表接口
symtab.c 符号表实现
parse.c 语法和语义分析程序


三、实验过程

(一) 符号表的接口
1. 数据类型
2. 函数原型
$ cat > symtab.h
#ifndef SYMTAB_H_
#define SYMTAB_H_

typedef enum { k_VAR, k_FUN, k_PAR, k_KEYWORD, k_OP } Symkind;

// 符号表项
typedef struct _Symitem * Symitem;
struct _Symitem {
char * id; // 符号名称
Symkind kind; // 符号类别
int offset; // 地址偏移量
Symitem next; // 下一符号
};

Symitem sym_insert(char * id, int kind, int offset);
Symitem sym_find(char * id);
int symtab_print();

#endif

(二) 符号表的实现
1. sym_find() 函数
Symitem sym_find(char * id) {
Symitem s;
for (s = symtab; s != NULL; s = s->next)
if (strcmp(s->id, id) == 0)
return s;
return NULL;
}

2. sym_insert() 函数
Symitem sym_insert(char * id, int kind, int offset) {
Symitem s = sym_find(id);
if ( s != NULL )
return s;

s = (Symitem) malloc(sizeof *s);
s->id = id;
s->kind = kind;
s->offset = offset;

s->next = symtab;
symtab = s;
return s;
}

(三) 符号表的使用
pars

e.c 中,变量声明和变量使用的语义处理。
int symbol_use(char * id) {
Symitem p = sym_find(id);
if ( p == NULL )
Errexit("undefined.");
}
int symbol_def(char * id) {
Symitem p = sym_find(id);
if ( p != NULL )
Errexit("redefined.");

sym_insert(id, k_VAR, 0);
}

(四) 测试用例及运行结果分析
1. 符合语义
2. 不符合语义:变量 undefined。
$ cat > t32.cmm
int x, y2, z;
x = 100;
y = 200;
if (x < y)
z = y - x;
else
z = x - y;
print z;

$ ./parse < t32.cmm
3: near y: undefined.

3. 不符合语义:变量 redefined。
$ cat > t31.cmm
int x, y2, z;
int u, z, v;
x = 100;
y = 200;
if (x < y)
z = y - x;
else
z = x - y;
print z;

$ ./parse < t31.cmm
2: near z: redefined.

六、实验小结和理解
(一) 实验小结:本次实验了解了符号表怎么使用,符号表可以把某些东西加进去,也可以在符号表中查找它。
(二) 对符号表的理解:符号表是所有内核符号及其对应地址的一个列表,随着每次内核的编译,就会产生一个新的对应System.map文件,当内核运行出错时,通过System.map中的符号表解析,就可以查到一个地址值对应的变量名。System.map文件记录了所有代码的运行地址(所有函数和变量)。
(三) 对变量先声明、后使用的处理方法的理解:这是编程语言的语法规则,它这样定义的主要目的是为了让编译器首先知道该定义变量的类型,可以事先为该变量安排存储空间,不致于最后编译失败。如果预先没有定义,可想而知,编译器会弄不清楚此变量类型,如果分配空间大了浪费,小了存不下。

相关文档
最新文档