0

我在理解ECMAScript 2017Lexical Grammar规范之间Syntactic Grammar的具体区别时遇到了一些困难。


ECMAScript 2017 节选

5.1.2 词法和正则表达式文法

第 11 节给出了 ECMAScript 的词法文法。该文法的终端符号是符合 10.1 中定义的 SourceCharacter 规则的 Unicode 代码点。它定义了一组产生式,从目标符号 InputElementDiv、InputElementTemplateTail 或 InputElementRegExp 或 InputElementRegExpOrTemplateTail 开始,描述如何将这些代码点序列转换为输入元素序列

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

5.1.4 句法文法

当一个码位流被解析为一个ECMAScript Script或Module时,首先通过词法文法的重复应用将其转换为输入元素流;然后,该输入元素流由句法语法的单个应用程序解析。


问题

  1. 词汇语法
    • 这里它说终端符号是Unicode代码点(单个字符)
    • 它还说它产生输入元素(又名令牌)
    • 这些如何调和?终端符号要么是令牌,因此它会产生令牌。或者,终端符号是单独的代码点,这就是它产生的。
  2. 句法语法
    • 我对这个语法和词汇语法有同样的问题
    • 好像说这里的终端符号是token
    • 那么通过应用句法语法规则,产生了有效的标记,然后可以将其发送到解析器?或者,这个语法是否接受令牌作为输入,然后测试整个令牌流的有效性?

我最好的猜测

  1. 词法阶段
    • 输入:代码点(源代码)
    • 输出:应用词法产生式产生有效的记号(词位类型+值)作为输出
  2. 解析阶段
    • 输入:代币
    • 输出:应用句法文法产生 (CFG) 来确定所有标记是否一起表示一个有效的流(即源代码作为一个整体是一个有效的Script/ Module
4

2 回答 2

3

我认为您对终端符号的含义感到困惑。事实上,它们是解析器的输入,而不是输出(这是一个解析树——包括列表的退化情况)。

另一方面,生产规则确实有终端符号作为输出,目标符号作为输入——它是倒退的,这就是术语“终端”的来源。非终结符可以扩展(以不同的方式,这就是规则所描述的)为一系列终结符。

例子:

Language:
   S -> T | S '_' T
   T -> D | T D
   D -> '0' | '1' | '2' | … | '9'

String:
   12_45

Production:
     S          // start: the goal
   = S '_' T
   = T '_' T
   = T D ' ' T
   = T '2 ' T
   = D '2 ' T
   = '12 ' T
   = '12 ' T D
   = '12 ' T '5'
   = '12 ' D '5'
   = '12_45'     // end: the terminals

Parse tree:
   S
    S
     T
      T
       D
        '1'
      D
       '2'
    ' '
    T
     T
      D
       '4'
     D
      '5'

Parser output (generating a sequence of items from top-level Ts):
   '12'
   '45'

所以

  • 词法分析阶段将代码点作为输入,将标记作为输出。代码点是词法文法的终结符号。
  • 句法阶段将标记作为输入,将程序作为输出。记号是句法文法的终结符号。
于 2018-04-06T15:14:41.203 回答
1

您的“最佳猜测”对于第一个近似值是正确的。主要更正是将“令牌”更改为“输入元素”。也就是说,词汇级别产生输入元素(只有其中一些被指定为“令牌”),而句法级别将输入元素作为输入。

语法级别几乎可以忽略不是标记的输入元素,除了自动分号插入规则要求它注意空格和注释中的行终止符。

你的“这些怎么调和?” 问题似乎源于对“终端符号”或“产生”的误解,但我不清楚是哪个。

于 2018-04-07T14:54:03.500 回答