从任何正则表达式生成上下文无关语法的算法

时间:2012-10-30 13:15:25

标签: regex algorithm nlp context-free-grammar computation-theory

任何人都可以为我勾勒出一种算法,可以将任何给定的正则表达式转换为一组等效的CFG规则吗?

我知道如何解决基本问题,例如(a | b)*:

S -> a A
S -> a B
S -> b A
S -> b B
A -> a A
A -> a B
A -> epsilon
B -> b A
B -> b B
B -> epsilon
S -> epsilon (end of string)

但是,我遇到了一些问题,将其形式化为适当的算法,特别是对于可以有许多嵌套操作的更复杂的表达式。

1 个答案:

答案 0 :(得分:12)

如果你只是从理论的角度谈论正则表达式,那么有以下三种结构:

ab       # concatenation
a|b      # alternation
a*       # repetition or Kleene closure

你可以做什么:

  • 创建规则S -> (fullRegex)
  • (x)*中的每个重复字词fullRegex创建规则X -> x XX -> ε,然后将(x)*替换为X
  • 每次更改(a|b|c)创建规则Y -> aY -> bY -> c,然后将(a|b|c)替换为Y

只需递归地重复此操作(请注意,所有x, abc仍然可以是复杂的正则表达式)。请注意,您当然必须为每个步骤使用唯一标识符。

这应该足够了。这肯定不会给出最优雅或最有效的语法,但这就是规范化的目的(它应该在一个单独的步骤中完成,并且有well-defined steps来执行此操作)。

一个例子:a(b|cd*(e|f)*)*

S -> a(b|cd*(e|f)*)*

S -> a X1; X1 -> (b|cd*(e|f)*) X1; X1 -> ε

S -> a X1; X1 -> Y1 X1; X1 -> ε; Y1 -> b; Y1 -> cd*(e|f)*

S -> a X1; X1 -> Y1 X1; X1 -> ε; Y1 -> b; Y1 -> c X2 (e|f)*; X2 -> d X2; X2 -> ε

... and a few more of those steps, until you end up with:

S  -> a X1
X1 -> Y1 X1
X1 -> ε
Y1 -> b
Y1 -> c X2 X3
X2 -> d X2
X2 -> ε
X3 -> Y2 X3
X3 -> ε
Y2 -> e
Y2 -> f