从正则表达式构造ε-NFA

来自 vczh

?

1:字符集

?
?

字符集是正则表达式最基本的元素,因此反映到状态图上,字符集也会是构成状态图的基本元素。对于字符集C,如果有一个规则只接受C的话,这个规则对应的状态图将会被构造成以下形式:

?
?

?
?

这个状态图的初始状态是Start,结束状态是End。Start状态读入字符集C跳转到End状态,不接受其他字符集。

?
?

2:串联

?
?

如果我们使用A⊙B表示规则A和规则B的串联,我们可以很容易的知道串联这个操作具有结合性,也就是说(A⊙B)⊙C=A⊙(B⊙C)。因此对于n个规则的串联,我们只需要先将前n-1个规则进行串连,然后把得到的规则看成一个整体,跟最后一个规则进行串联,那么就得到了所有规则的串联。如果我们知道如何将两个规则串联起来的话,也就等于知道了如何把n个规则进行串联。

?
?

为了将两个串联的规则转换成一个状态图,我们只需要先将这两个规则转换成状态图,然后让第一个状态的结束状态跳转到第二个状态图的起始状态。这种跳转必须是不读入字符的跳转,也就是令这两个状态等价。因此,第一个状态图跳转到了结束状态的时候,就可以当成第二个状态图的起始状态,继续第二个规则的检查。因此我们使用了ε边连接两个状态图:

?
?

3:并联

?
?

并联的方法跟串联类似。为了可以在起始状态读入一个字符的时候就知道这个字符可能走的是并联的哪一些分支并进行跳转,我们需要先把所有分支的状态图构造出来,然后把起始状态连接到所有分支的起始状态上。而且,在某个分支成功接受了一段字符串之后,为了让那个状态图的结束状态反映在整个状态图的结束状态上,我们也把所有分支的结束状态都连接到大规则的结束状态上。如下所示:

?
?

4:重复

?
?

对于一个重复,我们可以设立两个状态。第一个状态是起始状态,第二个状态是结束状态。当状态走到结束状态的时候,如果遇到一个可以让规则接受的字符串,则再次回到结束状态。这样的话就可以用一个状态图来表示重复了。于是对于重复,我们可以构造状态图如下所示:

?
?

5:可选

?
?

为可选操作建立状态图比较简单。为了完成可选操作,我们需要在接受一个字符的时候,如果字符串的前缀被当前规则接受则走当前规则的状态图,如果可选规则的后续规则接受了字符串则走后续规则的状态图,如果都接受的话就两个图都要走。为了达到这个目的,我们把规则的状态图的起始状态和结束状态连接起来,得到了如下状态图:

?
?

?
?

如果重复使用的是0次以上重复,也就是原来的重复加上可选的结果,那么可以简单地把图4.4的Start状态去掉,让End状态同时拥有起始状态和结束状态两个角色,[Start]和[End]则保持原状。

?
?

至此,我们已经将5种构造状态图的办法都对应到了5种构造规则的办法上了。对于任意的一个正则表达式,我们仅需要把这个表达式还原成那5种构造的嵌套,然后把每一步构造都对应到一个状态图的构造上,就可以将一个正则表达式转换成一个ε-NFA了。

?
?

?
?

从正则表达式构造ε-NFA

时间: 2024-11-07 13:37:13

从正则表达式构造ε-NFA的相关文章

编译原理-第三章 词法分析-3.7 从正则表达式到自动机-从正则表达式构造NFA

基于MYT算法从正则表达式构造NFA 基本思想: 性质: 对于加括号的正则式(s),使用N(s)本身作为它的NFA 一.构造识别ε和字母表中一个符号的NFA 1.特点 仅一个接受状态,它没有向外的转换 2.示例 二.构造识别主算符为选择正则式的NFA 1.特点 仅一个接受状态,它没有向外的转换 2.示例 三.构造识别主算符为连接正则式的NFA 1.特点 仅一个接受状态,它没有向外的转换 2.示例 四.构造识别主算符为闭包正则式的NFA 1.特点 仅一个接受状态,它没有向外的转换 2.示例 五.例

从正则表达式到 NFA 到 DFA 到最简 DFA (二)

