您应该学习我在回答"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>a 或aa<sup>*</sup>——描述一个或多个'a'。)
还要注意语法,你没有任何“空产生”,例如A → ∧,因此变量S、X 或Y 的非可为空的,这意味着空字符串不是语法语言的成员,如:ε ∉ 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 的感伤派生出 ∣ω∣ ≥ 2.
上面讨论的表格,很明显,使用S产生式规则可以生成a*a或a*bX的句子形式,分两步:
对于a*,重复使用S → aS会得到S &zigrarr; a*S(符号⇝表示不止一个步骤)
将S 替换为S &zigrarr; a*S 的右侧,以通过a*a 或a*bX 获得
另外,“a*a or a*bX”可以写成S &zigrarr; a*(a + bX) 或S &zigrarr; (a*(a + bX)),如果你喜欢用括号括起来完整的表达式✎。
现在比较S和X的产生规则是一样的!因此,正如我在上面为S 显示的那样,您还可以为X 描述它可以用来生成句子形式X &zigrarr; (a*(a + bY))。
要导出答案中给出的正则表达式,将S &zigrarr; a*(a + bX) 中的X 替换为(a*(a + bY)),您将得到:
S &zigrarr; a*(a + b X )
S &zigrarr; a*(a + b (a*(a + bY)) )
现在,最后一个Y 产生规则比较简单——只需使用创建“plus clouser”a<sup>+</sup>(或a*a)。
所以让我们替换Y 也以S 派生句形式。
S &zigrarr; a*(a + b(a*(a + bY)))
&zigrarr; a*(a + b(a*(a + ba*a)))
简化它,两次应用低分布以删除内括号并连接正则表达式 - P(Q + R) 可以写成PQ + PR。✞
&zigrarr; a*(a + b(a*(a + ba*a)))
&zigrarr; a*(a + b(a*a + a*ba*a))
&zigrarr; a*(a + ba*a + ba*ba*a)
✎ : +在正式语言的正则表达式中使用两种语法 (i) +作为二元运算符的意思 - “联合运算” (ii) +作为一元上标运算符的意思 - “加 clouser”
✎ : 在编程语言的正则表达式中 + 仅用于“plus clouser”
✞ : 在正则表达式中我们使用 ∣联合符号,但 不是 完全是联合运算符。在联合中 (A ∪ B) 与 (B ∪ A) 相同,但在正则表达式中 (A ∣ B) 可能不等于 (B ∣ A)