对于一种可编程语言,是否必须基于上下文无关语法


23

实际上,对于最终可以被编译/转换为系统级指令的语言,是否有必要采用上下文无关的语法?

例如:所有编程/脚本语言都是上下文无关的语法吗?Java是基于CFG的,但是实际上所有编程语言都是基于CFG的吗?

它似乎不是强制性的,但是我的理解存在空白。

问题的上下文:我正在查看Java语言规范,该规范还提供了语法规则。这使我想到了这个问题。


1
通常,我认为只是您希望编译问题是可计算的,而解析CFG既好又容易。尽管我听到过一些说法,例如,识别有效的perl程序实际上是一个无法解决的问题。
Janne H. Korhonen

2
实际上,您真正需要的只是可确定的语法(所有CFG都是)。您还可以使编程语言的语法无法确定,但是当您输入错误时,编译器在试图确定其是否为有效语法时可能永远不会停止。这不是真正有用的
棘轮怪胎

@ratchet,您是否假定语法必须是递归可枚举的?
大卫·哈里斯

4
@JanneKorhonen:具体来说,不能静态解析Perl ,也就是说,如果不执行Perl ,就无法对其进行解析;由于上述执行可能是非终止的,因此静态解析Perl将意味着解决暂停问题。
乔恩·普迪

@janne我的意思是,后期预处理可能会带来可能无法计算的问题,通常情况下,验证程序所针对的最终语法是否与上下文无关。更具体地说,在进行后处理时,为了确定适合标记序列的规则,我们需要查看序列周围的其他标记。我不知道我是否有意义,对此感到抱歉。实际上我有点困惑。
sandeepkunkunuru

Answers:


20

两次没有

首先,大多数HPL不是上下文无关的。尽管它们通常具有基于CFG的语法,但它们也具有人们所谓的静态语义(这也经常包含在术语语法中)。这可以包括必须签出正确程序的名称和类型。例如,

class A {
  String a = "a";
  int b = a + d;
}

是语法上正确的Java程序,但由于d未定义且a没有合适的类型而无法编译。

其次,您可以解析非上下文无关的语言(编译器的存在证明了这一点)。通常,只有CFG可以有效地解析,而CSG通常无法解析。但是,您可以添加某些非上下文无关的功能,同时保持效率。

编译器通常分阶段运行:首先进行标记化(常规),然后进行无上下文解析,然后进行名称和类型分析(对上下文敏感,有时甚至更困难)。您可以通过收到的错误消息来观察该行为。


3
不要忘记public class Program { public static void main(String[] args) { ... } }... Java不会让您如此轻松。:-)
罗伊·廷克

从技术上讲,class A { ... }它足以javac编译您实际上无法执行的内容(由于缺少入口点)。但是,是的。
拉斐尔

20

6
我觉得这应该是Perl笑话的重点:)
Suresh Venkat

5
Suresh:我已经开过这个玩笑,尽管事实证明这不是一个很好的开玩笑,但我在SIGBOVIK 2011(sigbovik.org/2011/proceedings.pdf-第79页- 82)。
罗布·西蒙斯

1
注意:Perl解释器还不是不确定的,如果让任何人都感到舒服:)
Roy Tinker

15

我不认为Python的语法是上下文无关的。相同代码块中的行具有相同缩进量的要求不是上下文无关语法处理得很好的事情。

更准确地说,Python块形式的语言似乎具有同态性

如果条件:
     1号线
     2号线
     3号线
其他:
     4号线

到非上下文无关的语言,其中第一个零块来自第1行开始处的空格,第二个块来自第2行开始处的空格,第三个块来自第3行开始处的一组空格,其余行以及else等迫使第1行,第2行和第3行属于同一块。0n10n10n


4
严格来说你是对的,但是在编程语言的上下文中,我们尝试使上下文自由化,这是在称为标记化的预处理步骤之后产生的。我认为在此之前先检查缩进。
迭戈·德埃斯特拉达

7
是的,Python词法分析器(令牌生成器)具有一堆压痕深度。令牌流在每个块的开头都有一个INDENT符号,在结尾有一个DEDENT符号,可以用上下文无关的方式对其进行解析(INDENT和DEDENT的行为与C中的花括号非常相似)。C具有“不能告诉我们,如果声明或表达”的问题:是foo * bar;的声明foo为指针bar或乘法foobar
马克斯

8
好的,当然,但是您只是在词法分析器中隐藏了相同的复杂性,而不是像通常那样将其变成有限状态转换器。
David Eppstein

