JavaScript是一种上下文无关的语言吗?
这篇关于的文章解释了CSS是如何与上下文无关的,而HTML不是。但是JavaScript呢,JavaScript是无上下文的吗JavaScript是一种上下文无关的语言吗?,javascript,context-free-grammar,formal-languages,Javascript,Context Free Grammar,Formal Languages,这篇关于的文章解释了CSS是如何与上下文无关的,而HTML不是。但是JavaScript呢,JavaScript是无上下文的吗 我正在学习CFG和形式证明,但距离理解如何解决这个问题还有很长的路要走。有人知道JavaScript是否是上下文无关的吗?没有任何编程语言是(完全)上下文无关的(我会说包括CSS)。即使上下文无关语法(CFG)可用于定义/生成该语言的编译器/解析器 例如,在使用变量之前,需要先定义变量,或者涉及标识符的声明应该是唯一的,这一简单事实使得语言“上下文敏感” (编程)语言的
我正在学习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描述了语言的语法(您可以在中找到所有产品)
当然,它确实对纯上下文无关的语法产物进行了一些扩展,并描述了解析器的额外行为。一件特别的事情是,它的使用仍然使上下文无关的语言,但如果不能用于某些规则,则会使语法复杂化很多。不允许某些东西出现在严格的模式代码中是类似的——可以通过调整语法(产生的结果要多得多)来实现,但是通过离开,规则更容易表达