阅读博客的朋友可以到我的网易云课堂中,通过视频的方式查看代码的调试和执行过程:

http://study.163.com/course/courseMain.htm?courseId=1002830012

大家好,欢迎大家来到coding迪斯尼,在上一节,我们讨论了如何对简单的正则表达式构造其对于的NFA状态机,通过代码,我们理解了如何对形如[abcd], [a-z], . , a 等这几种形态最简单的正则表达式,构建他们对应的Nfa。这一节,我们看看,如何在这一步基础上,构造更复杂的Nfa状态机。

我们把上面四种形态的正则表达式统一用 term 来概括,因此有:
term -> […] | [.-.] | . | a | [^…]
其中[…]对应[abcd]这种类型的字符集类,[.-.]对应[a-z]这种类型的字符集类。

现在我们看看, 如何构建term闭包操作对应的Nfa, 也就是如何实现
term*, term+, term?
这几种类型的Nfa状态机.

让我们回想下,Thompson构造算法中,闭包操作是怎么构造的:

中间的虚线框所代表的,可以是我们通过term所构造的Nfa状态机。通过上图,我们可以总结出程序的实现流程:
1. 通过term构造nfa状态机。
2. 分配两个节点作为头结点和尾结点。
3. 将头结点的next指向term返回的状态机的头结点(startNode),term返回的尾结点(endNode)的next2指向它本身的头结点, 将endNode的next指向分配的尾结点。
4. 将分配的头结点的next2指向尾结点(对应于图中的由头到尾那一条长长的ε边。

我们看看代码的实现:

大家可以看到,代码的实现步骤跟我在前面总结的是一一对应的。

我们再看看正闭包操作的实现:

根据上图,我们代码的实现流程如下:
1. 通过term构造nfa状态机(中间虚线框部分)
2. 分配两个节点做头节点和尾节点
3. 将头结点的next指向term返回的状态机的头节点,将term返回的状态机的尾节点的next2指向上面分配的尾节点,将term返回的状态机的尾结点的next 指针指向它自己的头结点(startNode)

我们看看代码的实现:

接下来,我们看看选择操作的nfa构建过程:

根据上图,我们总结出的构建流程如下:
1. 通过term 构造nfa状态机(中间虚线部分)
2. 分配两个节点作为头结点和尾节点
3. 将头结点的next指向term返回的状态机的头节点,将term返回的状态机的尾节点的next指向上面分配的尾节点
4. 将第二部分配的头结点的next2指向分配的尾节点。

我们看看代码的实现:

最后,我们把上面三个函数整合到一个函数factor中:

通过factor函数,可以总结出 以下语法规则:
factor -> term* | term+ | term?.

正则表达式 & 操作的nfa构建

正则表达式的 & 操作,其实就是多个正则表达式前后连接成一个新的表达式而已。例如 expr1 = [0-9]*, expr2 = [a-z] 那么expr1 & expr2 就是:
[0-9]*[a-z]
大家是否已经意识到,正则表达式的& 操作其实就是多个factor 前后连在一起。

(Thompson nfa状态机连接操作)

根据Thompson构造法,正则表达式 的nfa构建也简单,先通过factor构建多个nfa状态机,然后把上个factor返回的状态机所对应的尾节点的next指向下一个factor返回的状态机的头节点,流程总结如下:
1. 通过factor构建首个nfa状态机
2. 通过factor构建第二个nfa状态机
3. 将前两个状态机首尾连接成一个nfa状态机
4. 再看看能不能继续用factor构建出新的nfa状态机,如果可以的话,将第3步构建的状态机与当前构建的状态机首尾相连成一个nfa状态机
5. 重复 4, 直到不能继续用factor构造不出新的状态机为止。

代码实现如下:

while 循环实现的就是前面提到的2,3,4,5步骤。
first_in_cat 主要用来判断正则表达式的输入是否合法,如果表达式以 ], ) ,*, 等符号出现在开头,那么输入的表达式就是错误的,错误的表达式也就没有构建的必要, 如果表达式以EOS开始,也就是表达式解析结束了,这意味factor再也构建不了新的nfa状态机,那么连接操作就不需要再进行了:

讲解完代码和算法思路后,接下来,就是通过代码调试,跟大家展示代码的实现逻辑了。

