ECMAScript 2015官方文档翻译(三)

前言:本章讲编译方面的知识,读起来可能会很艰难,文中提到的格式问题(比如斜体,等宽字体等)以官方文档为标准,本译文由于排版问题可能会有不符合的地方。

5 符号公约

  
  5.1句法和词汇语法
  
  5.1.1上下文无关文法
  上下文无关文法由多个产生式组成。每个产生式都有一个抽象符号(称为非终结符)作为其左侧,一个、零个或多个非终止符号和终端符号序列作为其右侧。对于每个语法,终结符从指定的字母表中绘出。
  链产生式是在其右侧有一个非终结符,以及零或更多的终结符。
  从一个由单一非终端组成的句子(称为目标符号)开始,给定的上下文无关语法指定了一种语言,即(可能是无限的)可能的终结符序列集合,它可以由重复地替换其中非终端是左侧的产生式的右侧的序列。
  
  5.1.2词汇和RegExp语法
  第11节给出了ECMAScript的词汇语法。该语法具有符合10.1中定义的SourceCharacter规则的Unicode码点的终端符号。它定义了一组表达式,从目标符号InputElementDivInputElementTemplateTailInputElementRegExpInputElementRegExpOrTemplateTail开始,它们描述了如何将这些代码点序列如何转换为输入元素序列。
  除空白和注释之外的输入元素构成ECMAScript语法的终端符号,称为ECMAScript tokens。这些tokens是ECMAScript语言的保留字,标识符,文字和标点符号。此外,line terminator(线路终端器、行终止符)虽然不被认为是tokens,但也成为输入元件流的一部分,并指导了自动分号插入过程(11.9)。简单的空白和单行注释被丢弃,不会出现在句法语法的输入元素流中。一个MultiLineComment(也就是说,/*…… */形式的评论不管它是否跨越多行)如果不包含任何行终止符同样简单地被丢弃; 但是如果MultiLineComment包含一个或多个行终止符,那么它将被单行终止符替代,该行终止符成为syntactic grammar(句法语法)的输入元素流的一部分。
  ECMAScript 的RegExp语法在21.2.1中给出。这个语法也有它的终端符号,由SourceCharacter定义的代码点。它定义了一组生成,从目标符号Pattern开始,描述代码点的序列如何转换为正则表达式模式。
  词法和RegExp语法的生成通过将两个冒号“ :: ”作为分隔标点来区分。词汇和RegExp语法分享一些表达式。
  
  5.1.3数字字符串语法
  另一种语法用于将字符串转换为数值。这个语法类似于lexical grammar(词法语法)与数字文字有关的部分,并具有其终端符号SourceCharacter。该语法出现在7.1.3.1中。
  通过将三个冒号“ ::: ”作为标点符号来区分数字字符串语法的生成。
  
  5.1.4句法语法
  用于ECMAScript的句法语法在第11,12,13,14,15节给出。此语法具有被词法语法定义的ECMAScript的tokens作为其终端符号(定义5.1.2)。它定义了一组产生式,从两个替代目标符号Script (脚本)和Module(模块)开始,描述了tokens序列如何在语法上正确地构成ECMAScript程序独立组件。
  当代码点流被解析为ECMAScript 脚本或模块时,首先通过重复应用词汇语法被转换成输入元素的流; 然后,这个输入元素流由句法语法的单个应用解析。如果输入元素流中的tokens不能被解析为目标非终结符(脚本或模块)的单个实例,且没有 tokens遗漏,则输入流在语法上是错误的。
  句法语法的产生式通过仅使用一个冒号“ : ”作为标点符号来区分。
  第12,13,14和15条中提出的句法语法不是完整的记录哪个 tokens序列被接受为正确的ECMAScript 脚本或模块。某些额外的令牌序列也被接受,也就是说,只要在某些序列的特定地方中添加了分号(例如在行终止符之前),那么这些序列将被语法描述。此外,如果在某些“尴尬”的地方出现行终止符,则语法所描述的某些tokens序列被认为是不可接受的。
  在某些情况下,为了避免歧义,句法语法使用了通用的产生式,允许标记序列不构成有效ECMAScript 脚本或模块的tokens序列。例如,该技术用于对象字面量和对象解构模式。在这种情况下,提供了更加严格的 补充语法,其进一步限制可接受的tokens序列。 在某些上下文中,与此类产生式相对应的输入元素会再次被使用补充语法的目标符号解析。
  
  5.1.5语法符号
  词法,RegExp和数字字符串语法的终端符号都以fixed width(等宽样式)字体显示,无论是语法的产生式还是在整个本规范中,只要文本直接引用这样的终端符号。其都将以书面形式出现在脚本中。以这种方式指定的所有终端符号代码点应被理解为来自基本拉丁语范围的适当的Unicode代码点,而不是来自其他Unicode范围的任何类似代码点。
  非终端符号以斜体显示。非终止(也称为“产生式”)的定义是由一个或多个冒号后面定义的非终结符的名称引入的。(冒号指示产生式属于哪种语法)。非终结符的一个或多个可替代右手边跟着连续的行。例如,句法定义:

