不要让这变得比它需要的更难。您的语言具有以下特点:
=
中间有个
- LHS 以 s 开头和结尾,中间
2
有2
s 和*
s
- RHS 只是
2
s
- LHS 和 RHS 上的
2
s 数量相等
- LHS 不包含
**
.
这些规则很容易放入语法中:
(P1) S -> 2=2
(P2) S -> 2S2
(P3) S -> 2*S2
第一条规则是我们的基本情况,并确定=
必须始终将LHS
and分开RHS
。它还规定LHS
必须以 a 结尾,2
并且 RHS 必须以 开头2
。
第二条和第三条规则允许我们添加更多2
的 s 以获得语言中更长的字符串。第二条规则说“你总是可以2
在 LHS 的前面放一个,如果你这样做,你必须在 RHS 的末尾放一个”。第三条规则允许我们放入*
LHS,只要我们在 RHS 上至少放一个 S”。
你的例子:
222*2*22=222222
S
2S2 P2
22S22 P2
222*S222 P3
222*2*S2222 P3
222*2*2S22222 P2
222*2*22=222222 P1
2*2*2=222
S
2*S2 P2
2*2*S22 P2
2*2*2=222 P3
2*222222*22=222222222
S
2*S2 P3
2*2S22 P2
2*22S222 P2
2*222S2222 P2
2*2222S22222 P2
2*22222S222222 P2
2*222222*S2222222 P3
2*222222*2S22222222 P2
2*222222*22=222222222 P1
该语法的正式正确性证明将涉及证明(a)生成该语言中的每个字符串,以及(2)生成的每个字符串都使用该语言。我们可以同时使用归纳法:
证明:通过归纳。基本情况:语言中最短的字符串是2=2
,由 P1 生成。没有更短的生成字符串。归纳假设:假设所有长度小于的字符串k
都在语言中生成(集合在长度之前是相同的k
)。归纳步骤:我们必须显示长度大于的字符串k
也是一致的。如果我们k
在语言中有一个长度或更长的字符串(或者,由语法生成),它必须是形式22x22
或2*x2
,其中x
另一个字符串是语言(或者,由语法生成)。的长度x
小于k
或此参数递归地应用于x
自身。由于x
长度小于k
,归纳假设意味着它可以由语法生成(或者,它在语言中);并且两种形式都可以生成(或者,在语言中),结果是:通过 P2 的两次应用和 P3 的一次应用(或者,通过语言本身的定义)。
更新:
有一条评论让我注意到,数量*
应该固定为 2。这需要更改语法的定义:
S -> 2S2 | 2*R2
R -> 2R2 | 2*T2
T -> 2T2 | 2=2
这以相对较小和可预测的方式改变了上述论点。基本上,我们跟踪 P3 的应用程序的数量,并在第二次之后禁止进一步的应用程序,同时仅在我们看到至少两个应用程序之后才允许消除所有非终结符。