我经常听到有人说c++是一种上下文敏感的语言。举个例子:

a b(c);

这是变量定义还是函数声明?这取决于符号c的含义。如果c是一个变量,则ab (c);定义一个名为b的类型为a的变量。它直接用c初始化。但如果c是类型,则ab (c);声明一个名为b的函数,该函数接受c并返回a。

如果您查找上下文无关语言的定义,它基本上会告诉您,所有语法规则的左侧必须恰好包含一个非终结符。另一方面,上下文敏感语法允许在左侧使用任意的终结符和非终结符字符串。

浏览“c++程序设计语言”的附录A,我找不到一条语法规则,它的左边除了一个非终结符之外,还有其他任何东西。这意味着c++是上下文无关的。(当然,每一种与上下文无关的语言也是与上下文相关的,因为与上下文无关的语言构成了与上下文相关的语言的一个子集,但这不是重点。)

那么,c++是上下文无关的还是上下文敏感的?


当前回答

你可能想看看Bjarne Stroustrup写的《c++的设计与进化》。在这篇文章中,他描述了他在尝试使用yacc(或类似的)来解析早期版本的c++时遇到的问题,并希望他当时使用的是递归下降。

其他回答

首先,你正确地观察到c++标准末尾的语法中没有上下文敏感的规则,因此语法与上下文无关。

然而,这种语法并不能精确地描述c++语言,因为它生成的是非c++程序,例如

int m() { m++; }

or

typedef static int int;

c++语言被定义为“一组格式良好的c++程序”,它不是与上下文无关的(可以证明,仅仅要求声明变量就可以做到这一点)。理论上,您可以在模板中编写图灵完备程序,并根据其结果使程序具有病态形式,因此它甚至不是上下文敏感的。

现在,(无知的)人们(通常不是语言理论家,而是解析器设计者)通常在以下一些含义中使用“not context-free”

模棱两可的 不能用Bison解析 而不是LL(k) LR(k) LALR(k)或任何他们选择的解析器定义的语言类

标准后面的语法不满足这些类别(即它是模糊的,不是LL(k)…),所以c++语法对他们来说“不是上下文无关的”。从某种意义上说,他们是对的,要创建一个工作的c++解析器是非常困难的。

注意,这里使用的属性只与上下文无关的语言有微弱的联系——歧义与上下文无关没有任何关系(事实上,上下文敏感的规则通常有助于消除歧义),另外两个只是上下文无关语言的子集。解析与上下文无关的语言不是一个线性过程(尽管解析确定性语言是)。

c++模板已经被证明是图灵强大的。虽然不是正式的参考资料,但从这方面来看,我们可以从以下几个方面入手:

http://cpptruths.blogspot.com/2005/11/c-templates-are-turing-complete.html

我大胆地猜测一下(古老的民间和简明的CACM证明表明,60年代的ALGOL不能用CFG表示),并说c++因此不能仅用CFG正确地解析。cfg与各种TP机制结合在一起,无论是在树通道还是在减少事件中——这是另一个故事。一般来说,由于停止问题,存在一些c++程序不能被证明是正确的/不正确的,但仍然是正确的/不正确的。

{PS-作为Meta-S的作者(上面有几个人提到过),我可以很肯定地说Thothic并没有消失,也不是免费的软件。也许我这样回答是为了不被删除或被投票降至-3。

Meta-S”是Quinn Tyler Jackson开发的上下文敏感解析引擎。我没有用过,但他讲了一个令人印象深刻的故事。在comp.compilers中查看他的评论,并查看rnaparse.com/MetaS%20defined.htm - Ira Baxter 7月25日10:42

正确的环节是解析谜题

Meta-S是一家已经倒闭的tho栖公司的财产。我可以将Meta-S的免费副本发送给任何感兴趣的人,我已经在rna解析研究中使用了它。请注意,示例文件夹中包含的“伪结语法”是由一个非生物信息学的、成熟的程序员编写的,基本上不起作用。我的语法采用了一种不同的方法,而且效果很好。

c++不是上下文无关的。我以前在编译器课上学过。快速搜索得到了这个链接,其中“语法或语义”部分解释了为什么C和c++不是上下文无关的:

维基百科演讲:上下文无关语法

眼神, Ovanes

真正的:)

斯坦利·沃福德。计算机系统。页341 - 346。