词法分析程序构造原理与实现技术编译原理实验报告_第1页
词法分析程序构造原理与实现技术编译原理实验报告_第2页
词法分析程序构造原理与实现技术编译原理实验报告_第3页
词法分析程序构造原理与实现技术编译原理实验报告_第4页
词法分析程序构造原理与实现技术编译原理实验报告_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、编译原理实验词法分析程序构造原理与实现技术目录引言3一、实验目的3二、实验环境3三、实验内容3四、实验要求4五、程序功能描述45.1 输入输出45.2大小写不敏感55.3识别大多数常用程序字符55.4注释的处理55.5 错误检查和处理5六、主要数据结构6七、程序结构描述67.1各单词符号的类别编码67.2程序总体以及局部执行图67.3设计方法87.4函数定义及函数之间的调用关系8八、程序测试8代码附录12引言本课程开展研究性教学的目的是,在教师的引导下以问题回朔与思维启发的方式,使学生在不断的探究过程中掌握编译程序设计和构造的基本原理和实现技术,启迪学生的抽象思维、激发学生的学习兴趣、培养学生

2、的探究精神和专业素养,从而提高学生发现问题、分析问题和解决问题的能力。一、实验目的1. 解决正则文法到状态转换图的转化问题2. 掌握正则文法及其状态转换图的基本概念,正则表达式及有限自动机的基本概念3. 深入理解理论对实践的指导作用:基本原理、实现技术和方法的正确运用4. 掌握正规文法构造相应的状态转换图的基本方法和正则表达式构造有限自动机的基本方法及不确定有限自动机确定化的基本方法5. 完成词法分析程序的设计与编写二、实验环境软件:操作系统:WINDOWS 8应用软件:VC6.0三、实验内容1、教学安排内容:完成以下正则文法所描述的 Pascal 语言子集单词符号的词法分析程序。<标识

3、符>字母 <标识符>字母 <标识符>数字<无符号整数>数字 <无符号整数>数字<单字符分界符> + * ; ()<双字符分界符><大于>=<小于>=<小于>><冒号>=<斜竖>* <小于>< <等于>= <大于>> <冒号> : <斜竖> /该语言的保留字 :begin end if then else for do while and or not 2、在此基础上,我自己新完善了

4、一下词法分析处理: 1)新增保留字:return break main 2)扩充可识别的标识符文法:<标识符><标识符><下划线>字母 <标识符><下划线>数字3)新增可识别的经常使用的符号:如 ' " = != n(t)(r) %s(%d)( %f) 等,以及数组(形如a )还有程序经常出现的,<> 等四、实验要求1. 给出各单词符号的类别编码;2. 词法分析程序应能发现输入串中的错误;3. 词法分析作为单独一遍编写,词法分析结果为二元式序列组成的中间文件;4. 设计两个测试用例(尽可能完备),并给出测

