编译原理实验查填符号表含源代码和运行结果.docx

上传人:b****8 文档编号:10973997 上传时间:2023-02-24 格式:DOCX 页数:14 大小:19.05KB
下载 相关 举报
编译原理实验查填符号表含源代码和运行结果.docx_第1页
第1页 / 共14页
编译原理实验查填符号表含源代码和运行结果.docx_第2页
第2页 / 共14页
编译原理实验查填符号表含源代码和运行结果.docx_第3页
第3页 / 共14页
编译原理实验查填符号表含源代码和运行结果.docx_第4页
第4页 / 共14页
编译原理实验查填符号表含源代码和运行结果.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

编译原理实验查填符号表含源代码和运行结果.docx

《编译原理实验查填符号表含源代码和运行结果.docx》由会员分享,可在线阅读,更多相关《编译原理实验查填符号表含源代码和运行结果.docx(14页珍藏版)》请在冰豆网上搜索。

编译原理实验查填符号表含源代码和运行结果.docx

编译原理实验查填符号表含源代码和运行结果

〈〈编译原理》实验报告

实验1查填符号表

姓名学号班级计科1001班

时间:

2012/3/22地点:

文波

同组人:

指导教师:

朱少林

实验目的

1、运用所学知识,选择语言、选择算法(数据结构),编程实现符号表管理程序。

2、熟悉编译过程,训练编写程序的能力,为后续实验积累经验。

实验内容

1、运用所学知识,编程实现符号表管理程序。

读出源程序中与C语言词法规定相一致的标

识符,并在符号表中进行查找,若存在则输出该标识符及其编号和位置;否则将其填入符号

表,并分配编号,确定位置,输出该标识符。

2、输出标识符表。

实验环境

软件:

VC++6.0

实验前准备

1、方案设计:

1准备模拟数据:

由于是识别符合c语言规定的标识符,故本实验中使用“测试文件.c”

2写出c语言标识符的正规式定义:

letter_rA|B|C|••-Z|a|b|•••z|_

digitr0|1|••-9idletter_(letter_|digit)*

3画出不确定的有限自动机

不确定的有限自动机如下:

C={3,4,5,6,8,9}

D={3,4,5,7,8,9}

状态转换表如下

状态

letter_

digit

A

B

B

C

D

C

C

D

D

C

D

 

4程序思想:

该实验重点是构造识别标识符的函数。

程序中,使用的数据结构如下:

structrecord

{

charname[20];

};

typedefstructrecordRECORD;

20

record是用来记录标识符的名字,并且规定标识符的长度最大为

structinfor//记录符号表的相关信息

structrecord*head;

intlength;//记录符号表的长度

};

typedefstructinforINFOR;

infor是用来指向record结构体的指针和符号表的长度,这个结构体主要是用于比较标

识符并将识别到的标识符写入分析结果文件中即本实验中的"search_table”函数,该函

数并没有直接把标识符写到文件,而是在该函数之外,新建一个文件用来放符号表,然在后来打印符号表的同时把打印的结果写该文件中去。

该程序中的"search_table”函数判断是否为新的标识符的方法就是把识别的一个标识符

与已经识别的一一比较看是否相同,如不相同则表长度加1,并将该标识符填入表中

while(j

j++;

}//与已有的标识符一一比较

if(j==i)//说明是新的标识符

strcpy(point[j].name,teststring);

//point[j].line=j;

p->length++;

}

2、程序设计

#include"stdio.h"

#include"stdlib.h"

#include"string.h"

structrecord

charname[20];

};

typedefstructrecordRECORD;

structinfor//记录符号表的相关信息

structrecord*head;

intlength;//记录符号表的长度

};

typedefstructinforINFOR;

voidsearch_table(char*teststring,INFOR*p,FILE*f)//查填符号表函数,p为指向结构体的指针

inti=p->length;

intj=0;

RECORD*point;

point=p->head;

while(j

}//与已有的标识符一一比较

if(j==i)//说明是新的标识符

strcpy(point[j].name,teststring);

//point[j].line=j;

p->length++;

}

printf("标识符%s在符号表的第%d行\n",teststring,j+1);

fprintf(f,"%s\t%5d\n”,teststring,j+1);//将新的标识符写入文件分析结果文件f中

return;

}

voidmain()

charreadchar;//从文件中读到的字符

charteststr[20];//存放标识符

charlinkstr[2]={0};//用于把字符readchar连接到teststrFILE*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"命令

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<='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);

}

inti=0;

//printf("行数\t");

//printf("标识符\n");

printf("************************************\n");

printf(-以下是符号表的内容\n”);

printf("行数\t\t\t标识符\n”);

while(i

printf("%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”内容如下:

include

1

stdio

2

h

3

int

4

_qq

5

int

4

temp

6

char

7

temp_s

8

int

4

search

9

char

7

str

10

char

7

c

11

void

12

main

13

char

7

str

10

c

11

int

4

m

14

i

15

printf

16

please

17

input

18

a

19

string

20

gets

21

str

10

puts

22

please

17

input

18

the

23

char

7

you

24

search

9

c

11

getchar

25

m

14

search

9

str

10

c

11

if

26

m

14

printf

16

can

27

not

28

find

29

else

30

printf

16

the

23

c

11

you

24

search

9

is

31

d

32

n

33

m

14

int

4

search

9

char

7

str

10

char

7

c

11

int

4

i

15

for

34

i

15

str

10

i

15

i

15

if

26

str

10

i

15

c

11

return

35

i

15

return

35

存放符号表的文件“符号表.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

使用的模拟数据“测试文件.c”如下:

#include

int_qq;

int3temp;

chartemp_s;

intsearch(charstr[80],charc);

voidmain()

{

charstr[80],c;

intm,i;

printf("pleaseinputastring:

");

gets(str);

puts("pleaseinputthecharyousearch");

c=getchar();

m=search(str,c);

if(m==-1)

printf("cannotfind");else

printf("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(&information.head[i],strlen(mark[i].name),1,table);我把每次写入的数据块长

度设为了sizeof(record),而该结果是20,所以导致每个标识符长度是20.

不过该实验还有一个地方需要改进,因为对于“23aa”这样的字符串“aa”按照规定应该不

是一个标识符,而在这个试验中却也把“aa”识别为了一个标识符,本来想用一个char型

history来记录上个读入字符来判断识别的字符串是不是以数字开头的某字符串的后部分,但

是没成功,时间关系,我再思考下如何实现该功能。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 学科竞赛

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1