对于上面的正规式 r,我们不难(?)写出:
A → HT H → ε | Ha | Hb T → abb 复制代码
过程:
通过观察,我们发现正规式 (a|b)*abb 是可以分为明显的两部分的,即a或b的星闭包连接上abb。第一部分就是星闭包,第二部分就是abb。因此,我们在构造 CFG 的时候,也就可以一上来就把开始符号拆成两部分,即上面第一行的 H 和T我们用前面的非终结符 H 来生成正规式中前半部分的星闭包。a或b的星闭包,就是由a或b构成的长度>=0的一个ab串,于是我们就可以通过 H 本身不限次引入 a、b 来构造星闭包,具体就是第二行的产生式。产生式 H->ε 的作用有二,一是为了满足只有空串的情况,因为星闭包可以为空;二是用来结束 H 的产生式,只有有了 ε,我们才能够结束对 H 的构造,否则这个推导会一路无限递归下去。。。T 就是给 abb 准备的
万一,如果 H 是正闭包而不是星闭包,那么就可以改成:H→a|b|Ha|Hb
正规式和 CFG 的关系
我们都知道:如果 NFA 能够接受一个串,那就说明在这个 NFA 内部一定存在一条从初态到终态的路径,路径上的链接就是这个串本身。
而,从上面的转化规则和例子,我们可以确定:这样的一个串一定对应CFG里面的一个推导。
也就是说,NFA 中的一个路径一定对应着 CFG 中的一个推导。反过来讲,CFG 中任意一个推导也都对应着 NFA 中的一个路径。
因此,正规式与 CFG 之间是等价的!!
任意一个正规式所描述的语言,都可用 CFG 来描述。也就是说对任意一个正规式,我们都可以为他构造出来其相应的、和它描述的语言相同的集合的 CFG。
但反过来,就不一定了——并不是所有用 CFG 描述的语言都可以用正规式来描述
好的,我已经很震撼了:既然凡是正规式能描述的,都能用CFG描述,反之则不行。这就说明 CFG 的语言描述能力更强。
可,为什么还用正规式,而非 CFG 来描述词法呢???
为毛不用 CFG 描述词法规则
原因很简洁:对人好,对机器也好。
对人好:正规式更直观简单,人容易理解。而正规式描述词法恰巧已经够用了(词法无非标识符、关键字、字面量之类,这些都是线性结构,使用正规式就能充分描述);
对机器好