5、试结果。五、程序功能描述5.1 输入输出 输入:将事先准备好的代码录入txt中,程序将改*.txt进行词法分析 输出:在命令行中以二元组(类别码,TOKEN)显示5.2大小写不敏感 将纯字母组合中的大写字母转换成小写后,在保留字数组中查找是否是系统保留字 5.3识别大多数常用程序字符能够识别C语言中常见的 n r t , %s %d %f, 单引号,双引号, 逻辑运算符 以及形如a的数组的符号等。 5.4注释的处理1. 当输入文件中出现了/*的字符串之后,程序会自动忽略之后的输入字符串,直到遇*/,但程序会输出/*2. 当输入文件中出现了/的字符串之后,程序会自动忽略之后的输入字符串,直到遇回

6、车字符后,则判断为注释结束,但程序会输出/5.5 错误检查和处理当输入串为未定义的字符时,在输出文件中显示“Error!”,如输入¥六、主要数据结构主要是利用数组,进行保留字的查询与将符合某个正则文法的字符归结到一起。七、程序结构描述7.1各单词符号的类别编码单词符号类别码单词符号类别码begin1:=23end2+24if3-25then4*26else5/27for6;28do7(29while8)30and931or1032not11数组(形如a)33return12#34break13.35main14,36ID标识符15形如n,37INT整型16形如%s38<17"3

7、9<=18!40=19!=41<>20=42>2143>=22/ | /*44 | 457.2程序总体以及局部执行图总体流程图:词法分析流程图:7.3设计方法1. 预定义好各单词符号的类别,包括保留字2. 用数组来存储识别过程中的单词字符3. 循环一个一个字符的读取与分析,若开头是字母,则判断为标识符,并将其转换为小写,然后读取完后,进行保留字比较,若是,则输出保留字的二元组;不是则输出标识符的二元组4.开头不是字母的而是数字的,则继续读取,直到数字全读完,输出类别是整型的二元组5. 若不属于以上2中类型,则转到其他字符的判别,查找宏定义中的字符,找到则输出其二元

8、组,没有找到,则进行出错输出。7.4函数定义及函数之间的调用关系main函数中,调用fopen函数,将文本文件打开,在调用scanner_example函数进行词法分析,在分析过程中,调用lookup函数进行保留字查找,用out函数进行二元组的输出,用report_error函数来进行出错检查八、程序测试测试文件1:#include<stdio.h>char TOKEN20;char TOKEN120;/*sjsj*/if(strcmp(temp,keywordi)=0)/hkskx=i+1;return x;break;¥void main()FILE *fp;char file

9、name10;/*sdsfsfs*/while(1)printf(" n r t");scanf("%s",filename);fp=fopen(filename,"r");/122344scanner_example(fp);fclose(fp);运行截图: 测试文件2:#include <stdlib.h>#include <conio.h>/*=宏定义部分=*/#define ID 15 /标识符#define INT 16 /整型#define LT 17 /"<"void m

10、ain()FILE *fp;char filename10;while(1)printf("n");scanf("%s",filename);fp=fopen(filename,"r");/*以只读的方式打开文本文件*/scanner_example(fp);fclose(fp);截图: 代码附录/*=头文件部分=*/#include<stdio.h>#include<ctype.h>#include<string.h>#include <stdlib.h>#include <co

11、nio.h>/*=宏定义部分=*/#define ID 15 /标识符#define INT 16 /整型#define LT 17 /"<"#define LE 18 /"<="#define EQ 19 /"="#define NE 20 /"<>"#define GT 21 /">"#define GE 22 /">="#define DE 23 /":="#define ADD 24 /"+&qu

12、ot;#define SUB 25 /"-"#define MUL 26 /"*"#define DIV 27 /"/"#define SE 28 /""#define BL 29 /"("#define BR 30 /")"#define HL 31 /""#define HR 32 /""#define SZ 33 /"形如a"#define TS 34 /"#"#define PO 35 /

13、"."#define CO 36 /","#define TX 37 /"形如n"#define Tx 38 /"形如%s"#define QU 39 /" " "#define TH 40 /"!"#define BD 41 /"!="#define DY 42 /"="#define SQ 43 /" ' "#define X 44 /" / "#define XX 45 /

