编译原理实验 查填符号表含源代码和运行结果文档格式.docx
- 文档编号:22836265
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:15
- 大小:93.56KB
编译原理实验 查填符号表含源代码和运行结果文档格式.docx
《编译原理实验 查填符号表含源代码和运行结果文档格式.docx》由会员分享,可在线阅读,更多相关《编译原理实验 查填符号表含源代码和运行结果文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
2写出c语言标识符的正规式定义:
letter_→A|B|C|…Z|a|b|…z|_
digit→0|1|…9id→letter_(letter_|digit)*
3画出不确定的有限自动机
不确定的有限自动机如下:
进行化简:
A={1}
B={2,3,4,5,9}
C={3,4,5,6,8,9}
D={3,4,5,7,8,9}
状态转换表如下:
状态
letter_
digit
A
B
C
D
{A}{B,C,D}
化简后的确定有限自动机如下:
4程序思想:
该实验重点是构造识别标识符的函数。
程序中,使用的数据结构如下:
structrecord
{
charname[20];
};
typedefstructrecordRECORD;
record是用来记录标识符的名字,并且规定标识符的长度最大为20
structinfor//记录符号表的相关信息
structrecord*head;
intlength;
//记录符号表的长度
typedefstructinforINFOR;
infor是用来指向record结构体的指针和符号表的长度,这个结构体主要是用于比较标识符并将识别到的标识符写入分析结果文件中即本实验中的“search_table”函数,该函数并没有直接把标识符写到文件,而是在该函数之外,新建一个文件用来放符号表,然在后来打印符号表的同时把打印的结果写该文件中去。
该程序中的“search_table”函数判断是否为新的标识符的方法就是把识别的一个标识符与已经识别的一一比较看是否相同,如不相同则表长度加1,并将该标识符填入表中
while(j<
i&
&
strcmp(teststring,point[j].name))
{
j++;
}//与已有的标识符一一比较
if(j==i)//说明是新的标识符
strcpy(point[j].name,teststring);
//point[j].line=j;
p->
length++;
}
2、程序设计
#include"
stdio.h"
stdlib.h"
string.h"
voidsearch_table(char*teststring,INFOR*p,FILE*f)//查填符号表函数,p为指向结构体的指针
inti=p->
length;
intj=0;
RECORD*point;
point=p->
head;
while(j<
printf("
标识符%s在符号表的第%d行\n"
teststring,j+1);
fprintf(f,"
%s\t%5d\n"
//将新的标识符写入文件分析结果文件f中
return;
}
voidmain()
charreadchar;
//从文件中读到的字符
charteststr[20];
//存放标识符
charlinkstr[2]={0};
//用于把字符readchar连接到teststr
FILE*fp;
fp=fopen("
测试文件.c"
"
r"
);
if(fp==NULL)
打开文件失败!
"
exit(0);
}//打开测试文件fp
FILE*result;
result=fopen("
结果.txt"
w+"
//新建打开一个存放分析结果的文件result
//fclose(result);
这个命令使下面调用的search_table函数不能将分析结果写入“结果.txt”
//,因为search_table函数函数中没有打开“结果.txt”命令
INFORinformation;
//用于指向符号表
RECORDmark[300];
//定义符号表最多可以有300个符号
information.head=mark;
information.length=0;
readchar=fgetc(fp);
//charhistory=readchar;
利用这个记录读取的上一个字符,判断是否是数字
while(readchar!
=EOF)
teststr[0]=0;
if(readchar<
='
z'
readchar>
a'
||readchar>
A'
readchar<
Z'
||readchar=='
_'
)
//字母数字下划线开头,如果这个满足则下面的也一定满足
{
while(readchar<
0'
9'
{
linkstr[0]=readchar;
strcat(teststr,linkstr);
//会自动添加‘\0’
//if(history>
'
history<
readchar=fgetc(fp);
}
if(strlen(teststr)!
=0)
search_table(teststr,&
information,result);
//将结果写入"
}
}//这个循环结束后就读入一个标识符
fclose(fp);
fclose(result);
FILE*table=fopen("
符号表.txt"
//新建"
文件
if(table==NULL)
printf("
文件打开失败!
exit(0);
inti=0;
//printf("
行数\t"
标识符\n"
************************************\n"
以下是符号表的内容\n"
行数\t\t\t标识符\n"
while(i<
information.length)
%3d\t\t\t%s\n"
i+1,mark[i].name);
fwrite(&
information.head[i],strlen(mark[i].name),1,table);
fprintf(table,"
%4d\n"
i+1);
//向符号表中写入数据
i++;
fclose(table);
实验步骤
1、建立简单的符号表,可以只包含标识符和编号;
2、编写单词解析子程序,从源程序中分离出单词;
3、编写查找标识符的子程序(应考虑查找算法),插入新的标识符;
4、程序调试,输出标识符表。
实验结果及其分析:
分析后输出的分析文件是“结果.txt”内容如下:
include1
stdio2
h3
int4
_qq5
temp6
char7
temp_s8
search9
str10
c11
void12
main13
m14
i15
printf16
please17
input18
a19
string20
gets21
puts22
the23
you24
getchar25
if26
can27
not28
find29
else30
is31
d32
n33
for34
return35
存放符号表的文件“符号表.txt”内容如下:
使用的模拟数据“测试文件.c”如下:
#include<
stdio.h>
int_qq;
int3temp;
chartemp_s;
intsearch(charstr[80],charc);
voidmain()
{
charstr[80],c;
intm,i;
pleaseinputastring:
gets(str);
puts("
pleaseinputthecharyousearch"
c=getchar();
m=search(str,c);
if(m==-1)
cannotfind"
else
thecyousearchis%d\n"
m);
intsearch(charstr[80],charc)
inti;
for(i=0;
str[i]!
\0'
;
i++)
if(str[i]==c)
return(i);
}
return-1;
分析:
实验过程中最大的难题是文件的操作,因为之前关于文件的操作课程没有讲,再加上很久没写代码的原因,就先学了下文件操作,实验过程中最开始“结果.txt”总是空,后来知道原来是我在创建了该文件后就关闭了,在没有打开的情况下不能进行写入结果的操作;
还有就是刚开始的“符号表.txt”每个符号后面都有不同数目的“烫”,经分析知道这种情况下每个标识符都是强制的长度一致,都是20(定义的标识符最大长度是20),这是因为向文件中写入数据时:
fwrite(&
我把每次写入的数据块长度设为了sizeof(record),而该结果是20,所以导致每个标识符长度是20.
不过该实验还有一个地方需要改进,因为对于“23aa”这样的字符串“aa”按照规定应该不是一个标识符,而在这个试验中却也把“aa”识别为了一个标识符,本来想用一个char型history来记录上个读入字符来判断识别的字符串是不是以数字开头的某字符串的后部分,但是没成功,时间关系,我再思考下如何实现该功能。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理实验 查填符号表含源代码和运行结果 编译 原理 实验 符号 源代码 运行 结果
![提示](https://static.bdocx.com/images/bang_tan.gif)