说明:本系列文章介绍的算法均来自编译原理(龙书)一书,如果读者对代码没有兴趣,只想了解算法思路,完全可以阅读龙书相关章节内容,比我讲得清晰透彻。

序:

啃编译原理半年以来,任然徘徊在前4章,其间反反复复,时而不求甚解,时而略有所悟。其间接触到正则表达式,对其实现原理颇有兴趣,于是百度之、谷歌之,以求解惑。

先是搜索到不少国内发表的学术论文和各位大侠博客上的文章,后又通过文章链接中的链接找到一篇不错的老外写的文章,并附有源码,看完了其文章,基本上和编译原理(龙书)中介绍的先从正则表达式构造NFA,再将NFA转化为DFA,最后在优化、化简DFA的思路一样。而我在下载其代码后稍微看了一些片段,试运行了一下发现代码写的有BUG,内存释放有问题,略觉不爽。于是便想自写一个玩玩,但如若还按照从正则表达式到NFA,再从NFA到DFA的过程,又觉得重复别人的老路,参考别人的代码颇无趣味。

老外的文章和代码下载地址在这里:http://www.codeproject.com/Articles/5412/Writing-own-regular-expression-parser

于是翻看龙书第三章后半部分,看到有直接从正则表达式构造得到DFA的算法过程。觉得可以一试,于是就有了这篇系列文章,有了2个来星期的1000多行代码(含空行^_^)。

根据正则表达式构造最小DFA的过程,总结如下:

1 根据正则表达式构造抽象语法树T。

2 从T的根节点开始,进行深度优先遍历,对每一个节点计算该节点的4个函数:nullable, firstpos, lastpos, followpos。

3 从T的根节点N0开始,构建状态集列表LIST,开始时状态集链表LIST中只包含firstpos(N0)。

4 遍历LIST中的各个元素(开始的时候LIST中只有一个元素),假设当前遍历到第i个元素,LIST(I)是一个集合,集合中每个节点对应的输入字符是不一样的,按照输入字符对节点进行分组(例如代表字符a的分在一个组中,代表字符b的分在一个组中),对每个组中各个节点K计算followpos(K),followpos(K)也是一个集合,K可能不止一个,得到的结果可能是多个集合,将这多个集合合并为一个集合S。如果这个集合S在LIST中还没有出现过,则将这个集合S加入到LIST中。同时,不管S是否在LIST中出现过没有,都需要记录下转换过程:LIST(i)经过某个字符(前面分组过程依据的字符)到达集合S。就这样一边处理LIST链表,一边记录转换过程,直到LIST中的元素依次从头到尾都被处理完毕。

最后得到的LIST链表和所有转换过程记录就构成了一个有向图,实质上就是一个DFA(确定性有穷状态自动机)。

5 对得到的DFA进行最小化处理。

转载于:https://www.cnblogs.com/snake-hand/archive/2013/06/09/3129886.html

正则表达式引擎的构建——基于编译原理DFA(龙书第三章)——1 概述相关推荐

  1. 正则表达式引擎的构建——基于编译原理DFA(龙书第三章)——5 DFA最小化

    完整引擎代码在github上,地址为:https://github.com/sun2043430/RegularExpression_Engine.git DFA最小化的算法原理 "DFA状 ...

  2. 【编译原理】龙书第三章作业答案

    [编译原理]龙书第三章作业答案 练习3.1.1:根据3.1.2节中的讨论,将下面的C++程序划分成正确的词素序列.哪些词素应该有相关联的词法值?应该具有什么值? 答案: 左列为词素,右列为值,划分如下 ...

  3. 编译原理(龙书)学习笔记 第一章

    编译原理(龙书)学习笔记 第一章 1.1语言处理器 解释器(interpreter) : 编译器(compiler): 一个语言处理系统 练习 1.1.1:编译器和解释器之间的区别 1.1.2:相对优 ...

  4. 编译原理(龙书):第八章部分题目参考答案

    目录 8.2.2(1) 8.2.3 8.2.5* 8.2.6 8.3.3(1) 8.4.2 8.5.1 8.5.5 8.6.1* 8.6.4* 8.6.5* 8.9.1* 8.9.2* 以下题目答案源 ...

  5. 编译原理(龙书):第一章部分题目参考答案

    目录 1.1.1 1.1.2 1.1.3 1.1.4 1.6.1 1.6.3 1.6.4 1.1.1 What is the difference between a compiler and an ...

  6. 编译原理(龙书):第四章部分题目参考答案

    目录 4.2.1 4.2.2 4.2.3 4.3.1 4.4.1 4.4.3 4.4.4 4.5.1 4.6.2 4.6.5 4.6.6 4.7.4 4.7.5 4.2.1 4.2.2 4.2.3 4 ...

  7. 编译原理(龙书第二版)--怎么求FIRST集

    提示:建议先看例题,有不懂的地方再结合相应的文字部分. 怎么求FIRST集 什么是FIRST集?可以这么理解,first的意思是第一,首个的.所以FIRST集就是 " 箭头右侧首个终结符的集 ...

  8. 编译原理(龙书):第六章部分题目参考答案

    目录 6.1.1 6.1.2 6.2.1 (1) (3) 6.3.1 6.4.1 6.4.2 6.4.3 6.4.6 6.5.1 6.6.1 (2) 6.6.2 6.6.4 6.7.1 6.7.2 6 ...

  9. 编译原理 START 龙虎鲸书简介

    编译原理START-龙书虎书鲸书 什么是龙书虎书鲸书 龙书 英文名:<Compilers: Principles, Techniques, and Tools > 中文名:<编译原理 ...

最新文章

  1. htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体。
  2. phoenix数据类型,语法,方法
  3. android dialog 结构,Android 原生Dialog实现
  4. 编码gbk的不可映射字符_Python基础:编码表和字符的故事
  5. 【牛客 - 318L】彪神666(水题,半高精度,递推,trick)
  6. RSS Feed Generator for PHP (兼有podcast rss - iTunes )
  7. JSONArray传值的使用小结
  8. Import Changes from Direct3D 11 to Direct3D 12
  9. asp.net jquery.Ajax() 方法调用后台方法
  10. 物理、化学实验仪器与设备
  11. 使用大数据分析需避免哪些错误
  12. 第七次网页前端培训(JS)
  13. 计算机毕业设计django基于python智能在线考试阅卷系统(源码+系统+mysql数据库+Lw文档)
  14. 一张图理清SpringMVC工作原理
  15. 深南电国际油价期权对赌协议详解? 毁约?
  16. YouTube视频推荐系统
  17. NOTA-NHS ester,1338231-09-6,双功能配体的大环化合物
  18. Mac系统不能使用网银怎么办?Parallels帮你
  19. 服务器解决了什么问题、状态同步和帧同步
  20. cad修改快捷键_CAD入门学习技巧:CAD软件中的CAD快捷键的分类

热门文章

  1. 深拷贝与浅拷贝Object.assign()
  2. [react] 怎样在react中使用innerHTML?
  3. React开发(177):opentab没有menu会报错
  4. 深入react技术栈(1):React简介
  5. 前端学习(3130):react-hello-react之回调形式的createRef
  6. PS教程第十九课:移动工具
  7. [vue] 为什么我们写组件的时候可以写在.vue里呢?可以是别的文件名后缀吗?
  8. [css] 你有去看过或者了解过css的标准文档吗?
  9. 前端学习(2462):打包优化
  10. plsql轻量版异常机制