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

a b(c);

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

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

浏览“c++程序设计语言”的附录A,我找不到一条语法规则,它的左边除了一个非终结符之外,还有其他任何东西。这意味着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。

其他回答

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++标准中的结果是与上下文无关的,但正如我们所知,它并没有真正精确地定义语言。大多数人认为当前语言中的一些歧义可以(我相信)用上下文敏感的语法明确地解决。

对于最明显的例子,让我们考虑最恼人的解析:int f(X);。如果X是一个值,那么它将f定义为一个将用X初始化的变量。如果X是一个类型,它将f定义为一个接受单个类型X形参的函数。

从语法的角度来看,我们可以这样看:

A variable_decl ::= <type> <identifier> '(' initializer ')' ';'

B function_decl ::= <type> <identifier> '(' param_decl ')' ';'

A ::= [declaration of X as value]
B ::= [declaration of X as type]

当然,为了完全正确,我们需要添加一些额外的“东西”来解释其他类型的介入声明的可能性(即,A和B都应该是“声明,包括将X声明为…”,或者类似的顺序)。

这与典型的CSG还是有很大不同的(至少在我印象中是这样)。这取决于正在构造的符号表——即专门将X识别为类型或值的部分,而不仅仅是前面的某些语句类型,而是正确的符号/标识符的正确语句类型。

因此,我必须做一些研究来确定,但我的直接猜测是,这并不是真正的CSG,至少从通常使用的术语来看是这样的。

我感觉在“上下文敏感”的正式定义和“上下文敏感”的非正式使用之间存在一些混淆。前者有明确的含义。后者用于表示“为了解析输入,您需要上下文”。

这里也有一个问题: 上下文敏感性vs模糊性。

这是一个与上下文无关的语法:

<a> ::= <b> | <c>
<b> ::= "x"
<c> ::= "x"

它是模棱两可的,所以为了解析输入“x”,你需要一些上下文(或者忍受这种模棱两可,或者发出“警告:E8271 - input is ambiguous in line 115”)。但它肯定不是上下文敏感的语法。

要回答你的问题,你需要区分两个不同的问题。

几乎每一种编程语言的语法都与上下文无关。通常,它是作为扩展的Backus-Naur形式或上下文无关语法给出的。 然而,即使一个程序符合编程语言定义的上下文无关语法,它也不一定是一个有效的程序。为了成为一个有效的程序,程序必须满足许多与上下文无关的属性。例如,最简单的属性是变量的作用域。

综上所述,c++是否与上下文无关取决于你问的问题。