ECMAScript 2017:字符串文字、StringValue、字符串值和 SV 之间的区别

ECMAScript 2017: Difference between string literal, StringValue, String value, and SV

以下摘录参考ECMAScript 2017.

11.8.4.2 静态语义:StringValue

StringLiteral::
    "DoubleStringCharactersopt"
    'SingleStringCharactersopt'

1. Return the String value whose elements are the SV of this StringLiteral.

11.8.4.3 静态语义:SV

A string literal stands for a value of the String type. The String value (SV) of the literal is described in terms of code unit values contributed by the various parts of the string literal.

问题

在上面的摘录中,出现了以下术语:

  1. string literal
  2. 非终结符号StringLiteral
  3. String value
  4. SV

谁能帮忙解释一下这些术语的区别?

另外,11.8.4.2最后一句是什么意思?

一个字符串文字是你,一个人类编写或阅读代码,可以识别为序列"..."'...'[=17的东西=]

令牌StringLiteral是EMCAScript形式语法中的一个nonterminal,可以用实际字符串文字的终端替换。

一个字符串值是一个字符串文字的语义内容。规范说

The String value (SV) of the literal is ...

因此,我们可以确定一个字符串字面量一个字符串值:某个字符串字面量的字符串值是一个集合代码单元值。

对于 "string value".

(并可互换使用),标识符 SV 似乎是 shorthand

Also, what does the last sentence in 11.8.4.2 mean?

每个非终结符 "returns" 在计算时都有一些值。行

Return the String value whose elements are the SV of this StringLiteral.

只是意味着当解析器在程序文本中找到一个 StringLiteral 时,解析该非终结符的结果是与 just-parsed StringLiteral 关联的字符串值(即代码单元值的集合)。

您正在查看的许多术语对 JavaScript 平台维护人员来说确实很有价值;实际上,您几乎肯定已经知道 "string" 是什么。其他术语对于阅读规范很有用。

术语StringLiteral指的是一段JavaScript源代码,JavaScript程序员会查看并调用"a string";换句话说,在

let a = "hello world";

StringLiteral=右边从开头double-quote到结尾double-quote的运行个字符。它是 "nonterminal" 因为它不是语法定义中的 "terminal" 符号。语言语法是从最低级别的终端符号和 non-terminals 构建的,用于描述程序的 higher-level 子部分。您在 double-quoted 字符串的描述中看到的 bold-faced double-quote 字符是终端符号的示例。

术语StringValue指的是适用于语法的多个组件的内部操作;对于 StringLiteral 它具有您发布的相当明显的定义。语义规则是根据构成某些语法概念的 non-terminals 编写的。

术语 String valueSV 用于描述字符串的 piece-by-piece 部分。

JavaScript 规范在术语方面特别古怪,因为语言委员会坚持描述在语言采用的早期 willy-nilly 演变而来的语义。发明具有明显冗余的术语层是一种应对困难的方法,可以创建对代码应该做什么的明确描述,直到最后的细节和奇怪的特例。由于(出于我不知道的原因)词法语法被分解为 higher-level 构造的令人痛苦的细节这一事实使它变得更加复杂,因此真正复合了规范的 nit-picky 感觉。

知道术语的扩展会有用的一个例子可能是解释为什么在从字符串文字而不是正则表达式文字构建正则表达式时有必要在反斜杠上 "double-up"。很明显,对 RegExp 构造函数的调用:

var r = new RegExp("foo\.bar");

有一个只包含一个 StringLiteral 的表达式。然后,为了调用构造函数,该操作的语义规则将在某个时候调用获取该文字的 StringValue(因此 SV),并且这些规则包含每个细节一段文字。这就是您遇到 SV 语义有反斜杠规则的地方,特别是说两个反斜杠折叠为一个的规则。

现在我并不是说这个解释比简单的解释更好,但它对问题的每个细节都非常清楚。