(1)词法分析概述(主要介绍词法分析的主要功能)

1. 将正规式转化为NFA

2. 将NFA转化为DFA

3. 将DFA转化为最小DFA

4. 模拟DFA

5. 识别源程序

6. 错误信息判断

(2)?采用的技术及平台安装(主要介绍采用了什么开发语言,如何部署软件运行环境,简要说明不超过300字)

本实验采用Java语言编写,IDE为Eclipse Jee Oxygen,部署时直接下载安装对应软件即可,Java语言的配置需要在安装相应文件后,设置环境变量和系统变量。

(3)?算法分析(主要介绍采用的算法及数据结构,以及如何用数据结构实现算法,包含:数据结构和算法分析两部分内容,在对应算法分析部分,必须给出示例说明算法)

1.?栈,优先级识别正规式

数据结构:使用栈,分为运算符栈和字符栈

算法:将‘#’符号压入运算符栈,当输入表达式的字符坐标不等于表达式的长度或者运算符栈顶不等于‘#’时,做循环,在循环体中,判断表达式的各个字符,若不是运算符则压入字符栈,若是运算符,则与运算符栈的栈顶元素进行优先级比较,若栈顶元素优先级低,将运算符压栈,若相等,运算符栈弹栈,若栈顶元素优先级高,则弹出运算符栈,以及连续弹出两次字符栈,将上述弹出的两个字符和一个运算符作为一个运算组。

2.?Thompson算法

数据结构:构造节点和弧的结构来表示NFA,构造的结果类似图。通过结点和弧可以遍历整个图;NFA栈,用来保存中间的NFA结果。

算法:在通过优先级判断后得到的表达式单元,比如AB|(A或B)这样的正规式后,判断运算符是 | ,则调用事先编写好的五个构造函数(分别是或运算,连接运算,闭包运算,单个字符,ε运算)中的或运算,构造A|B的NFA,同时将构造好的NFA压进NFA栈,这一过程实际就是将NFA构造过程和表达式优先级判断过程同步。不断重复过程,最终得到的NFA栈的栈顶元素就是完整的NFA。

3.?最小子集法

数据结构:定义了表示DFA的矩阵和 表示状态集合的结构。

算法:首先定义了ε闭包和smove函数,设计递归的部分用栈来模拟递归。然后用表示状态集合的数据结构表示ε闭包+smove操作所得到的的状态集合,在运算过程中对于新的状态标号,并在后续对新的状态进行对应字符的smove+ε闭包运算,直到不再产生新状态为止。完成上述运算后,根据表示的新状态号和对应的字符,构造DFA矩阵。

4.?最小DFA算法

数据结构:定义了表示一个划分的数据结构,以及记录可以合并状态(即同属一个划分的两个状态)的集合。

算法:计算两个状态是否可以合并时,采用的是n!的时间复杂度的算法,即第一步为第一个状态和第2至n的状态进行是否可以合并为一组的判断,将可以合并的两个状态进行记录,第二步为判断第2个状态和第3至n的状态的判断,同样将可以合并的两个状态进行记录,循环上述步骤,直到n-1个状态和第n各状态进行上述过程。在完成上述步骤后,对于得到的记录可以合并为一组的状态的集合,判断二元组之间是否有公共状态,则表示这两个二元组的三个状态可以合并。比如,(1,2)和(2,3)表示1,2状态可以合并,2,3状态可以合并,通过判断知道,1,2,和2,3有公共状态2,则表示1,2,3这三个状态可以合并为一个组,即(1,2,3),其他组的判断也是这样,在全部合并完之后,得到最终的划分结果,再依照原先的DFA矩阵和划分结果,构造一个新的最小DFA矩阵。

5.?DFA模拟器算法

数据结构:无新定义数据结构。

算法:主要是将源程序代码段的各个字符依序进行再矩阵里的状态转移,观察最终结果是处于终态,非终态,还是出现错误的字符。

6.?字符串最大匹配识别

数据结构:将构造的最小DFA进行集合化,即定义list这样的集合

算法:主要是判断在最大匹配的过程中,会产生什么样的不同情况,比如当前字符串无法被所有DFA识别,或者能识别但是不处于终态,或者能识别且处于终态,明确各种情况下的操作即可。在这里要注意将构造的几个最小DFA按照关键字,数字,特殊字符,。。。标识符的顺序进行DFA模拟,确保没有误识别。

(4)?流程图(绘制并说明算法流程)

