我目前正在阅读这本书"理解计算"作者:汤姆斯图尔特(顺便说一句,这本书很棒 - 它教会了我很多,对于像我这样缺乏正规数学培训但想要更好地理解计算机科学的人来说,这是一个非常宝贵的资源。强烈推荐!)我们谈到Context Free Grammar(CFG)。有一点特别关于CFG,我还没有能够开发出足够的心理模型 - 让我用一个例子来证明。
本书使用的是一个非常有限的CFG示例(为了简单起见),它只能处理您在完整编程语言中可能看到的非常严格的可能性子集(单个内容)引号代表标记,尖括号中的东西代表符号):
<statement> ::= <while> | <assign>
<while> ::= 'w' '(' <expression> ')' '{' <statement> '}'
<assign> ::= 'v' '=' <expression
<expression> ::= <less-than>
<less-than> ::= <multiply> '<' <less-than> | <multiply>
<multiply> ::= <term> '*' <multiply> | <term>
<term> ::= 'n' | 'v'
以下是一些如何使用我当前的心理模型的例子 - 我会大声朗读其中一些:
&#34;陈述可以是一个循环或一个分配&#34;
出于这个有限的例子的目的,这对我来说非常有意义。
&#34;术语可以是数字文字或变量&#34;
同样,鉴于范围有限,这对我来说非常有意义。
&#34;乘法可以是一个乘以另一个乘法或一个术语&#34;
好的,现在我吓坏了!我明白给出&#34; out&#34;允许少于成为乘法是潜在魔法的一部分,使整个事情发挥作用(即,它是我们的非确定性下推自动机能够探索每个可能的组合的机制),但逻辑上 - 在至少我读它的方式 - 我只是不能让它变得有意义。为什么会那样&#34; out&#34; (正如我所说)不仅仅是被推到了上一级 - 我的意思是:
<expression> ::= <less-than> | <multiply>
我们是否有某种原因需要检查它是否有效率低于第一,然后只检查它是否只有在我们确定它不是小于? / p>
答案 0 :(得分:0)
我认为答案与<less-than>
可嵌套有关。 <less-than>
可以是(<multiply>
&lt; <less-than>
),也可以是<multiply>
。
话虽这么说,理论上你可以在| <multiply>
中复制<expression>
但它只是变得多余。无论哪种方式,你都必须给<less-than>
一个&#34; out&#34;正如你所描述的那样,当没有(&lt; {{}}}延续时。
例如,问题中定义的语法对以下内容有效:
<less-than>
你得到(如果你原谅XML表示法,那是我能想出的最好的说明我的观点):
v=n<v
但是如果你没有用<statement>
<assign>
v
=
<expression>
<less-than>
<multiply><term>n</term></multiply>
<
<less-than>
<multiply><term>v</term></multiply>
</less-than>
</less-than>
</expression>
</assign>
</statement>
定义<less-than>
,那么最后的&#34; v&#34;上面(| <multiply>
)不满足语法中的任何定义(更好的是定义<multiply><term>v</term></multiply>
永远不会结束!)
答案 1 :(得分:0)
如果你写
a * b + c
或者,就此而言
c + a * b
你可能意味着c的总和以及a和b的乘积。如果在第一个表达式中你的意思是a的乘积和b和c的总和,你会使用括号:
a * (b + c)
我们如何在CFG中表达这一点?我们需要说一个总和可以是一个带有产品的加号。但不仅仅是一种产品:它也可以是取幂,或分裂,或者当然是变量或数字。或括号中的任何表达。
此外,乘法和加法是关联的,但并非所有数学运算符都是关联的。例如,9 - (5 - 2)与(9 - 5) - 2不同,按照惯例,9 - 5 - 2被认为是第二个。所以减法可以在右边有另一个减法,但不在左边(除非用括号括起来。)
类似的观察适用于比较。在以下内容中:
a + b < 3 * c
目的是将太阳与产品进行比较,而不是对比较结果进行算术运算。