WhileStatement :
   while (Expression) Statement

  表示非终结的WhileStatement表示token while,后跟左括号标记,后跟一个表达式,后跟右括号标记,后跟一个Statement(语句)。表达式和语句的出现是它们自己的非终端。另一个例子,句法定义:

ArgumentList :
   AssignmentExpression
   ArgumentList , AssignmentExpression

  一个ArgumentList也许代表了一个单一的AssignmentExpression或者一个ArgumentList,然后是一个逗号,然后是一个AssignmentExpression。这个ArgumentList的定义是递归的,也就是说,它是根据它本身来定义的。这样的结果就是,一个ArgumentList也许会包含任意数量逗号分隔的正参数,其中的每个argument表达式是一个AssignmentExpression。这样的非终结符的递归定义是非常常见的。
  下标后缀“ opt ”,它可能出现在终端或非终端之后,表示一个可选的符号。包含可选符号实际上指定了两个右侧,一个省略了可选元素,另一个包含它。这意味着:

VariableDeclaration :
   BindingIdentifier Initializeropt

是下面的缩写:

VariableDeclaration :
   BindingIdentifier Initializeropt

然后还有:

IterationStatement :
   for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

是下面的缩写:

IterationStatement :
   for ( LexicalDeclaration ; Expressionopt ) Statement
   for ( LexicalDeclaration Expression ; Expressionopt ) Statement

这又是一个缩写:

IterationStatement :
   for ( LexicalDeclaration ; ) Statement
   for ( LexicalDeclaration ; Expression ) Statement
   for ( LexicalDeclaration Expression ; ) Statement
   for ( LexicalDeclaration Expression ; Expression ) Statement

  所以在这个例子中,非终结符迭代语句实际上有四个可选的右侧。
  一个产生式可以通过“ [parameters] ” 形式的下标注释进行参数化,这可以作为产生式定义的非终结符号的后缀。“parameters”可以是单个名称或逗号分隔的名称列表。参数化产生式是一组定义了参数名称的所有组合的缩写,后面是一个下划线,附加到参数化的非终结符号。这意味着:

StatementList[Return] :
   ReturnStatement
   ExpressionStatement

是下面的缩写:

StatementList :
   ReturnStatement
   ExpressionStatement
StatementList_Return :
   ReturnStatement
   ExpressionStatement

然后:

StatementList [Return,In] :
   ReturnStatement
   ExpressionStatement

是下面的缩写:

StatementList :
   ReturnStatement
   ExpressionStatement
StatementList_Return :
   ReturnStatement
   ExpressionStatement
StatementList_In :
   ReturnStatement
   ExpressionStatement
StatementList_Return_In :
   ReturnStatement
   ExpressionStatement

  多个参数产生组合数量的产生式,并不是所有的都必须以完整的语法引用。
  也可以对产生式右侧的非终端进行参数化。例如:

StatementList :
   ReturnStatement
   ExpressionStatement[In]

相当于说:

StatementList :
   ReturnStatement
   ExpressionStatement_In

  非终止引用可能同时具有参数列表和“ opt ”后缀。例如:

VariableDeclaration :
   BindingIdentifier Initializer[In]opt

是下面的缩写:

VariableDeclaration :
   BindingIdentifier
   BindingIdentifier Initializer_In

  给一个参数在右值的非终结符引用加上前缀“?”使得该参数依赖于引用当前产生式左值符合的参数名,。例如:

VariableDeclaration [In] :
   BindingIdentifier Initializer [?In]

是下面的缩写:

VariableDeclaration :
   BindingIdentifier Initializer
VariableDeclaration_In :
   BindingIdentifier Initializer_In

  如果右侧替代方案以“[+ parameter]”为前缀,则只有在引用产生式的非终结符号时使用了该命名参数,该选项才可用。如果右侧替代方案以“[〜parameter]”为前缀,则只有在引用产生式的非终结符号时未使用命名参数才可用。这意味着:

StatementList[Return] :
   [+Return] ReturnStatement
   ExpressionStatement

是下面的缩写:

StatementList :
   ExpressionStatement
StatementList_Return :
   ReturnStatement
   ExpressionStatement

然后

StatementList[Return] :
   [~Return] ReturnStatement
   ExpressionStatement

是下面的缩写:

StatementList :
   ReturnStatement
   ExpressionStatement
StatementList_Return :
   ExpressionStatement

  当单词“one of”在语法定义中跟随冒号时,它们表示下一行或行中的每个终端符号都是可选的定义。例如,ECMAScript的词法语法包含产生式:

NonZeroDigit :: one of
   1 2 3 4 5 6 7 8 9

  是下面的内容一个方便的缩写:

NonZeroDigit ::
   1
   2
   3
   4
   5
   6
   7
   8
   9

  如果短语“[empty]” 出现在产生式的右侧,则表示产生式的右侧不包含终结或非终结符。
  如果短语“[lookahead ∉ set]”出现在产生式的右侧,则表示如果紧随其后的输入token序列是给定的成员可以不使用产生式 集合。该集合可以写成逗号分隔的一个或两个元素终端序列的列表,其中括号包含在大括号中。为了方便起见,该集合也可以被写为非终结符,在这种情况下,它表示非终端可以扩展的所有终端的集合。如果该组由单个终端组成,则可以使用短语“[lookahead≠ terminal ]”。
  例如,给定定义

DecimalDigit :: one of
   0 1 2 3 4 5 6 7 8 9
DecimalDigits ::
   DecimalDigit
   DecimalDigits DecimalDigit

定义:

LookaheadExample ::
   n [lookahead ∉ {1, 3, 5, 7, 9}]    DecimalDigits
   DecimalDigit [lookahead ∉ DecimalDigit]

  匹配字母n后跟一个或多个十进制数字,其中第一个是偶数,或一个十进制数字不跟随另一个十进制数字。
  如果在句法语法产生式的右侧出现短语“[no LineTerminator here]”,则表示产生式是受限产生式:如果LineTerminator出现在输入流中,则可能不会使用指示位置。例如,产生式:
  

ThrowStatement :
   throw [no LineTerminator here] Expression ;

  表示在throw token和表达式之间的脚本中出现LineTerminator(行终结符)时,不能使用产生式。
  除非被限制的产生式禁止使用LineTerminator,否则在输入元素的流中,任何两个连续的标记之间都可能出现任意数量的LineTerminator,而不会影响脚本的语法可接受性。
  当在词汇语法或数字字符串语法的产生式中出现一个可选方案且是一个多码点标记时,它代表将构成这样一个token的代码点序列。
  产生式的右侧可以指定通过使用短语“but not” ,而不允许某些扩展,然后指示被排除的扩展。例如,产生式:
  

Identifier ::
   IdentifierName but not ReservedWord

  意味着非终结标识符可以被任何可能替代IdentifierName 的代码点序列替换,只要相同的代码点序列不能替代ReservedWord。
  最后,在sans - serif(无衬线字体)类型中,一些非终结符号用一种描述性的短语来描述,在这些情况下,列出所有备选方案是不切实际的:

SourceCharacter ::
   any Unicode code point

  5.2算法约定
  规范通常使用编号列表来指定算法中的步骤。这些算法用于精确地指定ECMAScript语言结构所需的语义。这些算法并不意味着使用任何特定的实现技术。在实践中,可能有更有效的算法可用于实现给定的特征。
  算法可以显式地参数化,在这种情况下,参数的名称和用法必须作为算法定义的一部分提供。为了便于在本规范的多个部分使用它们,称为抽象 操作的一些算法以参数化的函数形式命名和写入,以便可以通过其他算法中的名称来引用它们。一些抽象操作被视为类类规范抽象的多态调度方法。这种类似方法的抽象操作通常使用诸如operationName(arg1,arg2)之类的函数应用程序引用。
  算法可能与ECMAScript语法之一的产生式相关联。具有多个替代定义的产生式通常对于每种替代方案具有不同的算法。当算法与语法产生式相关联时,它可以引用产生式替代的终端和非终止符号,就像它们是算法的参数一样。当以这种方式使用时,非终止符号是指解析源文本时匹配的实际替代定义。
  当算法与产生式替代方案相关联时,通常会显示替代方案,而没有任何“[ ]”语法注释。这样的注释只能影响替代方法的句法识别,并且对替代方案的相关语义没有影响。
  除非另有明确规定,否则所有连锁产生式对于可能应用于产生式的左侧非终端的每个算法都有隐含的定义。隐式定义简单地将具有相同参数的相同算法名称(如果有的话)重新应用于链产生式的唯一右手侧的非终止,然后返回结果。例如,假设有一个产生式:

Block :
   { StatementList }

  但是并没有明确指定该产生式的相应的评估算法。如果在一些算法中有一个形式的语句:“ 返回评估块的结果 ”,则隐含的是一个评估算法存在的形式:
  运行时语义:评估

Block : { StatementList }
   1. 返回评估StatementList的结果。

  为了表达的清楚,算法步骤可以被细分为顺序子步骤。子项缩进,本身可以进一步划分成缩进的子步骤。轮大纲编号的约定是用来确定子步骤的第一级的子步骤,标记小写字母的字符和第二级的子步骤,用小写罗马数字标记。如果需要三级以上,则这些规则使用数字标签与第四级重复。例如:

Top-level step
   a. Substep
   b. Substep.
     i. Subsubstep。
       1. Subsubsubstep
         a.Subsubsubsubstep
           i. Subsubsubsubsubstep

  步骤或子步骤可以被写为条件其子步骤的“if”谓词。在这种情况下,只有在谓词为真的情况下才应用子步骤。如果一个步骤或子步骤以“else”一词开始,那么它是一个谓词,它是同一级别上一个“if”谓词步骤的否定。
  步骤可以指定其子步骤的迭代应用。
  以“Assert:”开头的一个步骤说明了其算法的不变条件。这样的断言用于显式算法不变量,否则将是隐式的。这种断言不会增加额外的语义要求,因此不需要由实现来检查。它们仅用于阐明算法。
  数学运算如加法,减法,否定,乘法,除法以及本章后面定义的数学函数应该被理解为计算数学实数的精确数学结果,除非另有说明,否则不包括无穷大,不包括与正零区分的负零。该标准中的浮点运算模型的算法包括明确的步骤,在必要时,处理无穷大并签名为零并执行舍入。如果将数学运算或函数应用于浮点数,则应理解为应用于由该浮点数表示的精确数学值; 这样一个浮点数必须是有限的,并且如果是+ 0或−0则相应的数学值是0。
  数学函数abs(x)产生x的绝对值,即如果x是负数(小于零) 取x,否则是x本身。
  数学函数 sign(x)如果x是正数产生1,如果x是负的产生-1。在这个标准中,当x为0时,sign函数没有使用。
  数学函数min(x1, x2,…,xn)产生 x 1到x n中最小的数。数学函数max(x1, x2,…, xn)产生x 1到x n中最大的数。这些数学函数的范围包括+ ∞和-∞。
  符号“x modulo y”(y必须是有限的,并且非零)计算一个计算与y(或0)相同符号的k值,使得对于一些整数q,abs(k) < abs(y) 并且x−k = q × y。
  数学函数floor(x)产生不大于x的最大整数(最接近正无穷大)。
  注:floor(x)= x - (x模1)。

  5.3静态语义规则
  上下文无关的语法没有足够的功能来表达所有的规则,它们定义输入元素流是否形成可以被评估的有效的ECMAScript 脚本或模块。在某些情况下,需要使用ECMAScript算法约定或散文要求来表达额外的规则。这样的规则总是与语法的产生式相关联,并被称为产生式的静态语义。
  静态语义规则具有名称,通常使用算法定义。命名静态语义规则与语法产生式相关联,并且具有多个替代定义的产生式通常会为每个可应用的命名静态语义规则提供不同的算法。
  除非另有说明,否则本规范中的每个语法产生式替代方案都隐含地具有名为Contains的静态语义规则的定义,该静态语义规则采用名为symbol的参数,其值为包含关联产生式的语法的终端或非终端。Contains的默认定义是:

  1. 对于每个终端和非终结语法符号,sym,在这个产生式的定义中
       a. 如果sym是与 symbol相同的语法符号,则返回true。
       b. 如果sym是非终端的,那么
         i. 令contained 显示 sym包含symbol的结果。
         ii. 如果contained是true,则返回true。
  2. 返回假。

  上述定义明确地被覆盖了特定的产生式。
  一种特殊的静态语义规则是一个早期错误规则。早期的错误规则定义了早期的错误条件(参见第16条),它与特定的语法制作相关联。大多数早期错误规则的评估在本规范的算法中没有显式地调用。在脚本或 模块的首次评估之前,必须验证所有用于解析该脚本或模块的产生式的早期错误规则。如果任何早期错误规则被违反,脚本或模块将无效,无法评估。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值