编译原理实验报告
实验一 词法分析程序的设计与实现
指导教师: 姓名: 学号: 班级:
一、实验目的
基本掌握计算机语言的词法分析程序的开发方法。 二、实验内容
编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。 三、实验要求
1.根据以下的正规式,编制正规文法,画出状态图; 标识符 <字母>(<字母>|<数字字符>)*
十进制整数 0 | (1|2|3|4|5|6|7|8|9) (0|1|2|3|4|5|6|7|8|9)* 八进制整数 0 (0|1|2|3|4|5|6|7) (0|1|2|3|4|5|6|7)*
十六进制整数 0 (x|X) (0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f) (0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)* 运算符和分隔符 + - * / > < = ( ) ; 关键字 if then else while do
2.根据状态图,设计词法分析函数int scan( ),完成以下功能: (1)从输入流(键盘或文件)读入数据,分析出一个单词。 (2)返回单词种别(用整数表示),
(3)返回单词属性(不同的属性可以放在不同的全局变量中)。
3.编写测试程序,循环调用函数scan( ),每次调用,获得一个单词的信息。在测试程序中,打印输出单词种别、属性(注意:不要在词法分析函数
scan 中打印输出!)。 四、实验环境
微型计算机。
Windows 操作系统/Linux 操作系统。
编程语言:C/C++/Java/C#。建议使用Visual C++/Netbeans/Eclipse 集成开发环境。 五、实验步骤
1. 根据状态图,设计词法分析算法 2. 设计函数scan( ),实现该算法
3. 编制测试程序(在本试验中,可以是主函数main( ) )。 4. 调试程序:输入一组单词,检查输出结果。 六、状态图
七. 测试数据: 0 92+data> 0x3f
00 while
八.测试结果
九,思考题
1. 词法分析能否采用空格来区分单词?
答:不能,因为比如abc+bcd中没有空格,但这是三个单词。 2. 程序设计中哪些环节影响词法分析的效率?如何提高效率?
答:整个程序都由状态转换图而来。由递归方法实现的状态转换图,影响了整个词法分析器的分析效率,可以考虑使用栈来非递归的实现词法分析。 十.实验心得
通过词法分析程序的实现,我理解了计算机是怎么去识别一个个单词的,或者可以说是各种命令的。这次实验使我对c语言中文件操作更加了解,了解文件指针的运行情况,还了解了编译原理中有限自动机的概念,根据状态图写程序。 十一.源代码
#include
#define INT8 11 //八进制 #define INT10 12 //十进制 #define INT16 13 #define SLP 14 //左括号( #define SRP 15 //右括号) #define SEMI 16 //分号; #define LP 17 //左花括号{ #define RP 18 //右花括号}
#define INC #define DECC 20 #define NEQ #define EQ #define JAE #define JA #define JBE #define JB
struct word { int kind; int value; };
int fpoint; int num_token; char *token; fstream file;
19 21 22 23 24 25 26
//--
//++ //不等于 //等于 //大于等于 //大于 //小于等于 //小于
//文件字符指针 //一个单词中的字符数量,主要是数字长度
//所要读取的文件
//处理标识符(包括关键字)
word handle_identifier(char *ch)
{
struct word re; //返回值 //////////////////////////关键字/////////////////////////// if(strcmp(ch,\ { re.kind=IF; re.value=0; return re; } if(strcmp(ch,\ { re.kind=THEN; re.value=0; return re; } if(strcmp(ch,\ { re.kind=WHILE; re.value=0; return re; } if(strcmp(ch,\ {
}
re.kind=DO; re.value=0; return re;
//////////////////////////标识符/////////////////////////// re.kind=ID; re.value=0; return re; }
int convert(char ch) //将字符转换成数字 { int number; switch(ch) { case'0': number=0;break; case'1': number=1;break; case'2': number=2;break; case'3': number=3;break; case'4': number=4;break; case'5': number=5;break; case'6': number=6;break; case'7': number=7;break; case'8': number=8;break; case'9': number=9;break; case'A': number=10;break; case'a': number=10;break; case'B': number=11;break; case'b': number=11;break; case'C': number=12;break; case'c': number=12;break; case'D': number=13;break; case'd': number=13;break; case'E': number=14;break; case'e': number=14;break; case'F': number=15;break; case'f': number=15;break; default: number=-1;break; //非法字符转换成-1 } return number; }
word handle_number(char *ch,int TN) //处理无符号整数 { int i,j;