ECMAScript 2017:从非终结StringLiteral解析为String值

时间:2018-04-04 02:43:27

标签: javascript parsing ecmascript-6 lexical-analysis ecmascript-2017

我试图在ECMAScript 2017之后理解字符串文字到最终字符串值(由代码单元值组成)的转换。

相关摘录

5.1.2 Lexical和RegExp Grammars

  

ECMAScript的词汇语法在第11节中给出。这个语法   具有符合的终端符号Unicode代码点   10.1中定义的SourceCharacter规则。它定义了一组   制作,从目标符号InputElementDiv开始,   InputElementTemplateTail,或InputElementRegExp,或   InputElementRegExpOrTemplateTail,描述如何序列   代码点被转换为一系列输入元素

     

除了空格和注释之外的输入元素构成终端   ECMAScript语法语法的符号被称为   ECMAScript令牌。这些令牌是保留字,标识符,   文字和ECMAScript语言的标点符号。

5.1.4语法语法

  

当要将代码点流解析为ECMAScript脚本时   或模块,它首先被转换为输入元素流   重复应用词汇语法;这个输入流   然后,单个元素应用程序解析元素   语法。

11 ECMAScript语言:词汇语法

  

首先转换ECMAScript脚本或模块的源文本   转换为一系列输入元素,它们是令牌,行终止符,   评论或空格。源文本从左侧扫描到   对,重复采用尽可能长的代码点序列   作为下一个输入元素。

11.8.4字符串文字

StringLiteral ::
    " DoubleStringCharacters_opt "
    ' SingleStringCharacters_opt '

SingleStringCharacters ::
    SingleStringCharacter SingleStringCharacters_opt

SingleStringCharacter ::
    SourceCharacter but not one of ' or \ or LineTerminator
    \ EscapeSequence
    LineContinuation

EscapeSequence ::
    CharacterEscapeSequence
    0 [lookahead ∉ DecimalDigit]
    HexEscapeSequence
    UnicodeEscapeSequence

CharacterEscapeSequence ::
    SingleEscapeCharacter
    NonEscapeCharacter

NonEscapeCharacter ::
    SourceCharacter but not one of EscapeCharacter or LineTerminator

EscapeCharacter ::
    SingleEscapeCharacter
    DecimalDigit
    x
    u

11.8.4.3静态语义:SV

  

字符串文字代表String类型的值。字符串   根据代码单位值描述文字的值(SV)   由字符串文字的各个部分贡献。

  

SingleStringCharacter的SV :: SourceCharacter但不是'要么   \或LineTerminator是代码点值的UTF16Encoding   SourceCharacter。

     

SingleStringCharacter :: \ EscapeSequence的SV是。的SV   EscapeSequence。

问题

假设我们有字符串文字'b\ar'。我现在想要遵循上面的词法语法和语义语法,将字符串文字转换成一组代码单元值。

  1. b\ar被识别为 CommonToken
  2. b\ar进一步被识别为 StringLiteral
  3. StringLiteral 已转换为 SingleStringCharacters
  4. SingleStringCharacters 中的每个代码点都转换为 SingleStringCharacter
  5. 没有\ infront的每个 SingleStringCharacter 都会被转换为 SourceCharacter
  6. \a被识别为\ EscapeSequence
  7. EscapeSequence (a)已翻译为 NonEscapeCharacter
  8. NonEscapeCharacter 已转换为 SourceCharacter
  9. 所有 SourceCharacter 已翻译为any Unicode code point
  10. 最后,应用SV规则来获取字符串值,从而编码单元值
  11. 我遇到的问题是StringLiteral输入元素现在是:

    SourceCharacter, \ SourceCharacter, SourceCharacter
    

    \ SourceCharacter 没有SV规则,仅适用于 \ EscapeCharacter

    这让我想知道我的顺序是否错误,或者误解了如何应用词法和句法语法。

    我也对如何完全应用SV规则感到困惑。因为它们被定义为应用于非终结符号,而不是终结符号(应该是应用词法语法后的结果)。

    非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

