ECMAScript:词法语法与句法语法

ECMAScript: Lexical Grammar vs Syntactic Grammar

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


ECMAScript 2017 节选

5.1.2 词法和 RegExp 文法

A lexical grammar for ECMAScript is given in clause 11. This grammar has as its terminal symbols Unicode code points that conform to the rules for SourceCharacter defined in 10.1. It defines a set of productions, starting from the goal symbol InputElementDiv, InputElementTemplateTail, or InputElementRegExp, or InputElementRegExpOrTemplateTail, that describe how sequences of such code points are translated into a sequence of input elements.

Input elements other than white space and comments form the terminal symbols for the syntactic grammar for ECMAScript and are called ECMAScript tokens. These tokens are the reserved words, identifiers, literals, and punctuators of the ECMAScript language.

5.1.4 句法语法

When a stream of code points is to be parsed as an ECMAScript Script or Module, it is first converted to a stream of input elements by repeated application of the lexical grammar; this stream of input elements is then parsed by a single application of the syntactic grammar.


问题

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

我最好的猜测

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

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

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

示例:

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'

所以

  • 词法分析阶段将代码点作为输入,将标记作为输出。代码点是词法文法的终结符号。
  • 句法阶段将标记作为输入,将程序作为输出。标记是句法文法的终结符号。

您的 "best guess" 初步估计是正确的。主要更正是将"tokens"改为"input elements"。即词法层面产生输入元素(仅指定部分'tokens'),句法层面产生输入元素作为输入。

句法级别可以几乎忽略不是标记的输入元素,除了自动分号插入规则要求它注意空格和注释中的line-terminators .

你的 "How are these reconcilable?" 问题似乎源于对 "terminal symbol" 或 "produces" 的误解,但我不清楚是哪一个。