在这一过程中,文件流会不断将生成的中间结果写入txt文件中。

(5)?程序运行截图(根据实验指导书第3节提供的内容及要求显示输出结果,并提供对应交互信息)

1. 输入正规式

课本例子:case:(a|b)* a b b

生成的dfa和最小dfa

结果

用例:case:(0|1|2|3|4|5|6|7|8|9)

2. 对于每一个正规式所生成的DFA和最小DFA,数字代表状态,null代表空

Void

id:(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z) (a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|0|1|2|3|4|5|6|7|8|9)*

digital:(0|1|2|3|4|5|6|7|8|9) (0|1|2|3|4|5|6|7|8|9)*

因为正规式比较多且比较复杂,所以只展示出其中两个,所有的结构式保存在工程文件的resource.txt中。

3. 输入源程序

4. 识别结果

控制台

Resource.txt

5. 错误信息

对于数字开头的标识符,能将其非法性识别出来,见下图第四行的11a

(6)?测试用例

1.?正规式

KW:v o i d

KW:i n t

KW:f l o a t

KW:i f

KW:e l s e

id:(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z) (a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|0|1|2|3|4|5|6|7|8|9)*

ks:(|)|{|,|;|+|/|>|=|}

digital:(0|1|2|3|4|5|6|7|8|9) (0|1|2|3|4|5|6|7|8|9)*

(id这个用例在粘贴到界面内时注意让它的内容显示在同一行)

2.?源程序

void main(){

int x,a,b;

float y,c,d;

x=a+b;11a

??????y=c/d;

??????if(x>y)

??x=10;

??????else

???y=100;

}

?(7)?代码结构说明

?

(8)程序分析(主要介绍编程中出现的错误以及修改的说明以及实验心得)

1. 正规式的优先级是构造NFA的关键,运用数据结构课中的算数表达式优先级可以解决。

2. 构造NFA的五个子结构,因为NFA很像图,所以定义了结点和弧这两种结构,还定义了深度优先遍历NFA的函数,更深体会到了大二学习的数据结构知识对于编程的重要性。

3.在将NFA转化为DFA的过程中,由于对于数字,或者标识符这样字符很多的正规式的NFA,会含有大量ε,所以一开始用函数递归进行空闭包操作时,堆栈会溢出,后来将函数递归的形式用数据结构栈来模拟后,成功解决,由此体会到函数调用时以堆栈形式调用这一方式,以及告诫自己在使用递归时,虽然函数递归从代码上看结构更清楚,但是用栈来模拟递归的过程的性能会更好。

4. 接上一点,在最初使用函数递归的形式模拟空闭包和Smove操作时,由于中间变量的不断更新,导致在递归函数逐层退出到最外面一层时,中间变量的值已经改变,所以为了能暂时保存最外层函数的中间变量的原值,学习了Java语言的深拷贝和浅拷贝,这一机制是为了在存储内部增加一块存储空间,而不是简单的引用变量。

5.在设计最大匹配扫描源程序的字符串的算法时,因为在扫描过程中遇到的情况特别多,如果不将所有的过程用流程图或伪代码的形式预先定义好,编写程序时代码结构会显得臃肿。所以在编写代码时,按照流程图或伪代码的参照来写,代码的结构的简洁性以及程序的正确性会提高。

6. 在对字符串进行较为复杂的操作,比如提取某个特定的中间字符串时,使用java语言本身定义的正规式函数,进行split等操作时,会方便很多,不过要明确正规式的规则。

7. 在源程序字符串匹配过程中,想象int这个关键词,被用来识别字符串的DFA集合是有次序的,如果在识别int时,标识符DFA先于关键字intDFA,则int会被识别成一个标识符,而不是关键字,所以要明确这些DFA的识别优先级。