从正则表达式到 NFA 到 DFA 到最简 DFA (二) NFA $ \rightarrow $ DFA (子集构造法) 这里我们用一个例子来解释. 如上图所示,这是上一篇文章中的正则表达式化成的 NFA,这里拿来接着用. 我们首先看开始状态 n0.n0 在接收了一个字符 a 之后可以转换到 n1,这个时候我们要看 n1 是否存在 $ \varepsilon $ 转移.若存在,则递归的将所有能 $ \varepsilon $ 转移的状态添加到一个集合里(包括 n1).然后再看我们所创造的这个集

java实现正则表达式到NFA的转换

我用java实现了一个正则表达式到NFA的转换程序,以下是我的代码 package com.siwanghu.regextoNFA; public class Node {     private int id;     private static int ID=0;          public Node(){      this.id=ID++;     } public int getId() { return id; } public static void reset(){ ID=

从正则表达式到 NFA 到 DFA 到最简 DFA (三)(结束)

从正则表达式到 NFA 到 DFA 到最简 DFA (三) DFA $ \rightarrow $ 最简 DFA (Hopcroft 算法) 这是一个基于等价类的算法. split(S) foreach char c if c 能切分 S split S into T1, T2, ..., TK hopcroft() split all nodes into N, A(即非接收状态和接收状态) while (set is still changing) split(N/A) 这里的等价类,通俗来

编译原理 词法分析

原文地址:编译原理 词法分析 编译原理 词法分析 词法分析的主要任务是从左至右逐个字符地对源程序进行扫描,产生一个个单词序列,用于语法分析. 1.正则表达式 对给定的字符集∑={c1,c2,...,cn},归纳定义: 1.空串ε是正则表达式 2.对于任意c∈∑,c是正则表达式 3.如果M和N是正则表达式,则下列表达式也是正则表达式 (1)选择 M|N={M,N} (2)连接 MN={mn|m∈M,n∈N} (3)闭包 M*={ε,M,MM,MMM,...} 2.正则表达式的扩展 (1)[c1-c

编译原理pdf

下载地址:网盘下载 内容简介  · · · · · · 本书全面.深入地探讨了编译器设计方面的重要主题,包括词法分析.语法分析.语法制导定义和语法制导翻译.运行时刻环境.目标代码生成.代码优化技术.并行性检测以及过程间分析技术,并在相关章节中给出大量的实例.与上一版相比,本书进行了全面的修订,涵盖了编译器开发方面的最新进展.每章中都提供了大量的系统及参考文献. 本书是编译原理课程方面的经典教材,内容丰富,适合作为高等院校计算机及相关专业本科生及研究生的编译原理课程的教材,也是广大技术人员的极佳参

基于ε-NFA的正则表达式引擎

正则表达式几乎每个程序员都会用到,对于这么常见的一个语言,有没有想过怎么去实现一个呢?乍想一下,也许觉得困难,实际上实现一个正则表达式的引擎并没有想像中的复杂,<编译原理>一书中有一章专门讲解了怎么基于状态机来构建基本的正则表达式引擎,讲这个初衷是为词法分析服务,不过书里的东西相对偏理论了些,实现起来还是要费些功夫的,只是它到底指明了一条路,当然,书里只针对基本的语法进行了分析讲解,对于在实际中有些非常有用的很多扩展语法,它就基本没有涉及了,这些扩展的语法中有些是比较好实现的,有些则很难. 基

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

阅读博客的朋友可以到我的网易云课堂中,通过视频的方式查看代码的调试和执行过程: http://study.163.com/course/courseMain.htm?courseId=1002830012 上一节,我们通过代码,实现了一个有限状态自动机,并将其应用于对整形和浮点数的识别.构造有限状态自动机,并驱动它,从而实现对输入字符串的识别,整个过程就是词法分析的本质. 上一节所开发的状态机,基于以下模型: 这个模型,是我们在代码中,手动写入程序的.实则上,它对应着一组正则表达式: D    

南瓜不说话(M01)-正则表达式原理

文法 一个文法可以用一个四元来定义,G = {Vt,Vn,S,P} Vt:一个非空有限的符号集合,它的每个元素称为终结符号; Vn:一个非空有限的符号集合,它的每个元素称为非终结符号,并且Vt∩Vn=Φ; S∈Vn,称为文法G的开始符号; P是一个非空有限集合,它的元素称为产生式; 产生式是指,其形式为α→β,α称为产生式的左部,β称为产生式的右部,符号"→"表示"定义为",并且α.β∈(Vt∪Vn)*,α≠ε,即α.β是由终结符和非终结符组成的符号串; 开始符S必