【问题标题】:converting context free grammar into regular expression将上下文无关语法转换为正则表达式
【发布时间】:2014-05-24 12:54:12
【问题描述】:

我目前正在查看 CFG 并看到了答案,但我不确定他们是如何得到答案的。他们是怎么把它从这里的 CFG 转换成正则表达式的?

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


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

【问题讨论】:

  • 请注意,语法不仅是上下文无关的,而且是常规的。不可能将每个 CFG 都转换为正则表达式。

标签: regex context-free-grammar


【解决方案1】:

您应该学习我在回答"constructing an equivalent regular grammar from a regular expression" 中所写的基本规则,这些规则将帮助您将“正则表达式转换为左右衬里语法”或“左右衬里语法转换为正则表达式” - 两个都。

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

首先,要回答这样的问题,您应该清楚“这种语法生成的语言是什么?” (类似地,如果您有自动机,那么请尝试理解该自动机所代表的语言)。

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

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

(注意:a<sup>+</sup> 也可以写成a<sup>*</sup>aaa<sup>*</sup>——描述一个或多个'a'。)

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

如果您注意到 start-variable 的 S 生产规则:

S → aS | bX | a

那么很明显,语言中的字符串 ω 可以以符号 'a' 或以 'b' 开头(因为您有两种选择来应用 S 产生式(1)S → aS | a 给出'a'作为 ω 中的第一个符号,或 (2) S → bX 用于生成以符号 'b' 开头的字符串。

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

接下来请注意"b" ∉ L(G) 因为如果您使用苹果S → bX 则稍后您必须使用X 的一些生产规则替换sentential form bX 中的X,以及正如我们所知,X 也不能为空,因此在'b' 之后总会有一些符号——换句话说,来自bX 的感伤派生出 &mid;ω&mid; &geq; 2.

上面讨论的表格,很明显,使用S产生式规则可以生成a*aa*bX的句子形式,分两步:

  1. 对于a*,重复使用S → aS会得到S &amp;zigrarr; a*S(符号&zigrarr;表示不止一个步骤)

  2. S 替换为S &amp;zigrarr; a*S 的右侧,以通过a*aa*bX 获得

另外,“a*a or a*bX”可以写成S &amp;zigrarr; a*(a + bX)S &amp;zigrarr; (a*(a + bX)),如果你喜欢用括号括起来完整的表达式

现在比较SX的产生规则是一样的!因此,正如我在上面为S 显示的那样,您还可以为X 描述它可以用来生成句子形式X &amp;zigrarr; (a*(a + bY))

要导出答案中给出的正则表达式,将S &amp;zigrarr; a*(a + bX) 中的X 替换为(a*(a + bY)),您将得到:

S &amp;zigrarr; a*(a + b X ) S &amp;zigrarr; a*(a + b (a*(a + bY)) )

现在,最后一个Y 产生规则比较简单——只需使用创建“plus clouser”a<sup>+</sup>(或a*a)。

所以让我们替换Y 也以S 派生句形式。

S &amp;zigrarr; a*(a + b(a*(a + bY))) &amp;zigrarr; a*(a + b(a*(a + ba*a)))

简化它,两次应用低分布以删除内括号并连接正则表达式 - P(Q + R) 可以写成PQ + PR

&amp;zigrarr; a*(a + b(a*(a + ba*a))) &amp;zigrarr; a*(a + b(a*a + a*ba*a)) &amp;zigrarr; a*(a + ba*a + ba*ba*a)

: &plus;在正式语言的正则表达式中使用两种语法 (i) &plus;作为二元运算符的意思 - “联合运算” (ii) &plus;作为一元上标运算符的意思 - “加 clouser”
: 在编程语言的正则表达式中 + 仅用于“plus clouser”
: 在正则表达式中我们使用 &mid;联合符号,但 不是 完全是联合运算符。在联合中 (A ∪ B) 与 (B ∪ A) 相同,但在正则表达式中 (A &mid; B) 可能不等于 (B &mid; A)

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2021-06-29
      • 1970-01-01
      • 2016-04-11
      • 2017-09-02
      • 1970-01-01
      • 2012-02-03
      • 2023-03-14
      • 2016-05-02
      • 1970-01-01
      相关资源
      最近更新 更多