JavaScript是一种上下文无关语言吗?

时间:2015-06-07 18:52:48

标签: javascript context-free-grammar formal-languages

这篇关于how browsers work的文章解释了CSS如何无上下文,而HTML 不是。但是JavaScript呢,JavaScript上下文是免费的吗?

我正在学习CFG和正式证明,但距离理解如何解决这个问题还有很长的路要走。有没有人知道JavaScript是否没有上下文?

3 个答案:

答案 0 :(得分:15)

不,JavaScript不是一种无上下文的语言。

非常接近1,ECMAScript 5规范确实use a context-free grammar 1 来描述语言的语法(您可以在Annex A中找到所有产品)。< / p>

当然,它确实对纯无上下文语法产生做了一些扩展,并描述了解析器的额外行为。一个特别的事情是lookahead的使用仍然使得无上下文的语言,但如果它不能用于某些规则会使语法复杂化。不允许某些事物出现在严格模式代码中是相似的 - 它可以通过调整语法(具有更多的产品)来完成,但是通过离开BNF可以更容易地表达规则。

但是,也有一些 2 规则确实使语言不具有上下文。您将在description of early errors中找到概述,这可能会使程序代码无效。该对象文字不能包含重复的属性名称,并且函数参数列表不能包含重复标识符是两个不能使用(有限)无上下文语法表达的规则。
我的直觉告诉我the automatic semicolon insertion落在同一个盒子里,但我认为它的规则太复杂了,甚至不能在这里尝试证明。

1:实际上它使用了两个语法,一个lexical和一个syntactical,其中第一个是分词表达式和正则表达式之间的歧义,并且确实产生了作为输入的标记。第二个语法。
2:与其他编程语言

相比,实际上相当少

答案 1 :(得分:6)

没有编程语言(完全)没有上下文(我想说包括CSS)。尽管可以使用无上下文语法(CFG)来定义/生成该语言的编译器/解析器。

变量需要首先定义,使用之前,或者涉及标识符的声明应该是唯一的简单事实(例如)使语言成为&#34 ; 上下文敏感&#34;

(编程)语言的语法应该描述(并生成)仅使用该语言中的有效程序的字符串(语法上,但也可以是语义上的)。然而,CFG可以描述和生成不是有效程序的字符串(给定语言语义和规范)。描述有效程序的条件(例如:1。class需要在使用new class()之前定义,ids必须匹配等。)需要context-sensitivity

没有CFG(包含任何有限数量的作品)可以正确表示此语言的有效字符串{ anbncn : n >= 1 },其中n应与{a相同1}},bc(它应匹配)。 注意确实可以为这种语言的(超集)定义一个CFG,但它也会接受无效字符串和有效字符串(然后通过其他方式过滤掉它们),这不是什么是语言的语法规范应该做什么。它应仅接受有效字符串并拒绝无效。与statistics类比,可以说语言的语法规范应该消除/最小化 Type-I (拒绝有效字符串)和 Type-II (接受无效字符串)错误,而不仅仅是其中之一。

让我在JavaScript的上下文中给出一个简单的例子(因为变量似乎对JavaScript没有任何问题)。

在JavaScript中(在strict mode中),重复的命名函数声明无效。所以这是无效的:

function duplicateFunc(){}
function duplicateFunc(){} // duplicate named function declaration

所以程序不正确,但CFG无法处理这种情况。

即使打开严格模式本身也是上下文敏感的 可以通过在案例中拆分CFG并根据@Bergi's answer进行相应解析来处理严格模式规则的子集(删除严格模式示例)

[UPDATE]

我将尝试提供几个JavaScript非上下文无关代码的示例,这些代码不需要&#34;严格模式&#34; (对建议/更正开放)。

使用reserved words/keywords是语法的扩展(或限制)。这是一个无关紧要的功能,因此以下示例应作为非CF行为的示例。

var var; // identifier using reserved name
var function; // identifier using reserved name
obj.var; // reserved name used as (explicit) property
obj["var"]; // this is fine!!
Object++; // built-in type used as numeric variable

[/ UPDATE]

因此,上下文在正确解析程序中起作用。正如所说&#34; 上下文就是一切&#34;!

然而,只有对无上下文语法的轻微扩展(例如Attribute GrammarsAffix Grammars,{{3}),才能处理(希望)这个上下文敏感性等等),仍然有效解析(意思是多项式时间)。

[UPDATE]

&#34; 我想说包括CSS &#34;

详细说明这个陈述。 CSS1将为CF,但随着CSS规范添加更多功能,包括variable支持(例如TAG Grammars),它会生成CSS代码上下文 - 在上述意义上是敏感的(例如,变量需要在使用前定义)。所以浏览器会解析以下css代码(因为它无效而被忽略),但CFG无法描述

body { }
h3::before {
  counter-increment: section;               /* no counter section has been defined, not valid css code */
  content: "Section" counter(section) ": "; /* Display the counter */
}

[/ UPDATE]

答案 2 :(得分:-1)

我非常确定JS 上下文无关 - 给定一个任意代码伪像,如果不知道其上下文,就无法确定其确切含义。

首先想到的例子是{} - 这是代表​​空对象文字还是空语句块?在没有上下文的情况下决定是不可能的,但是因为语言允许在结尾的语句中省略分号,所以&#39;}&#39; (与大多数具有类似C语法的语言一样)它也可能是不可判断的 with context!考虑{x: {}} - 这可能是一个带有&#34; x&#34;的对象文字。包含空对象的字段,或带有标记子语句的语句块(其中标签为&#39; x&#39;且子语句为{})。也许语言规范在这种情况下有一些选择正确解释的规则,但在任何情况下,语言似乎都没有上下文,仅从这些例子来看。

JavaScript的自动分号插入&#39;功能当然无助于区分表达和陈述。

这是另一个要考虑的问题:function x() {} - 这是做什么的?如果它是一个声明,它会声明一个新的提升变量&#39; x&#39;用这个函数作为它的值。如果它是一个表达式,它只是评估一个具有upvalue&#39; x&#39;绑定到相同的功能(用于自我参考)。