`InputElementDiv` 在 ECMAScript 词法语法中代表什么

What does `InputElementDiv` stand for in ECMAScript lexical grammar

ECMAScript 的

The lexical grammar 为词法分析器 (lexer) 列出了以下标记 类:

InputElementDiv::
    WhiteSpace
    LineTerminator
    Comment
    CommonToken
    DivPunctuator
    RightBracePunctuator
InputElementRegExp::
    WhiteSpace
    LineTerminator
    Comment
    CommonToken
    RightBracePunctuator
    RegularExpressionLiteral
InputElementRegExpOrTemplateTail::
    WhiteSpace
    LineTerminator
    Comment
    CommonToken
    RegularExpressionLiteral
    TemplateSubstitutionTail
InputElementTemplateTail::
    WhiteSpace
    LineTerminator
    Comment
    CommonToken
    DivPunctuator
    TemplateSubstitutionTail

虽然我理解嵌套的 类,如 WhiteSpaceLineTerminator,但我不理解顶层 类 是什么:InputElementDivInputElementRegExpInputElementRegExpOrTemplateTailInputElementTemplateTail。谁能澄清一下?

绝对不明显,我曾在一次破解所有这些方面遇到过困难。重要说明在 https://www.ecma-international.org/ecma-262/8.0/index.html#sec-ecmascript-language-lexical-grammar 中。具体来说:

There are several situations where the identification of lexical input elements is sensitive to the syntactic grammar context that is consuming the input elements. This requires multiple goal symbols for the lexical grammar. The InputElementRegExpOrTemplateTail goal is used in syntactic grammar contexts where a RegularExpressionLiteral, a TemplateMiddle, or a TemplateTail is permitted. The InputElementRegExp goal symbol is used in all syntactic grammar contexts where a RegularExpressionLiteral is permitted but neither a TemplateMiddle, nor a TemplateTail is permitted. The InputElementTemplateTail goal is used in all syntactic grammar contexts where a TemplateMiddle or a TemplateTail is permitted but a RegularExpressionLiteral is not permitted. In all other contexts, InputElementDiv is used as the lexical goal symbol.

关键部分在前面:

There are several situations where the identification of lexical input elements is sensitive to the syntactic grammar context

请记住,这是词法语法定义,因此它的目的就是生成一组标记。

所以让我们进一步分解。考虑这样一个片段:

/foo/g

在没有给出上下文的情况下,有两种解释方式:

  1. DivPunctuator IdentifierName DivPunctuator IdentifierName

    "/" "foo" "/" "g"
    
  2. RegularExpressionLiteral

    "/foo/g"
    

从词法分析器的角度来看,它没有足够的信息来知道这些中的哪一个 select。这意味着词法分析器需要有一个像 expectRegex 之类的标志,它不仅根据当前字符序列而且还根据以前遇到的标记来切换行为。 有些事情 需要说 "expect an operator next" 或 "expect a regex literal next"。

以下同理

}foo${
  1. RightBracePunctuator IdentifierName Punctuator

    "}" "foo$" "{"
    
  2. TemplateMiddle

    "}foo${"
    

这种情况下需要使用第二个开关。

所以这给我们留下了很好的 table 您已经看到的 4 个选项

| expectRegex | expectTemplate | InputElement                     |
| ----------- | -------------- | -------------------------------- |
| false       | false          | InputElementDiv                  |
| false       | true           | InputElementTemplateTail         |
| true        | false          | InputElementRegExp               |
| true        | true           | InputElementRegExpOrTemplateTail |

然后规范会涵盖这些标志切换时的情况:

  • InputElementRegExpOrTemplateTail:此目标用于允许使用 RegularExpressionLiteral、TemplateMiddle 或 TemplateTail 的句法语法上下文。
  • InputElementRegExp:此目标符号用于所有允许使用 RegularExpressionLiteral 但不允许使用 TemplateMiddle 或 TemplateTail 的句法语法上下文。
  • InputElementTemplateTail:此目标用于所有允许使用 TemplateMiddle 或 TemplateTail 但不允许使用 RegularExpressionLiteral 的语法上下文。
  • InputElementDiv:此目标用于所有其他上下文。