编译原理实验报告--词法分析器
- 格式:docx
- 大小:311.52 KB
- 文档页数:18
编译原理实验—词法分析器
一、 实验目的
通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。同时增强编写和调试程序的能力。 二、 实验内容及要求
对某特定语言A ,构造其词法规则。
该语言的单词符号包括:
保留字(见左下表)、标识符(字母大小写不敏感)、 整型常数、界符及运算符(见右下表) 。
功能要求如下所示:
·按单词符号出现的顺序,返回二元组序列,并输出。
·出现的标识符存放在标识符表,整型常数存放在常数表,并输出这两个表格。
·如果出现词法错误,报出:错误类型,位置(行,列)。
·处理段注释(/* */),行注释(//)。
·有段注释时仍可以正确指出词法错误位置(行,列)。
三、 实验过程
1、 词法形式化描述
使用正则文法进行描述,则可以得到如下的正规式:
其中ID表示标识符,NUM表示整型常量,RES表示保留字,DEL表示界符,OPR表示运算符。
A→(ID | NUM | RES | DEL | OPR) *
ID→letter(letter | didit)*
NUM→digit digit*
letter→a | … | z | A | … | Z
digit→ 0 | … | 9
RES→ program | begin | end | var | int | and | or | not | if | then
| else | while | do
DEL→( | ) | . | ; | ,
OPR→+ | * | := | > | < | = | >= | <= | <>
如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。空格由空白、制表符和换行符组成。
2、 单词种别定义;
A语言中的单词符号及其对应的种别编码如下表所示:
单词符号 种别编码 单词符号 种别编码 program 1 + 16
begin 2 * 17
end 3 ( 18
var 4 ) 19
int 5 , 20
and 6 . 21
or 7 := 22
not 8 ; 23
if 9 >
24
then 10 < 25
else 11 = 26
while 12 >= 27
do 13 <= 28
标识符 14 <> 29
整型常量 15 - 30
3、 状态转换图;
语言A的词法分析的状态转换图如下所示:
空格符,制表符
或回车符 字母或数字
数字
非字母或数字 2 字母 0 1
非数字 3
+ 数字
5
6
3 1*
7 (
8 ) 4
10 . 9 ,
12 :
1) 1非= =
4、 运行环境介绍;
本次实验采用MyEclipse进行代码的编写和编译及运行,编写语言为java语言;程序的运行环境为windows 7 旗舰版
5、 关键算法的流程图及文字解释;
程序中用到的函数列表: 25 其他 A类定义各种类函数以及包含主函数public static void main()
变量ch储存当前最新读进的字符的地址
strToken存放当前字符串
main() //主函数
Analysis()//分析函数,每次读入一行文件,进行识别处理;
char GetChar(); //取得当前位置的字符的内容放入ch,并提前指向下一个字符;
char GetNextChar();//取得当前位置的下一位置的字符,
String ConCat(); //将ch指向的字符连接到strToken后面
isLetter(); //判断ch指向的字符是否字母
isDigit(); //判断ch指向的字符是否数字
add(p,str); //向p表中插入当前strToken的字符串
Boolean findKeyWord(str); //检测当前strToken中的字符串是否保留字,若是,则执行getKeyWordKey(str),返回保留字的id,否则,判别其是否是已存在的标示符,若是,返回标示符的id以及该标示符在表中的位置;
findPunctuation()//判断是否是一个保留的符号;
getindex() //返回已经识别的标示符或者是数字的位置下标;
Boolean exist(); //检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回true,否则返回false
void callError(); //出错处理过程,将错误的位置报告出来
(1)main()函数的流程图如下:
(2)具体分析流程图:
开始
类初始化,变量的初始化,准备执行main()函数
调用Analyse()函数分析
输出结果表
结束
Analyse(str)函数
读取第一个字符赋给变量Ch
继续判读
IndexoutofBound
6、测试报告(测试用例,测试结果);
首先输入一个不含错误的程序(两种注释)进行检测:
运行后在控制台上得到的结果如下所示:
得到的二元组序列如下:
经检验,输出的是正确的二元组序列。
再输入一个含有错误的程序(含有注释)进行检验:
运行后在控制台上得到的结果如下所示:
经检验,错误的位置是正确的
如果是空文件,编译也会通过;
四、 实验总结
通过本次试验,我加深了对编译原理中的词法分析的理解,同时通过动手,更加锻炼了自己。本次试验由于使用的刚刚学习的java语言,通过这次机会加强了自己对java语言的熟悉的使用。
在这次试验中,感谢老师的认真的讲解与同学的无私的帮助。总结来说,自己在这次试验中收获很大。
附:以下为本次实验的源代码:
package Analysis;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class A {
private static char ch;
private static String strToken;
private static int index = 0;
private static int line = 1;
private static boolean noteTag=false;
private Map< Integer,String > keywords;
private HashMap
private static ArrayList
private static ArrayList
// get and set 函数
public char getCh() {
return ch;
}
public void setCh(char ch) {
A.ch = ch;
}
public String getStrToken() {
return strToken;
}
public void setStrToken(String strToken) {
A.strToken = strToken;
}
public void setPunctuations(HashMap
{
this.punctuations = punctuations;
}
public Map
return punctuations;