用java实现编译器之代码实现Thompson构造:在简单NFA的基础上构造更复杂的NFA相关推荐

  1. 有限状态自动机java实现_用java开发编译器之:Thompson构造,将正则表达式转换为有限状态自动机...

    阅读博客的朋友可以到我的网易云课堂中,通过视频的方式查看代码的调试和执行过程: 上一节,我们通过代码,实现了一个有限状态自动机,并将其应用于对整形和浮点数的识别.构造有限状态自动机,并驱动它,从而实现 ...

  2. 用java开发编译器之:Thompson构造,将正则表达式转换为有限状态自动机

    阅读博客的朋友可以到我的网易云课堂中,通过视频的方式查看代码的调试和执行过程: http://study.163.com/course/courseMain.htm?courseId=10028300 ...

  3. java JNI调用C++代码(给出一个简单java application示例和实际java web项目过程及错误解决)(二)

    二.java web 服务器(tomcat)调用图像处理C++代码项目实例 转载请注明:https://blog.csdn.net/xitie8523/article/details/80009821 ...

  4. Java反编译的代码可以修改么

    一.Dubbo是什么? Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC(一种远程调用) 分布式服务框架(SOA),致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案. ...

  5. java JNI调用C++代码(给出一个简单java application示例和实际java web项目过程及错误解决)(一)

    一.简单java application示例篇 转载请注明:https://blog.csdn.net/xitie8523/article/details/79926948 本科毕业设计是图像分割相关 ...

  6. ROM-libcore中新加java文件编译报错

    背景: 1.安卓9之前,libcore中有一个libcore/io/EventLogger.java,但是安卓10之后却没有了 2.EventLogger可以将进程中所有的event事件,收敛到这里, ...

  7. eclipse安装JAVA反编译插件

    前言:在实际的开发中几乎都会使用到一些框架来辅助项目的开发工作,对于一些框架的代码我们总怀有一些好奇之心,想一探究竟,有源码当然更好了,对于有些JAR包中的代码我们就需要利用反编译工具来看一下了,下面 ...

  8. 学java用什么写比较好_学习Java需要什么基础,初学Java如何写好代码

    原标题:学习Java需要什么基础,初学Java如何写好代码 初学Java的同学时常会遇到这样的情况,跟着入门教程看过一遍,但需要自己写代码的时候却无从下手:写代码的时候时常会遇到不懂的地方,如果停下来 ...

  9. java源文件编译成jar_从源文件和JAR文件构建Java代码模型

    java源文件编译成jar 最近,我花了一些时间来研究有效java ,该方法正在GitHub上达到300星(可以免费帮助实现目标:D). Effectivejava是在您的Java代码上运行查询的工具 ...

  10. java反编译是什么_什么是Java代码的编译与反编译?

    Java代码的编译与反编译 2017-02-21 Hollis 数盟 一.什么是编译 1.利用编译程序从源语言编写的源程序产生目标程序的过程. 2.用编译程序产生目标程序的动作. 编译就是把高级语言变 ...

最新文章

  1. SQL Server数据库六种数据移动方法
  2. python找工作难吗-Python虽然很火,为啥找工作这么难?
  3. Spring boot模板引擎
  4. #25 centos7(RHEL)系列操作系统的启动流程、systemd的特性、与命令systemctl的使用...
  5. JavaScript稀疏数组
  6. 一步步构建大型网站架构(转载)
  7. linux uwsgi 非root,ubuntu-除非root用户,否则uWSGI Emperor权限被拒...
  8. 微信支付JAVA DEMO 微信支付爬过的坑
  9. mysql2000清除挂起工具,安装SQL提示挂起操作解决方法
  10. Matlab基础语法知识
  11. 微信百度网盘小程序文件分享Burp抓包获得链接和提取码
  12. python绘制国际象棋规则口诀_国际象棋口诀
  13. w3c怎么检测html5,HTML5教程:html标签属性通过w3c验证
  14. 《GPU编程与CG语言之阳春白雪下里巴人》 读书笔记2
  15. 异常恶毒的十二星座性格分析(转)
  16. 用JS 来简单计算一下现在距离9月10号还有几天几时几分几秒
  17. 移动通信:1G到5G发展过程简析 -- 什么是5G?
  18. 游戏玩家的饕餮盛宴:“天生BUFF”竞力狂飙
  19. (LeetCode)Java 求解正则表达式匹配
  20. WaitForSingleObject与事件、信号量、互斥、临界区的用法

热门文章

  1. 火车头采集器采集教程
  2. spark编程:DataFrame和SQL编程基础-2
  3. linux文件夹可视化工具,4款简单实用的的服务器文件管理工具推荐
  4. Unity3d FingerGestures
  5. unity3D的FingerGestures插件详细说明
  6. 关于2440嵌入式MPlayer播放器的移植方法
  7. Java之支付宝支付(电脑网站支付)案例实战
  8. php+bmp+加密,郁闷啊,谁知道BMP图片加密技术吗
  9. 2019年保研夏令营时间经验汇总
  10. excel双击后公式计算机,#电脑上的excel表格里的数字为什么要双击才能展开#excel文本双击后变数字...