这篇关于how browsers work的文章解释了CSS如何无上下文,而HTML 不是。但是JavaScript呢,JavaScript上下文是免费的吗?
我正在学习CFG和正式证明,但距离理解如何解决这个问题还有很长的路要走。有没有人知道JavaScript是否没有上下文?
答案 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(包含任何有限数量的作品)可以正确表示此语言的有效字符串:{
a
n
b
n
c
n
: n >= 1
}
,其中n
应与{a
相同1}},b
,c
(它应匹配)。 注意确实可以为这种语言的(超集)定义一个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 Grammars,Affix 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;绑定到相同的功能(用于自我参考)。