附录一 实验报告样式
《编译原理》实验报告
实验 1
查填符号表
地点:文波
时间: 2012/3/22
同 组 人:无
指导教师:朱少林
实验目的
1、运用所学知识,选择语言、选择算法(数据结构),编程实现符号表管理程序。
2、熟悉编译过程,训练编写程序的能力,为后续实验积累经验。
实验内容
1、运用所学知识,编程实现符号表管理程序。读出源程序中与 C 语言词法规定相一致的标
识符,并在符号表中进行查找,若存在则输出该标识符及其编号和位置;否则将其填入符号
表,并分配编号,确定位置,输出该标识符。
2、输出标识符表。
实验环境
软件:VC++6.0
实验前准备
1、 方案设计:
1 准备模拟数据:由于是识别符合 c 语言规定的标识符,故本实验中使用“测试文件.c”
2 写出 c 语言标识符的正规式定义:letter_→A|B|C|…Z|a|b|…z|_
digit→0|1|…9
3 画出不确定的有限自动机
不确定的有限自动机如下:
id→letter_(letter_|digit)*
进行化简:
A={1}
B={2,3,4,5,9}
C={3,4,5,6,8,9}
D={3,4,5,7,8,9}
状态转换表如下:
状态
A
B
C
D
letter_
digit
B
C
C
C
D
D
D
进行化简:{A} {B,C,D}
化简后的确定有限自动机如下:
4 程序思想:该实验重点是构造识别标识符的函数。程序中,使用的数据结构如下:
struct record
{
char name[20];
};
typedef struct record RECORD;
record 是用来记录标识符的名字,并且规定标识符的长度最大为 20
struct infor//记录符号表的相关信息
{
struct record
int length; //记录符号表的长度
*head;
};
typedef struct infor INFOR;
infor 是用来指向 record 结构体的指针和符号表的长度,这个结构体主要是用于比较标
识符并将识别到的标识符写入分析结果文件中即本实验中的“search_table”函数,该函
数并没有直接把标识符写到文件,而是在该函数之外,新建一个文件用来放符号表,然
在后来打印符号表的同时把打印的结果写该文件中去。
该程序中的“search_table”函数判断是否为新的标识符的方法就是把识别的一个标识符
与已经识别的一一比较看是否相同,如不相同则表长度加 1,并将该标识符填入表中
while( jlength++;
}
2、 程序设计
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
struct record
{
char name[20];
};
typedef struct record RECORD;
struct infor//记录符号表的相关信息
{
struct record
int length; //记录符号表的长度
*head;
};
typedef struct infor INFOR;
void search_table(char *teststring, INFOR *p, FILE *f)//查填符号表函数,p 为指向结构体的
指针
{
int i=p->length;
int j=0;
RECORD *point;
point=p->head;
while( jlength++;
}
printf("标识符%s 在符号表的第%d 行\n",teststring,j+1);
fprintf(f,"%s\t%5d\n",teststring,j+1);//将新的标识符写入文件分析结果文件 f 中
return;
void main()
}
{
char readchar;//从文件中读到的字符
char teststr[20];//存放标识符
char linkstr[2]={0};//用于把字符 readchar 连接到 teststr
FILE *fp;
fp=fopen("测试文件.c","r");
if (fp==NULL)
{
printf("打开文件失败!");
exit(0);
}//打开测试文件 fp
FILE *result;
result=fopen("结果.txt","w+");//新建打开一个存放分析结果的文件 result
//fclose(result);这个命令使下面调用的 search_table 函数不能将分析结果写入“结果.txt”
//,因为 search_table 函数函数中没有打开“结果.txt”命令
INFOR information;//用于指向符号表
RECORD mark[300];//定义符号表最多可以有 300 个符号
information.head=mark;
information.length=0;
readchar=fgetc(fp);
//char history=readchar;利用这个记录读取的上一个字符,判断是否是数字
while(readchar!=EOF)
{
teststr[0]=0;
if(readchar<='z'&& readchar>='a'||readchar>='A'&& readchar<='Z'||readchar=='_')
//字母数字下划线开头,如果这个满足则下面的也一定满足
{
while(readchar<='z'&&
readchar>='a'||readchar>='A'&&
readchar<='Z'||readchar=='_'||readchar>='0'&& readchar<='9')
{
linkstr[0]=readchar;
strcat(teststr,linkstr);//会自动添加‘\0’
//if(history>'9'&&history<'0')
readchar=fgetc(fp);
}
if(strlen(teststr)!=0 )
{
search_table(teststr, &information, result);//将结果写入"结果.txt"
}
}//这个循环结束后就读入一个标识符
readchar=fgetc(fp);
}
fclose(fp);
fclose(result);
FILE *table=fopen("符号表.txt","w+");//新建"符号表.txt"文件
if(table==NULL)
{
printf("文件打开失败!");
exit (0);
}
int i=0;
//printf("行数\t");
//printf("标识符\n");
printf("************************************\n");
printf("以下是符号表的内容\n");
printf("行数\t\t\t 标识符\n");
while(i
1
8
9
16
17
18
20
17
18
9
25
9
include
stdio
h
int
_qq
int
temp
char
temp_s
int
search
char
str
char
c
void
main
char
str
c
int
m
i
printf
please
input
a
string
gets
str
puts
please
input
the
char
you
search
c
getchar
m
search
str
c
if
2
3
4
5
4
6
7
4
7
10
7
11
12
13
7
10
11
4
14
15
19
21
10
22
23
7
24
11
14
10
11
26
14
27
28
29
30
23
11
24
31
32
33
14
4
7
10
7
11
4
15
34
15
10
15
15
26
10
15
11
15
m
printf
can
not
find
else
printf
the
c
you
search
is
d
n
m
int
search
char
str
char
c
int
i
for
i
str
i
i
if
str
i
c
return
i
return
16
16
9
9
35
35
1
存放符号表的文件“符号表.txt”内容如下:
include
stdio
h
int
_qq
temp
4
5
3
2
6