NFA为(a + b)?c

时间:2016-01-09 20:27:45

标签: regex nfa

我需要NFA用于正则表达式

(a+b)?c

据我所知,它应该包含从最后一个节点之前的零节点到节点的epsilon(例如,匹配字符串“c”)。

要查看我的NFA,请使用“Regular Expression to NFA Visializaton web service”, 但我的正则表达式在此服务上的图形不包含来自零节点的epsilon。

是服务中的错误,还是我误解了什么?

谢谢!

2 个答案:

答案 0 :(得分:4)

好像是一个错误。如果我尝试使用相同语言的(aa*b)?c,则NFA看起来非常不同(并且正确)。此外,当我尝试使用自动化库时,我不久前开发了自己,我得到了这个:

./fatool --in 're:^(a+b)?c$' --out dot:- | dot -Gdpi=70 -Tpng -onfa.png /dev/stdin NFA

如果您感兴趣,可以使用图书馆:https://github.com/wader/libfa

答案 1 :(得分:3)

这对我来说似乎是个错误。为了减少问题,a+?也失败了。

还有另一个错误,a|应该等同于a?,导致来自服务器的HTTP错误500.

扮演魔鬼的拥护者,他们有可能忽略某些案件,因为他们没有以常规语言关闭。如果他们接受表达式语言的一些非常规扩展,这将是可能的。

也许你的例子不是真正的常用语言。如果是这种情况,那么该工具可能正在按预期执行。也就是说,如果给出一个表示常规语言的正则表达式,那么它会产生一个识别该常规语言的NFA和DFA。但是,反过来可能不成立。

为了给这个回复增加更多的重量,我会证明你的例子确实是一种常规语言。

首先我们定义常规语言是什么。空ε和字母表的任何符号都是常规语言。如果xy是常规语言,则:连接x·y,选择x|y和重复x*是常规语言。

对于表示法,从最低到最高的优先级为:|·*。另外,我们添加通常的括号,它们具有最高优先级。 |·都是关联的,例如(a·b)·ca·(b·c)将被写为a·b·c

现在可以通过构建它来展示示例是常规语言。假设字母表包含'a','b'和'c'。为简洁起见,此演绎树未标记所使用的规则,但很容易推断出来。

    --
    a
--  --
a   a*
-----   --
 a·a*   b
----------   --
  a·a*·b     ε
 --------------   --
   (a·a*·b)|ε     c
 ------------------- 
    ((a·a*·b)|ε)·c

可以假定这些定义。

x+ ≡ x·x*
x? ≡ x|ε
xy ≡ x·y

然后通过使用定义,可以获得该示例。 +?的优先级与*相同。

((a·a*·b)|ε)·c
((a+·b)|ε)·c
((a+b)|ε)·c
(a+b)?·c
(a+b)?c

这不是了解常规语言的唯一方法。此外,我还没有定义构造语言中实际使用的单词,因此与您的示例等效是理所当然的 - 通过使用的约定我希望等效性足够明显。