java编译器id_JAVA 词法编译器相关推荐

  1. java的lr词法编译器_Sample语言编译器(词法分析、正规式、LL、LR、 算符优先)...

    [实例简介] 重庆理工大学 编译原理 课程设计.用java编写,有漂亮的界面,支持词法分析,正规式转换.LL(1)分析.LR(0)分析.算符优先分析 [实例截图] [核心代码] compiler_2 ...

  2. java的lr语法编译器,编译器开发--- 自己动手用Java写编译器

    课程目录 1.用java实现一个简易编译器1-词法解析入门.mp4 2.用java实现一个简易编译器2-语法解析.mp4 3.语法解析改进及代码生成.mp4 4.输入系统及分词系统概述.mp4 5.输 ...

  3. 测试用什么编译java代码_java – 测试编译器

    我参与了一个项目,其中Java AST被翻译成另一种语言OpenCL,使用Eclipse编译器,并且有类似的问题. 我没有为你提供神奇的解决方案,但我会分享我的经验以防万一. 您使用预期输出(使用ou ...

  4. 一文带你学明白java虚拟机:C1编译器,HIR代码优化

    HIR代码优化 为了减少编译时间,C1在抽象解释生成HIR期间,每生成一条SSA指令,都会调用append_with_bci努力尝试若干局部优化.除此之外,HIR构造完成之后,C1还会执行若干轻量级全 ...

  5. 你深入解析过java虚拟机:C1编译器,从HIR到LIR吗?

    从HIR到LIR LIR类似于三操作数的实现,但多了一些诸如对象分配和加锁的高级指令.C1遍历HIR的每个基本块,为每个基本块的每条SSA指令生成对应的LIR指令.从HIR到LIR的转换过程由LIRG ...

  6. 大多数程序员都懂的java虚拟机:C1编译器从字节码到HIR

    从字节码到HIR 正如之前看到的,C1的HIR是一个基于静态单赋值的图IR,由基本块构成控制流图,由静态单赋值指令构成基本块,如图8-1所示. 所有的指令都派生自Instruction类,其中,Blo ...

  7. java 解释器与JIT编译器

    早在Java1.0版本的时候,Sun公司发布了一款名为Sun Classic VM的Java虚拟机,它同时也是世界上第一款商用Java虚拟机,在当时这款虚拟机内部只提供解释器,用今天的眼光来看待必然是 ...

  8. java开发C语言编译器:把C实现的快速排序算法编译成jvm字节码

    有了前面一系列的铺垫和准备后,我们终于能走到至关重要的一刻.在本节,我们将用C语言开发快速排序算法,然后利用我们的编译器把它编译成java字节码,让C语言编写的快速排序算法能在java虚拟机上顺利执行 ...

  9. 【Android Protobuf 序列化】Protobuf 使用 ( protoc 编译器简介 | 下载 protoc 编译器 | 使用 protoc 编译器编译 .proto 源文件 )

    文章目录 一.protoc 编译器简介 二.下载 protoc 编译器 三.使用 protoc 编译器编译 addressbook.proto 源文件 四.参考资料 一.protoc 编译器简介 在上 ...

最新文章

  1. 高并发编程-重新认识Java内存模型(JMM)
  2. c++hello world代码_在 Rust 代码中编写 Python 是种怎样的体验?
  3. 让你一周变聪明的大脑保健操
  4. How to Leak a Context: Handlers Inner Classes
  5. python遍历文件目录_python遍历文件夹及其子目录
  6. C#unix时间戳转换
  7. 在线教育与计算机网络的融合发展,[浅谈线上教育和线下教育的融合]
  8. 全面接触PDF:最好用的PDF软件汇总
  9. Python计算水仙花数
  10. mysql5.7下载中文版_mysql 5.7版本的下载安装
  11. 计算机电源分金牌,机·科普贴:电脑电源金、银、铜牌到底是什么意思?
  12. 鸟哥的linux私房菜——蔡德明
  13. mysql中表结构是什么_查询MySQL数据库中表结构
  14. VMware 虚拟机 Nat 模式无法上网
  15. html自定义指针,如何自定义鼠标指针 怎样在wpf中自定义鼠标指针
  16. Mac 安卓投屏Scrcpy使用
  17. 后台获取访问端的真实ip地址
  18. 求解两圆相交的交点坐标
  19. Microchip PIC系列8位单片机入门教程(一)开发环境建立
  20. 电脑磁盘损坏怎么修复?数据恢复教程来了

热门文章

  1. Python入门100题 | 第004题
  2. spring4.x注解概述
  3. SpringMVC关于json、xml自动转换的原理研究[附带源码分析 --转
  4. 【数据处理】python数据评估常用指标:ks、fpr、tpr
  5. 【项目实战】SQL :部门花名册PBI展示
  6. 基于迁移学习的反欺诈方法研究
  7. 框架开发之Java注解的妙用
  8. 这个德国山寨工厂靠抄袭干到240亿,让硅谷恨之入骨
  9. 2013年,移动App设计的13大精髓
  10. Apache Kafka-通过设置Consumer Group实现广播模式