多正则匹配引擎(二)

实现思路

正则的实现, 偏向功能丰富的话,应该用NFA 的, 偏向高效的话应该用 DFA的。
对多正则来说,很多正则一起计算, 貌似要考虑性能。
我们采用混合模式。
单个正则编译成NFA, 合成出一个大DFA 表示所有正则
但是不可避免地, 这会引起DFA 状态膨胀, 我们做了一定妥协解决问题。

单个正则的NFA

这又分几种实现方法,我们不采用中规中矩的实现, 采用一种非回溯的 虚拟机实现。这个表面上看是以指令为主的虚拟机,实质还是NFA, 但比NFA 好理解。
我们选用老牌的 PikeVM, 其java 版本非常简洁,方便我们扩充。其实用re2 也没有问题。

所有正则的DFA

我们对每个正则生成 VM, 然后转换成正规的NFA,转换成DFA(并极小化), 然后合成一个总的DFA。
我们匹配过程是DFA用来召回正则的ID, 详情还是要用VM 再次匹配。因此为了抑制状态数膨胀,我们转换过程舍弃了准确性

指令优化

对 一些指令,如 环视,group位置保存等,直接转换成epsilon,相当于忽略掉了。

边的优化

一个状态下如果有大量的边指向另一个状态,如 任意字符, 一些否定字符等,是导致状态膨胀的元凶。 我们一律优化为只有一条边(值为-1,表示任意字符)

DFA 的整体优化

在将大量 DFA 合成 总DFA时,虽然有上述优化,还是有可能状态膨胀到无法完成。 这时候我们将总的状态设置一个上限,超出上限后,不再继续合成总DFA 状态, 而是将原始DFA 中 剩余的DFA 状态保留起来, 匹配时特殊处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值