1
@DavidEppstein:公平地说,无论如何,复杂性都不是很好。
乔恩·普迪

1
除了在词法分析器中处理INDENT / DEDENT之外,Python还具有非常简单的LL(1)语法。
rmmh 2011年

13

Bodo Manthey和MartinBöhme表明,每个C ++编译器都必须是Turing完整的,也就是说,它可以在编译时计算任何部分递归函数。因此,这比上下文敏感要糟糕得多。

http://wwwhome.math.utwente.nl/~mantheyb/journals/BotEATCS_BoehmeManthey_CompilingCPP.pdf


是的,但是编译器绝不是上下文无关的语法。您应该讨论语法本身,而不是编译器。
杰夫·伯奇斯

@Jeff:我的答案中的“编译时间”表示“检查给定的C +源代码是否正确”。通过对本文结构的稍作修改,可以得出结论:可以将每种可决定的语言简化为所有正确的C ++程序的集合。
MarkusBläser2011年

7

我认为使用变量之前的声明和OOP语言的功能多态性是上下文无关语法无法处理的编程语言规范的其他示例:

int myfun(int a) { ... }
int myfun(int a, int b) { ... }
int myfun(int a, int b, int c, ...) { ... }
...
int I_m_I_cfg = myfun(1,2);
...

我做了一个小谷歌搜索,我发现这篇文章:一个布尔语法的简单布尔语由A.Okhotin(2004年); 据他介绍,真正的问题是找到一种用正式语法完全描述的编程语言:

定义了一种玩具程序编程语言,并 为使用该语言的格式良好的程序集构建了布尔语法。显然,这完全是形式语法对编程语言的第一个规范。

本文的简介部分很简短,但很清楚。


6

我相信C的语法在技术上仅是上下文无关的,因为解析器始终使用非上下文无关的技术来支持Duff的设备

基于缩进的语言自然也不像David所说的那样没有上下文,但是相对于参数化的缩进令牌而言,它们变得没有上下文。

Haskell使您可以使用infix和infixl更改运算符优先级。Perl的严格编译指示模块使用词法设置$ ^ H和%^ H来实现,这使其不是上下文无关的,可能还有其他设置。

有些宏扩展器语言(例如TeX)在其中不执行afaik解析就没有意义。

甚至可能有两个上下文无关的语法,它们的交集不是上下文无关的,但仍然描述了图灵机。

Java和汇编器可能自然都与上下文无关。


2
(a)-b使C上下文敏感不模糊吗?(a可能是变量,也可能是
typedef-

对于延迟的评论,我深表歉意,但Duff的装置没有任何语法上的偏差。大括号正确平衡。在有关C是否与上下文无关的讨论中,最常忽略的C功能是预处理器。我怀疑“上下文无关”的任何解释,无论是非正式的,都允许使用它来描述带有宏处理器甚至是性能良好的语言的语言。而且,C预处理程序表现得还算不错。
rici

4

不可以,许多实用语言不是没有上下文的。例如,C ++语法不是,因为在某些情况下语法解析取决于键入不是上下文无关的信息。


4

首先,让我区分编程语言的语法和语言本身。

许多语言的语法都是(至少基于)上下文无关文法(CFG),因为它们已经得到了很好的研究,并且有一些算法可以有效地解析CFG,并且可以特别处理CFG无法解决的边缘情况。

但是,实际上许多语言不是上下文无关的(例如,在java,C(++),D中使用使用前声明的符号时)。

有趣的事实:D具有图灵完备的编译时函数评估和模板扩展功能,这使得该语言本身无法确定图灵。但是,语言的创建者竭尽全力使语法成为CFG。


名称和类型分析通常执行固有的非上下文无关任务。
拉斐尔

C ++中的模板元编程已完成Turing。
杰夫·伯奇斯

3

至于“所有编程/脚本语言都是上下文无关的语法吗?” 关于部分,答案是肯定的。

关于“对于最终可以被编译/转换成系统级指令的语言”的主要问题,我不知道为什么它必须成为CFG。但是,可能会有更好的解释。


1
克里斯(Kris),能否举一些基于非上下文自由语法的编程语言的示例。我的意思是说,后期预处理可能会带来可能无法计算的问题,即验证程序所依据的最终语法。
sandeepkunkunuru 2011年

3

编程语言需要基于某种语法形式主义,其中CFG就是一个例子。虽然CFG是最常见的(并且是大学编译器课程中教的常识),但还有其他形式主义,例如解析表达式语法,您可以在此处(pdf)或Wikipedia上了解更多有关内容的内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.