14、" /* "char TOKEN20;char TOKEN120;char* keyword14="begin","end","if","then","else","for","do","while","and","or","not","return","break","main"/*=函数声明部分

15、=*/int lookup(char *);void out(int,char *);void scanner_example(FILE *);void report_error(void);/*=函数实现部分=*/*-查找保留字-*/int lookup(char *temp)int i,x=15;for(i=0;i<14;i+)if(strcmp(temp,keywordi)=0)x=i+1;return x;return x;/*-输出二元式-*/void out(int a,char *temp)printf("( %d , %s )n",a,temp);/*

16、-报错-*/void report_error(void)printf("Error!n");/*-词法分析-*/void scanner_example(FILE *fp)char ch;char str3;int i,c;while(1) ch=fgetc(fp);if(ch=EOF)break;else if(ch=' '|ch='')/*跳过程序中的空格字符*/elseif (isalpha(ch)/*开头是字母的统一归到标识符或者保留字一类*/TOKEN0=tolower(ch);/*将大写字符转换成小写*/TOKEN10=ch;c

17、h=fgetc(fp);i=1;while(isalnum(ch)/*将标识符完整的读到数组TOKEN中*/TOKENi=tolower(ch);/*将大写字符转换成小写*/TOKEN1i=ch;i+;ch=fgetc(fp);TOKENi='0'TOKEN1i='0'if(!feof(fp)fseek(fp,-1,1);c=lookup(TOKEN);if(c=15)while(1)ch=fgetc(fp);if(ch=EOF)out(ID,TOKEN1);break;else if(ch=' ')out(ID,TOKEN1);break;el

18、se if(ch='')/*识别数组*/TOKEN1i=ch;ch=fgetc(fp);i+;while(isalnum(ch)TOKEN1i=ch;i+;ch=fgetc(fp);if(ch='')TOKEN1i=ch;out(SZ,TOKEN1);break;else if(ch='_')/*识别带有下标的标识符*/TOKEN1i=ch;ch=fgetc(fp);i+;while(isalnum(ch)TOKEN1i=ch;i+;ch=fgetc(fp);TOKEN1i='0'fseek(fp,-1,1);out(ID,TOK

19、EN1);break;elseout(ID,TOKEN1);break;elseout(c,TOKEN1);elseif(isdigit(ch)/*识别纯数字*/TOKEN0=ch;ch=fgetc(fp);i=1;while(isdigit(ch)TOKENi=ch;i+;ch=fgetc(fp);TOKENi='0'fseek(fp,-1,1);out(INT,TOKEN);elseswitch(ch)/*识别单字符分界符、双字符分界符以及一些程序中经常用到的逻辑运算符,注释(注释-统一忽略)等*/case '+': out(ADD,"+"

20、;);break;case '-': out(SUB,"-");break;case '*': out(MUL,"*");break;case '': out(SE,"");break;case '(': out(BL,"(");break;case ')': out(BR,")");break;case '': out(HL,"");break;case '':

21、out(HR,"");break;case '#': out(TS,"#");break;case '.': out(PO,".");break;case ',': out(CO,",");break;case '"': out(QU,""");break;case ''': out(SQ,"'");break;case '!':ch=fgetc

22、(fp); /*读到"!"的时候,再读一个字符,如果是"=",则判断为逻辑运算符"!=",否则判断为普通的"!"*/if(ch='=')out(BD,"!=");elsefseek(fp,-1,1);/*多读的那一个字符要退回去,避免将下一个读错*/out(TH,"!");break;case '':ch=fgetc(fp);/*读到""的时候,再读一个字符,如果是"n或t或r",则判断为回车、换行或者制

23、表"n 或r 或t"*/ str0=''if(ch='n'|ch='t'|ch='r') str1=ch;str2='0'out(TX,str);break;case '%':ch=fgetc(fp); /*读到"%"的时候,再读一个字符,如果是"s或d或f",则判断为输出的类型 "%s 或%d 或%f"*/ str0='%'if(ch='s'|ch='d'|ch='

24、;f') str1=ch;str2='0'out(Tx,str);break;case '/': ch=fgetc(fp);/*读到"/"的时候,再读一个字符,如果是"*",则判断为注释,跳过,一直读到结束为止;如果是"/",则也为注释,读到回车就结束*/if(ch='*')out(XX,"/*");while(1)ch=fgetc(fp);if(ch='*')ch =fgetc(fp);if(ch='/')break;else

25、 if(ch='/')out(X,"/");while(1)ch=fgetc(fp);if(ch ='n')break;elsefseek(fp,-1,1);/*多读的那一个字符要退回去,避免将下一个读错*/out(DIV,"/");break;case'<': ch=fgetc(fp);/*读到"<"的时候,再读一个字符,如果是"=",则判断为关系运算符"<=",否则判断为"<"*/if(ch='=') out(LE,"<=");else if (ch='>')out (NE,"<>");elsefseek(fp,-1,1);/*多读的那一个字符要退回去,避免将下一个读错*/out(LT,"<");break;case '=':ch=fgetc(fp);/*

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论