将无上下文语法转换为正则表达式

时间:2014-04-10 17:01:36

标签: regex context-free-grammar

我目前正在讨论CFG并看到答案,我不确定他们是如何得到的。他们是如何让它从CFG转换为正则表达式的?

S -> aS|bX|a
X -> aX|bY|a
Y -> aY|a


answer:
R.E -> (a*(a+ba*a+ba*ba*a))

2 个答案:

答案 0 :(得分:4)

你应该学习我在答案"constructing an equivalent regular grammar from a regular expression"中所写的基本规则,这些规则将帮助你将“正则表达式转换成右或左线性语法”或“将右边或左边的线性语法转换为常规表达“ - 两者。

尽管如此,语言可以使用多个正则表达式(和语法/自动机)。下面,我试图解释如何在教科书中找到答案中给出的正则表达式。准确阅读每个步骤并链接答案,以便您可以学习下次自己解决此类问题的方法。

第一步,回答这个问题你应该清楚“这个语法产生什么语言?” (同样,如果你有一个自动机,那么试着理解那个自动机所代表的语言)。

正如我在链接答案中所说的那样,语法规则如:S → eS | e对应于“plus clouser”并生成字符串e+。同样,你有三对这样的规则来在你的语法中生成a+

S → aS | a   
X → aX | a  
Y → aY | a    

(注意:a+也可以写成a*aaa* - 描述一个或多个'a'。)

另外注意语法,你没有任何“空产”,例如A → ∧,因此非变量SXY可以为空,这意味着空字符串不是语法语言的成员,如:ε∉L (G)。

如果您注意到起始变量的S制作规则:

S → aS | bX | a

然后很明显,语言中的字符串ω可以用符号'a''b'开头(因为你有两个选择来应用S作品(1){{ 1}},它将S → aS | a作为ω中的第一个符号,或者(2)'a'用于生成以符号S → bX开头的字符串。

现在,L(G)中可能的最小长度串ω是多少? - 使用生产规则可以使用最小长度字符串'b'"a"

接下来请注意S → a∉L(G),因为如果您申请"b",那么稍后您必须使用某些内容替换sentential form S → bX中的X bX的生产规则,并且我们知道X也不可为空,因此X之后总会有一些符号 - 换言之'b'的情感} derives |ω|≥2。

通过上述讨论形式,非常清楚的是,使用bX制作规则,您可以分两步生成句子形式Sa*a

  1. a*bX反复使用a*S → aS(符号⇝表示多个步骤)

  2. S ⇝ a*S的rhs中的S替换为S ⇝ a*Sa*a

  3. 此外,如果您想要将完整表达式括号,则“a*bXa*a”可以写为a*bXS ⇝ a*(a + bX)

    现在比较S ⇝ (a*(a + bX))S的生产规则都是相同的!正如我在上面针对X所示,您还可以为S描述它可用于生成句子形式X

    要导出X ⇝ (a*(a + bY))X的答案替换(a*(a + bY))中给出的正则表达式,您将得到:

    S ⇝ a*(a + bX)  
    S ⇝ a*(a + b X )

    现在,最后的S ⇝ a*(a + b (a*(a + bY)) )制作规则相对来说非常简单 - 只需用来创建“加号”Y(或a+)。

    因此,我们也可以在a*a派生的句子形式中替换Y

    S   
    S ⇝ a*(a + b(a*(a + bY)))

    简化它,将分布低两次以移除内括号并连接正则表达式 - ⇝ a*(a + b(a*(a + ba*a)))可写为P(Q + R)

    PQ + PR     
      ⇝ a*(a + b(a*(a + ba*a)))     
      ⇝ a*(a + b(a*a + a*ba*a))
    

    +正式语言中的正则表达式中使用两种语法(i)+作为二元运算符意味着 - “联合运算”(ii)+作为一元上标运算符意味着 - “加上clouser“
    编程语言中的正则表达式+仅用于“加上缓冲区”
    在正则表达式中,我们使用|符号作为union,但不是正是一个联合运算符。在联合(A∪B)与(B∪A)相同但在正则表达式(A | B)中可能不等于(B | A)

答案 1 :(得分:2)

从问题中您可以观察到的是,除了成为CFG之外,语法也是线性的。因此,您可以为此线性语法构造一个有限的自动机。现在,您已经构造了有限自动机,它们存在一个具有相同语言的正则表达式,并且可以使用this site中给出的步骤来完成转换。