编译原理课程设计词法分析
编译原理课程设计词法分析任务书
5)参考文献:
(1)张素琴,吕映芝. 编译原理[M]., 清华大学出版社
(2)蒋立源、康慕宁等,编译原理(第2版)[M],西安:西北工业大学出版社
6)课程设计进度安排
1.准备阶段(4学时):选择设计题目、了解设计目的要求、查阅相关资料
2.程序模块设计分析阶段(4学时):程序总体设计、详细设计
3.代码编写调试阶段(8学时):程序模块代码编写、调试、测试
4.撰写论文阶段(4学时):总结课程设计任务和设计内容,撰写课程设计论文
学生签名:
2019 年 5 月 9 日
课程设计(论文)评审意见
(1)学习态度(20分):优( )、良( )、中( )、一般( )、差( );
(2)系统设计(20分):优( )、良( )、中( )、一般( )、差( );
(3)编程调试(20分):优( )、良( )、中( )、一般( )、差( );
(4)回答问题(20分):优( )、良( )、中( )、一般( )、差( );
(5)论文撰写(20分):优( )、良( )、中( )、一般( )、差( );
评阅人: 职称: 讲师
2019 年 5 月 10 日
中文摘要
实现功能及实现:
主要实现对文本中的程序进行词法分析,把程序中的单词分为五大类(基本保留字[1]、标识符[2]、常数[3]、运算符[4]、分隔符[5])并与相应的区域数字来对应输出.
之前利用Java中的BufferedReader缓冲器对象来存储读取程序的文件,在刘立月老师指导下,较大程序文件的时有超时的情况,后更改成一行编译读取方式.利用两个异常处理,文件读取异常和输出异常时打印ERROR.
背景和意义:
词法分析的过程是线性的从头至尾扫描一遍,复杂度较低,易实现。能完成计算机翻译过程的关键阶段,它为后面的语法分析、语义分析做好准备,打好基础,以便快速地、高质量地生成目标语言程序。
关键字: 词法分析、文件异常、目标语言程序
一、课程设计任务及要求
1.1、目的
通过使用一个通用的能够自动根据正规表达式生成词法分析程序的工具程序设计一个简单语言的词法分析器,使学生充分理解课程理论内容和工具软件的使用技巧,掌握所涉及的典型数据结构,算法及方法,为今后在大型软件系统实践中设计性能优良的软件系统打下基础。
1.2、任务与要求
【基本要求】
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输 出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
【测试数据】
如源程序为C语言。输入如下一段:
1 main(){2 3 int a,b;4 5 a = 10;6 7 b = a + 20;8 9 }
测试数据
1 (2,”main”) (2,”a”) 2 3 (5,”(“) (4,”=”) 4 5 (5,”)“) (3,”10”) 6 7 (5,”{“) (5,”;”) 8 9 (1,”int”) (2,”b”)10 11 (2,”a”) (4,”=”)12 13 (5,”,”) (2,”a”)14 15 (2,”b”) (4,”+”)16 17 (5,”;”) (3,”20”)
二、需求分析
2.1、分析
通过修改代码使得自动机能够更多的实现运算符号的识别功能,使用TINY语言调试一个程序,加深同学对词法分析的认识以及理解。另外,同时增强编写和调试程序的能力。
2.2、问题解决
对读取的文件进行预处理,从头到尾进行扫描,去除//和/* */的内容,以及一些无用的、影响程序执行的符号如换行符、回车符、制表符等。但是千万注意不要在这个时候去除空格,因为空格在词法分析中有用,比如说int i=3;这个语句,如果去除空格就变成了“inti=3”,这样就失去了程序的本意,因此不能在这个时候去除空格。
2.3、解决步骤
对源文件从头到尾进行扫描了,从头开始扫描,主控程序主要负责系统建立一个文件保存四个表,这四个表分别存储关键字、运算符、界符、过滤符。而标识符和常数则用正则表达式判断。建立了多个布尔类,当系统读取代码时,用空格或制表符作为标志符,当遇到空格就输出之前检索的字符串进行判断(规定每个单词符号之间都有空格),判断字符串时,系统会通过顺序查找依次调用布尔类与之匹配来判断其属性并输出,如没有匹配成功,则说明所检索的字符串不合法,系统则会输出非法字符串。直到最后一个字符串匹配完毕之后系统结束。
三、设计思路
3.1、总体思路分析
程序的关键点在于对给出一段程序中的各种单词的分离。在每段程序中,单词种类可以分为:关键字,分界符,算术运算符,关系运算符,标识符和常数。关键字的判断则是通过与已知数组中列出的元素进行对比,得出该单词是否为关键字;分解符,算术运算符,关系运算符的判断与接受到的字符进行比较,得出该字符是否为分解符,算术运算符或者为关系运算符。
状态图
图3-1-1:功能模块分解图
总控程序流程图:
图3-1-2:控制流程图
3.2、设计原理
主要任务如下:
识别出输入的源程序中的单词,输出二元组形式的单词序列。
删除无用的空白字符、回车符等没有实质意义的字符。
图3-2:正规式和状态转换图
实验步骤:
PL/0语言文法的EBNF表示如下:
1 <程序>::=begin<语句串>end 2 3 4 5 <语句串>::=<语句>{;<语句>} 6 7 <语句>::=<赋值语句> 8 9 10 11 <赋值语句>::=ID:=<表达式>12 13 14 15 <表达式>::=<项>{+<项> | -<项>}16 17 18 19 <项>::=<因子>{*<因子> | /<因子>20 21 22 23 <因子>::=ID | NUM | (<表达式>)
3.3实现方法
本次实验是设计词法分析器,其中核心函数是cifa(),分析的语言是PL/0,首先,采用循环遍历的方法读取用户输入的一段代码,跳过源程序中的空格字符,然后if语句配合switch语句对读入的代码挨个判断,最后以二元组的形式输出结果。
四、详细设计
4.1、项目设计步骤
a) 创建存放识别程序文件
图4-1:待编译程序文件test.txt
b) 读取文件单词并存储
读取文件test.txt文件:
1 br = new BufferedReader(new FileReader("tests.txt"));
存放构成单词符号的字符串:
1 public StringBuffer strToken = new StringBuffer();
基本保留字(关键字)
1 public String [] retainWord = new String[]{"int","if","else","return","main","void","while","break"};
c) 识别不同程序单词
基本保留字
1 for(int i = 0;i < retainWord.length;i++){//是否为关键字,,是返回12 if(strToken.toString().equals(retainWord[i])){3 4 return 1;5 6 }7 8 }
1 if(code == 1){//关键字2 System.out.println("('"+1+"','"+strToken+"')");3 4 }
标识符
1 for(int i = 0;i < retainWord.length;i++){//是否为关键字,,是返回1 2 if(strToken.toString().equals(retainWord[i])){ 3 4 return 1; 5 6 } 7 8 } 9 10 if(strToken.length() != 0){11 12 ......13 14 }15 16 return 2;17 18 }19 20 21 22 else if(code == 2){//非数字,关键字23 System.out.println("('"+2+"','"+strToken+"')");24 25 }26 27 28 29 30 31 常数32 33 if(strToken.charAt(0)>='0' && strToken.charAt(0)<='9'){//第一个是否为数字返回334 return 3;35 36 }37 38 39 40 else if(code == 3){//数字41 System.out.println("('"+3+"','"+strToken+"')");42 43 }
运算符
1 else if(ch == 43){ 2 Retract(); 3 4 System.out.println("('"+4+"','"+(char) ch+"')"); 5 6 7 8 }else if(ch == 45){ 9 Retract(); 10 11 System.out.println("('"+4+"','"+(char) ch+"')"); 12 13 14 15 }else if(ch == 42){ 16 Retract(); 17 18 System.out.println("('"+4+"','"+(char) ch+"')"); 19 20 21 22 }else if(ch == 47){ 23 Retract(); 24 25 System.out.println("('"+4+"','"+(char) ch+"')");
分隔符
1 System.out.println("('"+5+"','"+(char) ch+"')"); 2 }else if((char) ch == '('){ 3 4 Retract(); 5 6 System.out.println("('"+5+"','"+(char) ch+"')"); 7 }else if((char) ch == ')'){ 8 9 Retract(); 10 11 12 13 System.out.println("('"+5+"','"+(char) ch+"')"); 14 }else if((char) ch == '{'){ 15 16 Retract(); 17 18 19 20 System.out.println("('"+5+"','"+(char) ch+"')"); 21 }else if((char) ch == '}'){ 22 23 Retract(); 24 25 26 27 System.out.println("('"+5+"','"+(char) ch+"')"); 28 }else if((char) ch == ','){
d) 语言单词编码
表4-4:语言单词编码
五、运行调试与分析讨论
程序运行环境为Win10系统,在IDEA/ECLIPSE上运行
运行结果分析如下:
5.1、当在文本文件test.txt中输入文法:
图5-1-1:类型号和单词输出结果
5.2输出异常处理:
a) 文件路径异常
图5-1-2:获取程序文件异常
b) 程序中未识别单词异常
图5-1-3:不能识别程序单词报错
六、设计体会与小结
心得体会:
这个程序实现了课设的所有要求(由于我是31号做第一题词法分析模拟,但同时实现了扩展功能对于注释的文字进行忽视编译),虽然可能还存在些不足,像之前刘立月老师提出的我的程序对于简短的程序是完全可以的,我的读取方式是对象全部读取.但是对于一些比较大的项目来进行对象读取时间比较长.于是在我的程序当中进行了一定量的修改,更改成行的读取.用编译原理的知识自己独立完成这样一个程序我觉得还不错了,毕竟做这样的课设可以学到不少东西.
学习心得:
一开始对编写词法分析毫无头绪,不知如何下手。上网查资料是我们迈开的第一步,然后查阅相关资料,小组里相互讨论帮助,在多次的调试和改进中终于把程序完成了。通过这次的程序实验我对编译原理这门课程有了进一步的深层次了解,而且在自已动手体验的情况下,更加透彻地理解了词法分析的过程。在设计过程中,要发扬团体合作的精神,互帮互助,共同进步。善于发问,善于思考。
七、参考文献
1 [1] 张素琴.编译原理. 北京:清华大学出版社,2005 2 3 [2] 付京周.JAVA 程序设计语言. 北京:人民邮电出版社,2007 4 5 [3]黄贤英,王珂珂.编译原理及实践教程.北京:清华大学出版社,2008 6 7 [4]黄贤英,王珂珂,刘洁,曹琼.编译原理重点难点分析.习题解析·实验指导.北京:机械 8 9 工业出版社,200810 11 [5]陈媛,何波,涂晓红,涂飞算法与数据结构.北京:清华大学出版社,2005[4]刘恒洋,杨宏雨.算法与数据结构.北京:机械工业出版社,201012 13 [6]陈火旺,《程序设计语言编译原理》(第3版),北京:国防工业出版社.2000.14 15 [7]美Alfred V. Aho Ravi Sethi Jeffrey D. Ullman著.李建中,姜守旭译.《编译原理》. 北京:机械工业出版社.2003.16 17 [8]美KennethC. Louden著.冯博琴等译.《编译原理及实践》.北京:机械工业出版社.2002.18 19 [9]金成植著.《编译程序构造原理和实现技术》.北京:高等教育出版社.2002.