编译原理课程设计词法分析

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

 

编译原理课程设计词法分析任务书正则表达式

 

 

5)参考文献:算法

(1)张素琴,吕映芝. 编译原理[M]., 清华大学出版社编程

(2)蒋立源、康慕宁等,编译原理(第2版)[M],西安:西北工业大学出版社数组

6)课程设计进度安排数据结构

1.准备阶段(4学时):选择设计题目、了解设计目的要求、查阅相关资料ide

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.二、任务与要求

  【基本要求】

   编制一个读单词过程,从输入的源程序中,识别出各个具备独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输            出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“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、需求分析

2.一、分析

  经过修改代码使得自动机可以更多的实现运算符号的识别功能,使用TINY语言调试一个程序,加深同窗对词法分析的认识以及理解。另外,同时加强编写和调试程序的能力。

 

2.二、问题解决

  对读取的文件进行预处理,从头至尾进行扫描,去除//和/*  */的内容,以及一些无用的、影响程序执行的符号如换行符、回车符、制表符等。可是千万注意不要在这个时候去除空格,由于空格在词法分析中有用,好比说int i=3;这个语句,若是去除空格就变成了“inti=3”,这样就失去了程序的本意,所以不能在这个时候去除空格。

 

2.三、解决步骤

  对源文件从头至尾进行扫描了,从头开始扫描,主控程序主要负责系统创建一个文件保存四个表,这四个表分别存储关键字、运算符、界符、过滤符。而标识符和常数则用正则表达式判断。创建了多个布尔类,当系统读取代码时,用空格或制表符做为标志符,当遇到空格就输出以前检索的字符串进行判断(规定每一个单词符号之间都有空格),判断字符串时,系统会经过顺序查找依次调用布尔类与之匹配来判断其属性并输出,如没有匹配成功,则说明所检索的字符串不合法,系统则会输出非法字符串。直到最后一个字符串匹配完毕以后系统结束。

 

 

 

 

3、设计思路

3.一、整体思路分析

  程序的关键点在于对给出一段程序中的各类单词的分离。在每段程序中,单词种类能够分为:关键字,分界符,算术运算符,关系运算符,标识符和常数。关键字的判断则是经过与已知数组中列出的元素进行对比,得出该单词是否为关键字;分解符,算术运算符,关系运算符的判断与接受到的字符进行比较,得出该字符是否为分解符,算术运算符或者为关系运算符。

 

状态图

 

 

 

 

图3-1-1:功能模块分解图

总控程序流程图:

 

 

图3-1-2:控制流程图

3.二、设计原理

主要任务以下:

识别出输入的源程序中的单词,输出二元组形式的单词序列。

删除无用的空白字符、回车符等没有实质意义的字符。

图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、详细设计

4.一、项目设计步骤

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:语言单词编码

 

5、运行调试与分析讨论

程序运行环境为Win10系统,在IDEA/ECLIPSE上运行

运行结果分析以下:

5.一、当在文本文件test.txt中输入文法:

 

图5-1-1:类型号和单词输出结果

 

 

 

 

 

 

 

 

 

5.2输出异常处理:

 

a)        文件路径异常

 

 

图5-1-2:获取程序文件异常

 

b)       程序中未识别单词异常

 

 

图5-1-3:不能识别程序单词报错

6、设计体会与小结

 

心得体会:

这个程序实现了课设的全部要求(因为我是31号作第一题词法分析模拟,但同时实现了扩展功能对于注释的文字进行忽视编译),虽然可能还存在些不足,像以前刘立月老师提出的个人程序对于简短的程序是彻底能够的,个人读取方式是对象所有读取.可是对于一些比较大的项目来进行对象读取时间比较长.因而在个人程序当中进行了必定量的修改,更改为行的读取.用编译原理的知识本身独立完成这样一个程序我以为还不错了,毕竟作这样的课设能够学到很多东西.

 

学习心得:

  一开始对编写词法分析毫无头绪,不知如何下手。上网查资料是咱们迈开的第一步,而后查阅相关资料,小组里相互讨论帮助,在屡次的调试和改进中终于把程序完成了。经过此次的程序实验我对编译原理这门课程有了进一步的深层次了解,并且在自已动手体验的状况下,更加透彻地理解了词法分析的过程。在设计过程当中,要发扬团体合做的精神,互帮互助,共同进步。善于发问,善于思考。