📜  正则表达式到 DFA

📅  最后修改于: 2022-05-13 01:57:01.605000             🧑  作者: Mango

正则表达式到 DFA

先决条件 – 有限自动机介绍

实用性——要从给定的正则表达式构造 DFA,我们可以首先为给定的表达式构造一个 NFA,然后通过子集构造方法将此 NFA 转换为 DFA。但是为了避免这个两步过程,另一种方法是直接为给定的表达式构造一个 DFA。

DFA 指的是确定性有限自动机。在 DFA 中,对于每个状态和每个输入符号,自动机可以从其当前状态转换到一个状态,并且只有一个状态。 DFA 不接受任何 ∈ 转移。

为了直接从正则表达式构造 DFA,我们需要遵循以下步骤:

示例:假设给定正则表达式 r = (a|b)*abb

1.首先,我们为给定的表达式构造增强的正则表达式。通过将唯一的右端标记“#”连接到正则表达式 r,我们在“#”上给出了 ra 转换的接受状态,使其成为 r# 的 NFA 的重要状态。

So, r' = (a|b)*abb#

2.然后我们为 r# 构建语法树。

(a|b)*abb# 的语法树

(a|b)*abb# 的语法树

3.接下来,我们需要评估四个可以为空的函数,firstpos、lastpos 和 followpos。

  1. 当且仅当由 n 表示的正则表达式在其语言中包含 € 时,nullable(n) 对语法树节点 n 为真。
  2. firstpos(n) 给出可以匹配由以 n 为根的子表达式生成的字符串的第一个符号的位置集。
  3. lastpos(n) 给出可以匹配由以 n 为根的子表达式生成的字符串的最后一个符号的位置集。

如果内部节点被连接标记,我们将其称为猫节点、或节点或星节点,|或 *运算符,分别。

计算 nullable、firstpos和 lastpos的规则:

Node nnullable(n)firstpos(n)lastpos(n)
n is a leaf node labeled €true  ∅
n is a leaf node labelled with position ifalse{ i } { i } 
n is an or node with left child c1 and right child c2nullable(c1) or nullable(c2)firstpos(c1) ∪ firstpos(c2)lastpos(c1) ∪ lastpos(c2)
n is a cat node with left child c1 and right child c2nullable(c1) and nullable(c2)If nullable(c1) then firstpos(c1) ∪ firstpos(c2) else firstpos(c1)If nullable(c2) then lastpos(c2) ∪ lastpos(c1) else lastpos(c2)
n is a star node with child node c1truefirstpos(c1)lastpos(c1)

计算规则如下:

1.如果 n 是一个具有左孩子 c1 和右孩子 c2 的猫节点,并且 i 是 lastpos(c1) 中的一个位置,那么 firstpos(c2) 中的所有位置都在 followpos(i) 中。

2.如果 n 是星节点并且 i 是 lastpos(n) 中的位置,则 firstpos(n) 中的所有位置都在 followpos(i) 中。

3.现在我们已经了解了计算 firstpos 和 lastpos 的规则,我们现在继续计算给定正则表达式 (a|b)*abb# 的语法树的相同值。

语法树中节点的 firstpos 和 lastpos for (a|b)*abb#

语法树中节点的 firstpos 和 lastpos for (a|b)*abb#

现在让我们为语法树中的每个节点计算 followpos 自下而上。

NODEfollowpos
1{1, 2, 3}
2{1, 2, 3}
3{4}
4{5}
5{6}
6

4.现在我们构造Dstates ,DFA D 和Dtran的状态集,D 的转换表。DFA D 的起始状态是 firstpos(root) ,接受状态是所有包含与 endmarker 符号关联的位置的状态# .

根据我们的示例,根的第一个位置是 {1, 2, 3}。设此状态为 A 并考虑输入符号 a。位置 1 和 3 用于 a,因此令 B = followpos(1) ∪ followpos(3) = {1, 2, 3, 4}。由于这个集合还没有见过,我们设置 Dtran[A, a] := B。

当我们考虑输入 b 时,我们发现在 A 中的位置中,只有 2 个与 b 相关联,因此我们考虑 set followpos(2) = {1, 2, 3}。由于这个集合之前已经见过,我们没有将它添加到 Dstates 中,而是添加了转换 Dtran[A, b]:= A。

对其他状态继续这样,我们到达下面的转换表。

 Input
Stateab
⇢ ABA
    BBC
    CBD
    DBA

这里,A 是开始状态,D 是接受状态。

5.最后我们为上面的转移表画出DFA。

最终的 DFA 将是:

(a|b)*abb 的 DFA

(a|b)*abb 的 DFA