Lexical Grammar

Literals

字面量(Literal)是直接表示值的基本表达式。字面量用于表示固定的值,它们可以是 StringNumericBooleanNullObjectArrayRegluarTemplate

  1. Null字面量:只有null
  2. Boolean字面量: 有falsetrue

Numeric字面量

Numeric字面量有DecimalLiteralDecimalBigIntegerLiteralNonDecimalIntegerLiteralLegacyOctalIntegerLiteral

  1. DecimalLiteral:是用于表示十进制数字的字面量。它可以包括整数部分、小数部分和指数部分。

根据其语法结构,可以有以下几种表示形式:

  • 整数+小数+指数
    • 123.23e2123.23E-2123.23
  • 小数+指数
    • .23e2.23E-2.23
  • 整数+指数
    • 123123e2123
let num = 123.23e2; // 12323 = 123.23 * (10 ** 2)
let num1= 123.23e-1; // 12.323 = 123.23 * (10 ** -1)
  1. DecimalBigIntegerLiteral:表示大整数字面量。这些大整数字面量超出了普通 Number 类型的安全范围,使用后缀 n 来表示。

根据其语法结构,可以有以下几种表示形式:

  • 0n
  • 123n
  • 1_000_000_33n
  1. NonDecimalIntegerLiteral: 非十进制整数字面量,可以是二进制、八进制或十六进制的整数。这些整数字面量不包含小数部分,而且可以使用数字分隔符提高可读性。

根据其语法结构,可以有以下几种表示形式:

  • BinaryIntegerLiteral: 二进制字面量
    • 0b01010B10100b0000_1111
  • OctalIntegerLiteral: 八进制字面量
    • 0o070o12340o777_777
  • HexIntegerLiteral: 十六进制字面量
    • 0x0f0xffff
  1. LegacyOctalIntegerLiteral: 传统的八进制整数字面量表示,语法结构

这种方式在严格模式下会有SyntaxError来标记这种使用,在 ES6以上版本中以禁止使用这种方式。

Note

Static Semantics: MV(Mathematical Value)

MV(Mathematical Value): 是一个定义,将数值文本转换成数值的数学值,这也是运行时需要执行的操作。

MV大概的计算过程:

  • 忽略前导空格:从输入文本中忽略任何前导空格(空格字符、水平制表符、垂直制表符、换行符、回车符和换页符)。
  • 处理符号:
    • 如果文本以 - 开头,则结果是一个负数。
    • 如果文本以 + 开头或没有符号,结果是一个正数。
  • 确定基数:
    • 如果文本以 0x 或 0X 开头,基数为 16。
    • 如果文本以 0o 或 0O 开头,基数为 8。
    • 如果文本以 0b 或 0B 开头,基数为 2。
    • 否则,基数为 10。
  • 解析数字:
    • 从文本 中移除可能的前缀,并解析剩余部分为一个整数。
  • 处理异常情况:
    • 如果文本包含非法字符或无法转换为有效数字,则返回 NaN(Not-a-Number)。
    • 如果文本表示的值超出了 JavaScript 数值类型的范围,则返回 Infinity 或 -Infinity。
  • 返回结果:
    • 返回计算得到的数学值(Mathematical Value)。

不同表示的数字的详细计算过程-规范,也可以参考进制之间的转换

String字面量

String字面量是单引号或双引号括起来的0个或多个Unicode码位

Note

Unicode码点也可以由转义序列表示。

除了"or'单双结束引号,U+005C反斜杠,U+000D回车,U+000A换行之外,所有的码点 都可以出现字符串文本中,任何码点都可以以转义序列的形式出现

字符串字面量会被计算成字符串值,而在生成字符串值时,Unicode码点通过UTF-16进行编码

字符串字面量语法表示方式(单双引号表示一致):

  1. sourceCharacters: 任何Unicode码位除了",',\, U+000D, U+000A

  2. \ EscapeSequence: 转义序列

转义序列又分为以下几种:

  • characterEscapeSequence:字符转义序列 包含\n-换行符, \t:制表符, \b-退格符, \r-回车符, \\-反斜杠, \'-单引号, \"-双引号
  • LegacyOctalEscapeSequence: 传统八进制转义序列使用八进制数值来表示字符。八进制转义序列以反斜杠 \ 开头,后跟一到三位的八进制数。
  • NonOctalDecimalEscapeSequence: 非八进制十进制转义序列较少见,主要用于表示与八进制数不重叠的十进制值。在现代标准中,这种转义序列通常不推荐使用,更建议使用十六进制或Unicode转义序列。
  • HexEscapeSequence: 十六进制转义序列使用十六进制数值来表示字符,格式为\x后跟两位十六进制数。
  • UnicodeEscapeSequence: Unicode转义序列使用Unicode码点来表示字符,格式为 \u 后跟四位十六进制数,或者 \u{} 包含一到六位十六进制数(ES6及以上版本)。
  • 0 [lookahead ∉ DecimalDigit]: 是一种正则表达式的语法,表示零的转义序列后面不能跟随十进制数字。具体来说,这在解释传统八进制和非八进制转义序列时特别有用。让我们更详细地了解这种用法以及它如何与不同的转义序列类型关联。
