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

JavaScript是一种上下文无关的语言吗?,javascript,context-free-grammar,formal-languages,Javascript,Context Free Grammar,Formal Languages,这篇关于的文章解释了CSS是如何与上下文无关的,而HTML不是。但是JavaScript呢,JavaScript是无上下文的吗 我正在学习CFG和形式证明,但距离理解如何解决这个问题还有很长的路要走。有人知道JavaScript是否是上下文无关的吗?没有任何编程语言是(完全)上下文无关的(我会说包括CSS)。即使上下文无关语法(CFG)可用于定义/生成该语言的编译器/解析器 例如,在使用变量之前,需要先定义变量,或者涉及标识符的声明应该是唯一的,这一简单事实使得语言“上下文敏感” (编程)语言的

这篇关于的文章解释了CSS是如何与上下文无关的,而HTML不是。但是JavaScript呢,JavaScript是无上下文的吗


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

没有任何编程语言是(完全)上下文无关的(我会说包括CSS)。即使上下文无关语法(CFG)可用于定义/生成该语言的编译器/解析器

例如,在使用变量之前,需要先定义变量,或者涉及标识符的声明应该是唯一的,这一简单事实使得语言“上下文敏感”

(编程)语言的语法应该描述(并生成)字符串,这些字符串是该语言中的有效程序(语法,但也包括语义)。然而,CFG可以描述和生成无效程序的字符串(给定语言语义和规范)。描述有效程序的条件(例如:1.a
class
需要在使用
newclass()
之前定义,2.
id
必须匹配等)需要

任何CFG(具有任何有限数量的产品)都不能正确地仅表示该语言的有效字符串:,其中
n
对于
a
b
c
(应匹配注意我们确实可以为这种语言定义一个CFG(超集),但它也会接受无效字符串和有效字符串(然后通过其他方式过滤掉),这不是语言的语法规范应该做的。它应该只接受有效字符串,拒绝无效字符串。与之类似,可以说一种语言的语法规范应该消除/最小化类型I(拒绝有效字符串)和类型II(接受无效字符串)错误,而不仅仅是其中之一

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

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

function duplicateFunc(){}
function duplicateFunc(){} // duplicate named function declaration
因此程序是不正确的,但是CFG不能处理这种情况

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

[更新]

我将尝试给出几个JavaScript非上下文无关代码的示例,这些代码不需要“严格模式”
(欢迎建议/更正)

使用是对语法的一种扩展(或限制)。这是一个无关的特性,因此以下示例应视为非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
[/更新]

因此,上下文在程序的正确解析中起着重要作用。正如人们所说的“语境就是一切”

然而,这种上下文敏感性可以通过对上下文无关语法(例如,等等)的轻微扩展来处理(希望),这仍然有助于高效解析(在多项式时间内)

[更新]

“我想说包括CSS”

我想对这句话稍作阐述
CSS1
将是
CF
,但由于
CSS
规范增加了更多功能,包括
变量
支持(例如),它使
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]

我非常确定JS不是上下文无关的-给定任意代码伪制品,您不必在不知道其上下文的情况下确定其确切含义

我想到的第一个例子是
{}
-这表示的是空对象文本还是空语句块?在没有上下文的情况下是不可能决定的,但是由于该语言允许在以“}”结尾的语句中省略分号(就像大多数使用类似C的语法的语言一样),因此在上下文中也可能是不可确定的!考虑<代码> {x:{} }/COD>这可能是一个对象文字,其中包含一个空对象的“x”字段,或者一个带有标记子语句的语句块(其中标签是“x”,子语句是“代码”{}} /代码>)。也许语言规范中有一些规则可以在这种情况下选择正确的解释,但无论如何,仅从这些示例来看,语言似乎并不与上下文无关

JavaScript的“自动分号插入”功能显然无助于区分表达式和语句


这里还有一个需要考虑的问题:
函数x(){}
-这是做什么的?如果它是一条语句,它将声明一个新的提升变量“x”,并将此函数作为其值。如果它是一个表达式,它的计算结果就是一个函数,该函数的upvalue“x”绑定到同一个函数上(用于自引用)。

否,JavaScript不是上下文无关语言

它非常接近于1,ECMAScript 5规范确实1描述了语言的语法(您可以在中找到所有产品)

当然,它确实对纯上下文无关的语法产物进行了一些扩展,并描述了解析器的额外行为。一件特别的事情是,它的使用仍然使上下文无关的语言,但如果不能用于某些规则,则会使语法复杂化很多。不允许某些东西出现在严格的模式代码中是类似的——可以通过调整语法(产生的结果要多得多)来实现,但是通过离开,规则更容易表达