如何将常规语法转换为正则表达式?

时间:2012-01-17 16:20:41

标签: regex compiler-construction bnf

是否有将常规语法转换为正则表达式的算法或工具?

3 个答案:

答案 0 :(得分:1)

来自dalibocai的答案:

我的目标是将常规语法转换为DFA。最后,我找到了一个很好的工具:JFLAP

答案 1 :(得分:1)

如果您可以从正则表达式计算自动机,则该算法非常简单。一旦你有自动机。例如对于(aa*b|c),自动机将是(箭头向右):

          a
         / \
      a  \ / b
-> 0 ---> 1 ---> 2 ->
    \___________/
          c

然后只需将您的过渡“枚举”为规则。下面,考虑0,1和2是非终结符号,当然a,b和c是标记。

0: a1 | c2
1: a1 | b2
2: epsilon

或者,如果你不想要空的右手边。

0: a1 | c
1: a1 | b

当然,另一个方向的路径提供了一种将常规语法转换为自动机的方法,因此是一种理性表达。

答案 2 :(得分:1)

从理论的角度来看,解决这个问题的算法的工作原理是根据语法中的每个规则创建一个正则表达式,并求解初始符号的结果方程组。

例如,对于正则语法({S,A},{a,b,c},P,S)

P:
   S -> aA | cS | a  | c
   A -> aA | a  | bS
  1. 取每个非终结符并从右手边生成正则表达式:

    S = aA + cS + a + c
    A = aA + bS + c
    
  2. 求解初始符号 S 的方程组:

    A = a(aA + bS + c) + bS + c
    A = a⁺bS + a⁺c + bS + c  
    
    S = aA + c(aA + cS + a + c)
    S = aA + c⁺aA + c⁺a + c⁺
    
    S = a(a⁺bS + a⁺c + bS + c) + c⁺a(a⁺bS + a⁺c + bS + c) + c⁺a + c⁺
    S = a⁺bS + a⁺c + c⁺a⁺bS + c⁺a⁺c + c⁺a + c⁺
    
    S = (c⁺ + ε)a⁺bS + a⁺c + c⁺(a⁺c + a + ε)
    
    substitution: x = (c⁺ + ε)a⁺b
    
    S = x(xS + a⁺c + c⁺(a⁺c + a + ε)) + a⁺c + c⁺(a⁺c + a + ε)
    S = x⁺a⁺c + x⁺c⁺(a⁺c + a + ε) + a⁺c + c⁺(a⁺c + a + ε)
    S = x*(a⁺c + c⁺(a⁺c + a + ε))
    
    S = ((c⁺ + ε)a⁺b)*(⁺a⁺c + c⁺(a⁺c + a + ε)) 
    

因为所有的修改都是等价的,所以 ((c⁺ + ε)a⁺b)*(⁺a⁺c + c⁺(a⁺c + a + ε)) 是一个正则表达式,相当于所有可以从初始符号产生的单词。因此这个表达式的值必须等价于由初始符号为 S 的文法生成的语言。

它不是漂亮,但我有目的地选择了一种包含循环的语法来描绘算法的工作方式。最难的部分是认识到 S = xS | x 等价于 S = x⁺,然后只需进行替换即可。