好吧,假设我们正在使用单个令牌'b\ar',就像你说的StringLiteral令牌一样。应用11.8.4.3 Static Semantics: SV中定义的算法以及10.1.1 Static Semantics: UTF16Encoding(cp),我们遵循SV规则:

  1. StringLiteral:: ' SingleStringCharacters '的SV是SV的{​​{1}}。
    • 打开引号,因为我们只在SingleStringCharacters部分递归SV运行,例如SingleStringCharacters
  2. SV(b\ar) SV的{​​{1}}是一个或两个代码单元的序列,SingleStringCharacters:: SingleStringCharacterSingleStringCharacters后跟所有按顺序SV SingleStringCharacter中的代码单元。

    这表示“每SV个附加结果调用SV”。

    1. SingleStringCharacters
      1. SingleStringCharacter SV(b)的{​​{1}}但不是SVSingleStringCharacter::SourceCharacter之一是'的{​​{1}}代码点值\
        • 代码点“b”是代码单元LineTerminator,因此这里的结果实际上是一个16位单元的代码单元序列UTF16Encoding
    2. SourceCharacter
      1. \x0062 \x0062 SV(\a)的{​​{1}}是SV的{​​{1}}。
        • 基本上SingleStringCharacter::\(无EscapeSequence前缀)
      2. SV EscapeSequence的{​​{1}}是SV(EscapeSequence)的{​​{1}}。
        • 基本上只是通过SV(a)
      3. \ SV的{​​{1}}是EscapeSequence::的{​​{1}}。
        • 更多传递
      4. CharacterEscapeSequence SV的{​​{1}}但不是CharacterEscapeSequenceSV(a)中的SV是SourceCharacter代码点值的CharacterEscapeSequence::
        • 代码点“a”是代码单元NonEscapeCharacter,因此这会产生仅SV的单个单元序列。
    3. NonEscapeCharacter
      • 按照与SV相同的步骤生成包含NonEscapeCharacter::的单个单元序列。
  3. 将序列SourceCharacter合并在一起,字符串的值是UTF16代码单元EscapeCharacter的序列。该代码单元序列导致LineTerminator
  4. 编辑:

      

    我虽然应该首先应用词汇语法并最终使用令牌,然后应用SV规则?

    词法分析员的观点中的“标记”是UTF16Encoding,其中的所有内容都只是有关如何解析的信息。 \x0061不是一种令牌。

    \x0061定义了如何将StringLiteral标记分解为一系列代码单元。

    作为11 ECMAScript Language: Lexical Grammar

    中的州
      

    ECMAScript脚本或模块的源文本首先转换为一系列输入元素,即标记,行终止符,注释或空格。源文本从左向右扫描,重复使用尽可能长的代码点序列作为下一个输入元素。

    这些“输入元素”是解析器语法使用的标记。

      

    假设事件顺序正确,我的第二个问题是SV(\ a)。应用第一个转义序列规则,我们留下SV(a),它应该遵循与SV(b)no相同的路径?

    不仅仅是值,还有数据类型。使用Flow / Typescript样式的注释,您可以考虑上面的步骤

    1. SV(r) SV(b) \x0072的{​​{1}}是SV(b) + SV(\a) + SV(r)的{​​{1}}。
    2. [\x0062, \x0061, \x0072] bar的{​​{1}}是StringLiteral的{​​{1}}。
    3. EscapeSequence SV的{​​{1}}是SV的{​​{1}}。
    4. SingleStringCharacter:: \的{​​{1}}但不是EscapeSequenceSV中的EscapeSequence是SourceCharacter代码点值的SV
    5. 好像它是一个重载函数,例如

      EscapeSequence::

      所以CharacterEscapeSequence有点像SVCharacterEscapeSequence有不同的类型。