'line1\nline2\tTabbed\x41\u0041\u{1F600}';
// Line1
// Line2 TabbedAA😃

Pitfall

Static Semantics: early errors:

在严格模式下,LegacyOctalEscapeSequenceNonOctalDecimalEscapeSequence是存在语法错误的。

Note

Static Semantics: SV(Semantics Value):

SV 是语义值(Semantic Value)的简称,用于解释字符串字面量如何解析为最终的字符串值。下面是对每个规则的详细解释和示例:

  1. ""或者''代表空字符串
  2. 字符串连接运算符+代表字符串拼接(''或者"")
  3. 引号内的字符(除了",\和换行符)会被UTF-16进行编码
  4. 特殊字符<LS>-(分隔符0x2028),<PS>-(分隔符0x2029),LineContinuation- (延续符,解释为空字符串)
  5. \0表示空字符
  6. 单字符转义序列,如\n\b等,转义表
  7. 非转义字符,即按UTF-16编码
  8. 传统八进制转义序列的数值部分被转换为响应的字符串值。
  9. 非八进制十进制转义序列89分别表示字符8和9。
  10. 十六进制转义序列, x后跟两位或者四位(Unicode字符)十六进制数。
  11. Unicode转义序列\u{} 中包含的码点将被转换为对应的 UTF-16 编码。
  12. 模板转义序列 \0表示空字符

Note

Static Semantics: MV(Mathematical Value): 在数学求值方面,有以下几种:

  • LegacyOctalEscapeSequence:这种八进制转义序列的求值已经在严格模式被弃用了。
  • HexEscapeSequence:十六进制转义序列求值规则第一个十六进制数乘以16再加上第二个十六进制数
    • \x41: 求值为 4*16 + 1 = 65为字符A。
  • Hex4Digits: 4位十六进制数求值,例如0xA1B3求值过程如下: MV(0xA1B3)=0x100016x10+0x100x1+0x100x11+0x10x3MV(0xA1B3)=4096x10+256x1+16x11+1x3MV(0xA1B3)=40960+256+176+1x3MV(0xA1B3)=41395 MV(0xA1B3) = 0x1000_{16} x 10 + 0x100 x 1 + 0x100 x 11 + 0x10 x 3 \\ MV(0xA1B3) = 4096 x 10 + 256 x 1 + 16 x 11 + 1 x 3 \\ MV(0xA1B3) = 40960 + 256 + 176 + 1 x 3 \\ MV(0xA1B3) = 41395 其结果跟Unicode转义序列\uA1B3的码点结果一致。

Regular Expression Literals

一个Regular Expression Literal 是一个输入元素,每次计算字面量时,它都会被转换成RegExp对象。 程序中的两个正则表达式文字计算为正则表达式对象,即使这两个文字的内容相同,它们也不会相互比较为===。 也可以在运行时通过new RegExp或将RegExp构造函数作为函数调用来创建RegExp对象。

正则表达式字面量语法结构如下:

RegularExpressionLiterals包含:

  • / RegularExpressionBody / RegularExpressionFlags 正则表达式字面量由 / 开头,接着是正则表达式主体,最后是 / 和可选的正则表达式标志。

RegularExpressionBody包含:

  • RegularExpressionFirstChar RegularExpressionChars 正则表达式主体由一个 RegularExpressionFirstChar 开始,接着是零个或多个 RegularExpressionChars。

RegularExpressionFirstChar包含:

  • RegularExpressionNonTerminator(一个终止符)but not one of * or \ or / or [
  • RegularExpressionBackslashSequence(一个反斜杠序列)
  • RegularExpressionClass(字符类)

RegularExpressionChars包含:

  • [empty] (可以是空的)
  • RegularExpressionChars RegularExpressionChars(可以是一个或者多个)

RegularExpressionBackslashSequence 包含:

  • \ RegularExpressionNonTerminator 反斜杠序列由一个反斜杠 \ 和一个非终止符字符

RegularExpressionNonTerminator:

  • sourceCharacters but not LineTerminator 非终止符字符是任何源字符(SourceCharacter),但不能是行终止符(LineTerminator)。

RegularExpressionClass:

  • [RegularExpressionClassChars] 字符类由[ 开始,然后是零个或多个字符类字符(RegularExpressionClassChars),最后由 ]结束。

RegularExpressionClassChars:

  • [empty]
  • RegularExpressionClassChars RegularExpressionClassChar

RegularExpressionClassChar:

  • RegularExpressionNonTerminator 一个非终止符字符,但不能是]或者\
  • RegularExpressionBackslashSequence 反斜杠序列

RegularExpressionFlags:

  • [empty]
  • RegularExpressionFlags IdentifierPartChar 正则表达式标志可以是空的,或者由一个或多个标识符部分字符(IdentifierPartChar)组成。

Pitfall

正则表达式文字不能为空;代码单元序列//开始单行注释,而不是表示空的正则表达式文字。要指定空正则表达式,请使用:/(?:)/

Template Literals