编译原理实验报告(C语言)

  • 格式:doc
  • 大小:336.00 KB
  • 文档页数:14

编译原理实验报告

实验项目1:词法分析程序实验

一、实验的目的与任务:

编译原理是计算机类专业特别是计算机软件专业的一门重要专业课。设置该课程的目的在于系统地向学生讲述编译系统的结构、工作流程及编译程序各组成部分的设计原理和实现方法,使学生通过学习既掌握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。编译原理是一门理论性和实践性都比较强的课程。进行上机实验的目的是使学生通过完成上机实验题目加深对课堂教学内容的理解。同时培养学生实际动手能力。

编译实验由三个独立实验组成,按照由浅入深进行排列,希望通过本实验使学生更深学习并理解编译的主要过程和相关方法。

词法分析的目的是将输入的源程序进行划分,给出基本符号(token)的序列,并掠过注解和空格等分隔符号。基本符号是与输入的语言定义的词法所规定的终结符。

本实验要求学生编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续进行)

二、题目分析

1.这里采用C语言编写的源程序作为词法分析程序的输入数据,输入数据保存在“in.txt”记事本中,将分析结果存在“out.txt”记事本中。词法分析器的源代码使用C语言编写。

2. 下面就词法分析程序中的主要变量进行说明:

主函数main():

打开要分析的C语言源程序,若不能正确打开,则报错。

先从源程序中读入一个字符ch,然后进行如下处理:

1、cp消耗掉空格,制表符,换行符后,cp数组复位,开始检测cp;

2、数字检测,对照符号表输出,若匹配成功,则返回序号;

3、字符串检测, 对照符号表输出,若匹配成功,则返回序号;

4、基本保留字检测,对照符号表输出,若匹配成功,则返回序号;

5、运算符检测,对照符号表输出,若匹配成功,则返回序号;注意这里碰到‘/’时,要判断后面是否跟着是注释语句。是则跳过,不是则输出运算符。

6、分隔符(界符)检测,对照符号表输出,若匹配成功,则返回序号;

7、排错处理;

结束。

3.以下给定一个C语言的符号表的设计和结构:

C语言基本保留字表

main 1 if 12 sizeof 23

void 2 else 13 return 24

int 3 switch 14

float 4 case 15

double 5 for 16

char 6 do 17

struct 7 while 18

const 8 goto 19 extern 9 continue 20 常数 28

register 10 break 21 自定义字符 29

static 11 default 22

运算符 分隔符

‘+' 31 ; 41

‘-’ 32 : 42

‘*’ 33 , 43

‘/' 34 { 44

‘<' 35 } 45

‘<=’ 36 [ 46

‘>’ 37 ] 47

‘>=’ 38 ( 48

‘=’ 39 ) 49

‘!=' 40

其他运算符 27

4.程序源代码(C语言)

#include

#define MAX 500 /*标识符的最大长度*/

main()

{

FILE *in,*out;

char word[MAX]; /*存储标识符*/

char cp; /*存储当前读入字符*/

int i;

if((in=fopen("in.txt","r"))==NULL)

{

printf("不能打开文档in.txt,请检查根目录下是否存在该文档\n");

exit(0);

}

else

{

printf("成功打开文档in.txt\n");

}

if((out=fopen("out.txt","w"))==NULL)

{

printf("不能打开文档out.txt,请检查根目录下是否存在该文档\n");

exit(0); }

else

{

printf("成功打开文档out.txt\n");

}

cp=fgetc(in);

while(cp!=EOF)

{

/*消耗掉空格,制表符,换行符*/

while(cp==' '||cp=='\t'||cp=='\n')

{

cp=fgetc(in);

}

/*cp数组复位*/

i=0;

/*数字检测*/

if(cp>='0'&&cp<='9')

{

word[i++]=cp;

cp=fgetc(in);

while(cp>='0'&&cp<='9')

{

word[i++]=cp;

cp=fgetc(in);

}

if(cp=='

'||cp=='\t'||cp=='\n'||cp=='='||cp=='+'||cp=='-'||cp=='*'||cp=='/'||cp=='>'||cp=='<'||cp=='!'||cp==';'||cp==':'||cp==','||cp=='{'||cp=='}'||cp=='['||cp==']'||cp=='('||cp==')')

{

word[i]='\0';

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',28,')');

}

else

{

while(cp!='

'&&cp!='\t'&&cp!='\n'&&cp!='='&&cp!='+'&&cp!='-'&&cp!='*'&&cp!='/'&&cp!='>'&&cp!='<'&&cp!='!'&&cp!=';'&&cp!=':'&&cp!=','&&cp!='{'&&cp!='}'&&cp!='['&&cp!=']'&&cp!='('&&cp!=')')

{

word[i++]=cp;

cp=fgetc(in);

} word[i]='\0';

fprintf(out,"%s%c%s%c%s\n","error: ",'"',word,'"',"不是合法的标识符");

}

continue;

}

/*字符串检测*/

if((cp>='a'&&cp<='z')||(cp>='A'&&cp<='Z')||cp=='_')

{

while((cp>='a'&&cp<='z')||(cp>='0'&&cp<='9')||(cp>='A'&&cp<='Z')||cp=='_')

{

word[i++]=cp;

cp=fgetc(in);

}

if(cp=='

'||cp=='\t'||cp=='\n'||cp=='='||cp=='+'||cp=='-'||cp=='*'||cp=='/'||cp=='>'||cp=='<'||cp=='!'||cp==';'||cp==':'||cp==','||cp=='{'||cp=='}'||cp=='['||cp==']'||cp=='('||cp==')')

{

word[i]='\0';

/*基本保留字检测*/

if(strcmp(word,"main")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',1,')');

else if(strcmp(word,"void")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',2,')');

else if(strcmp(word,"int")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',3,')');

else if(strcmp(word,"float")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',4,')');

else if(strcmp(word,"double")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',5,')');

else if(strcmp(word,"char")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',6,')');

else if(strcmp(word,"struct")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',7,')');

else if(strcmp(word,"const")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',8,')');

else if(strcmp(word,"extern")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',9,')');

else if(strcmp(word,"register")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',10,')');

else if(strcmp(word,"static")==0)

fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',11,')');