编译原理课程实验报告
实验 1:词法分析
院系
学号
出勤、表现得分
操作结果得分
指导教师
实验时间
实验报告
得分
实验总分
姓名
任课教师
实验地点
实验课表现
一、实验目的
基本目的:编写一个词法分析的程序以完成对词素的识别与分析、储存,能合理描述词法规
则,画出正确的状态转换图,并使用符号表存储词法分析的结果以便供语法分析器使用,还
要实现对错误的处理。主要目的在于巩固、加深对编译原理词法分析的认识和理解,并加强
动手实践的能力。
实现:通过对课堂所讲关于词法分析内容的复习,再加上自己阅读编译原理书籍并思考,分
析词法规则并画出状态转换图,并依照状态转换图写出这样一个程序,读取源代码并放入
char 数组,遍历此 char 数组并分析,实现对词素的识别,然后根据不同的状态将它们分类
存入符号表以供语法分析器使用。对于词法错误的地方,本程序还会给予提示。
二、实验内容
词法规则描述:
标识符:由字母开头,可以由数字和字母组成,但不能是已规定的关键字。
关键字:keyword→if | else | while | for | do | return | int | double | float | char | string
整常数:digit→[0-9]
integer→digit+
字符常数:letter→[a-z][A-Z]
character→ ' letter ' | ' digit ' | ' \(" | ' | \ | n | t | b | r | f | 0) '
浮点常数:decimal→integer(.integer)?
单界符:operator1→ = | + | - | * | / | < | > | = | , | { | } | ( | )
双界符:operator2→ != | >= | <= | ==
注释:comment→//
状态转换图与程序框图:
标识符状态转换图:
标识符程序框图(包含了关键字的程序框图):
关键字状态转换图:
由于在程序中,关键字直接从标识符中判断,所以关键字的程序框图合并到了标识符中
整常数状态转换图:
整常数程序框图(包含了浮点常数的程序框图):
字符常数状态转换图:
字符常数程序框图:
浮点常数状态转换图:
浮点常数程序框图被包含在整常数程序框图中。
单界符状态转换图:
单界符程序框图(包含了双界符程序框图):
双界符状态转换图:
双界符程序框图包含在单界符程序框图中。
注释状态转换图:
注释程序框图:
核心数据结构的设计:
关键字、双界符均用字符串数组存储,单界符、转义字符用字符数组存储。把对它们的
判断封装在方法里,此方法实现对数组的遍历,若数组中某项与想要判断的数据匹配,则返
回 true,否则返回 false。
符号表使用了 SymbolTable 类,此类中有两个私有属性:key 和 value,它们的类型都是
ArrayList。此类用于以字符串类型存储词法分析器分析出的各项信息,其中 key 存放类型,
value 存放值。假设有一个关键字 return,则它的 key 值为 keyword,value 值为 return。
key 值
keyword
关键字
identifier 标识符
integer
decimal
operator
string
character 字符
运算符
字符串
含义
整数
小数
此类暂时满足对词素的存储,在实现语法分析器的时候此类的设计可能会有改动。
错误处理:
若出错则终止分析,不能生成完整的符号表,输出已分析的词素并提示错误信息,粗略
指出出错位置。这时就需要检查源程序并改正相应的地方。
本程序可提示以下几个错误:
1.对浮点数进行判断,若小数点后没有数字(例如 78. )则提示“XX 附近出现错误,小数
点后应该有数字”;
2.对标识符进行判断,若标识符以数字开头(例如 123abc)则提示“XX 附近出现错误,标
识符不能以数字开头”;
3.对双引号进行判断,如果双引号未闭合(体现在字符串遇到换行符之前没有匹配的表字符
串结束的双引号),则提示“XX 附近出现错误,双引号未闭合”。
4.对字符常量进行判断。此判断实现较繁琐,一般来说单引号中只能有一个字符,但是需要
考虑转义字符的情况。如果是转义字符,则单引号中有两个字符,而且还需注意一点:不是
所有字符可以跟在\后面构成转义字符,所以这种情况也应该考虑到。一些可能的错误以及
对应的具体提示信息请参考实验结果中词法错误报告的表格。
三、实验结果
一个正确的输入对应的分析结果如下(分析结果有点长,未显示全),符号表即为右侧的分
析结果,其中冒号左边为 key 值,右边为 value 值,右边的结果即是遍历符号表并使用 key :
value 的格式打印出来的。对照右图可以发现词素都被正确地分析了:
下面是一些错误的例子(使用表格来表示):
提示信息
character : a (没有出错,被正确分析)
character : \" (没有出错,被正确分析)
'\q 附近有错误,字符未闭合或使用了不正确的转义字符
'\\附近有错误,字符未闭合或使用了不正确的转义字符
'ab 附近有错误,' '中字符的长度应为 1 或者字符未闭合
'a 附近有错误,' '中字符的长度应为 1 或者字符未闭合
所输入的数据
'a'
'\"'
'\q'
'\\
'ab'
'a
'''(3 个连续的单引号) '''附近有错误,您可能未使用规定的转义字符
123abc 附近出现错误,标识符不能以数字开头
123abc = 1
123.附近出现错误,小数点后应该有数字
double a = 123.
"abc
"abc 附近出现错误,双引号未闭合
四、实验中遇到的问题总结
遇到的问题:
1.把整个源代码使用 char 数组表示,最重要的一个问题是下标的越界问题,在判断 code[i+1]
时如果 code[i]已经是最后一个字符,则下标会越界。为了解决这个问题,我在代码中添加
了很多 if 判断语句,例如 i+1