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

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


序:

    啃编译原理半年以来,任然徘徊在前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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421729.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(JAVA)复制文件test.txt,并且排序。文件重新命名为test1.txt

//获取文件内的内容并排序public static void copyFile() throws Exception{//创建File 对象File sourece new File("/Desktop/pic/a.txt");//创建读字符流对象BufferedReader br new BufferedReader(new FileReader(sourece));//一次读取一行String str br.read…

C#如何使用httpwebrequest通过代理访问网页

string urlStr "http://www.itstrike.cn"; //设定要获取的地址 HttpWebRequest hwr (HttpWebRequest)HttpWebRequest.Create(urlStr); //建立HttpWebRequest对象 hwr.Timeout 60000; …

(JAVA)装饰流

package IODemo;/*** author Alina* date 2021年11月15日 11:48 下午* 设计思想:设计模式,装饰模式* JAVA中有23种设计思想,全部基于面向对象* 装饰设计模式,核心思想,解决什么问题* 增强原有对象的功能**/ //第一…

我的学习生涯(Delphi篇) - 21

我们平常要和图片打交道,那么我们如何把图片存在数据库中呢? -------------------------------------------------------------------------------------------------美丽分割线--------------------------- 年代:2007 文件:My091…

Map 的Properties集合存储IO流对象

package IODemo;import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties;/*** author Alina* date 2021年12月07日 11:29 下午* 集合IO一起使用* Map接口实现Hashtable 子类 Properties* 特点:线程安全,泛型Str…

WordPress的RSS订阅优化

一、确定一个永久的RSS地址 WordPress默认的订阅地址是www.domain.com/feed,使用这样的地址有三个比较大的缺陷: 1、无法统计多少人订阅了你。 2、博客更换域名或者被GFW后原RSS地址不能访问了,原来的读者群就流失了。 3、输出的内容太单调…

练习IO流

package IODemo;import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties; import java.util.Scanner;/*** author Alina* date 2021年12月08日 11:49 下午* 已知用户有一个文本文档,里面包含的键值对…

轻量级的ORM框架 fluentdata

codePlex 地址:http://fluentdata.codeplex.com/releases/view/82592转载于:https://www.cnblogs.com/Qiaoyq/archive/2013/06/11/3131428.html

(JAVA)线程

/*** author Alina* date 2021年12月12日 11:37 下午* 线程:分为三个级别* 1.定义类,继承Thread 类,继承线程类* 该类重写run()方法* 创建子类对象* * 执行join方法的线程,会一次执行完毕,其…

(JAVA)序列化

对象序列化与反序列化 对象中的数据有:new Object() 自己的成员变量 如果对象的基本数据不变,反复使用 什么是序列化 将对象中的数据以二进制方式存入硬盘,永久保存 二进制文件可以在网络上传输 反序列化 将存在硬盘中的二进制文件,读取出来还…

某final神犇的工作感想

http://hi.baidu.com/codemao/item/0bc294417fbaeceba5c06690  。。。 这一年,工作上也渐渐步入正轨了,首先,我很庆幸在我刚工作的时候就能碰到一个好的经理,我想,工作上最重要的事情莫过于跟对组,跟对经理…

(JAVA)线程之lock和死锁(例)

package thread; import java.util.concurrent.locks.*;/*** author Alina* date 2021年12月20日 11:07 下午* JDK5新特性* import java.util.concurrent.locks 包* lock接口* void lock() 获取锁,进同步* void unlock () 释放锁,出同步***/ c…

XML工作总结

XML文件使用 1webconfig webconfing有默认有缓存依赖,修改,则服务重启。JS三级联动XML处理导出。2asp.net站点地图3Soap WEB服务传输数据,Soap是有特殊数据的XML。本质是表单提交,Web服务response数据,表单要知道服…

c语言之计算两个数的大数

# include<stdio.h> //编译预处理指令 int main(){ //定义主函数int max (int x,int y);int a,b ,m; scanf("%d,%d",&a,&b);m max( a, b);printf("max is %d \n ",m);return 0 ;} int max(int x,int y){int c ;if (x>y){cx;}else{c y…