语义
5.1 句法和语法
5.1.1 上下文无关语法
一个上下文无关的语法包含一系列产生式productions。每个产生式都有一个叫做非终端符的抽象符号作为左位,然后一系列零个或者多个非终端符或者终端符作为右位。对于每个语法来说,每个终端符都来源于一张特殊的符号表。
一个链式生产式的右位有切仅有一个非终端符加上另个或多个终端符。(2016单独加的)
当从一个叫做 目标符goal symbol 的特殊非终端符组成的句子起始,那么给出的上下文无关文法就表示 语言 language,即,将产生式右边序列的非终结符当作左边,进行反复替换的结果就成为可能的终结符序列集合可能无限。
5.1.2 词法和正则语法
EMCAScript的词法在11章会的提到。该语法有它自己的根据10.1章定义的源字符终端符编码单元。他定义了一系列的产生式,从目标符InputElementDiv,InputElementTemplateTail,InputElementTefExp,InputElementRegExpOrTemplateTail开始,描述源字符序列是如何被翻译成输入元素序列的。
除了空格和注释的输入元素构成EMACScript句法的终端符,叫做ECMAScript token。这些Tokens是ECMAScript 语言的保留字,标识符,字面量,标点符号。以及,尽管不能作为tokens,行结束符也会作为输入元素流的一部分,并自动插入分号(11.9)。单独的空格和单行注释会被抛弃而不会出现在句法的元素输入流中。多行注释(由/.../所构成,无论是不是一行都会被忽略)如果不含行结束符就会单纯的直接被忽略,单如果一个多行注释包括一个或者多个行结束符,它就会被一个行结束符替换,然后成为句法的输入元素流中的一部分。
一个ECMAScript正则表达式语法在本说明21.2.1中。该语法有由SourceCharacter定义的代码作为终端符。这里定义了一些列产生式,以目标符Pattern开始,这描述了代码学了是如何转义成常规表达式的。
词法和正则语法的产生式由 含有两个“::”作为分割标点来做为区别。正则和词法语法共享一部分产生式。
5.1.3 数字字符串语法
另一个语法用来将字符串转换成数值。该语法类似于一部分处理数值字面量的词法,并有SourceCharacter的终端符。该语法在7.1.3.1中出现。
数值语法产生式由作为标点的“:::”来做识别。
5.1.4 句法
ECMAScript句法在11、12、13、14和15章中讲解。这语法由词法定义的ECMAScript tokens作为终端符。该语法定义一系列产生式,从两个描述了语法正确的 ECMAScript 程序应该怎样排列 tokens的选择目标符号Script和Module开始。
当代码流被解析成一个ECMAScript脚本或者模块时,它首先通过重复调用词法语法而被转换成一个输入元素流;之后由负责句法的单应用来解析这段输入元素流。如果输入流中的tokens不能被解析为(脚本或者模型)目标终端符的单实例,又没有额外的tokens剩下,则该输入流属于句法错误。
只含有一个“:”作为标点是产生式句法的标识。
12 13 14 15章中介绍的句法并不是一个正确ECMAScript脚本或者模型能接受的所有token的完整集合。某些额外的tokens序列也能被接受,特别来说,如那些语法描述的那样,分号被添加在句子里正确的地方(比如说位于行结束符字符之前)。更多,比如一个行结束符出现在确定的“awkward”位置这种情况,根据的语法描述这些特定的token序列是不能被接受的。
(以下为ecmascript2016额外内容)
某些特定情况下,为了避免句法产生的歧义,句法使用通用产生式允许token序列不构成一个有效的ECMAScript脚本或模型。举个例子,这个技巧用在对象字面量和对象解析模式里,在该情形下,一个有更多限制的补充语法会在将来限制可接受的token序列。在某些情况下,当显式指定,输入元素对应于这样一个生产再次解析使用目标补充语法的象征。如果输入流中的token由语法解析时不能作为被解析成一个对应的补充目标符号的单一实例,输入流在句法上是错误的。
5.1.5 语法符号
正则、词法结束符,以及数字字符串语法都用等宽字体显示,论是在文法的产生式,还是贯穿本规范的所有文本直接给出的终结符。他们的出现用来表示脚本写的正确。所以按照该方法规定的终结符代码点被理解成源自基础拉丁语范围中的Unicode编码,而不是任何其他看上去可能的unicode范围。
无终端符使用斜体显示。对于无终端符(也叫产生式)的定义,由非终结符名称和其后定义的一个或多个冒号给出(冒号数量决定产生式从属的语法)。一个或多个可供选择的代替子会紧跟在非终结符的右侧。如以下语法定义
*WhileStatement :*
**while (** *Expression* **)** *Statement*
声明以下非终结符WhileStatement表示tokenWhile,然后跟随者一个括弧token,然后跟着一个Expression(语句),然后跟着一个反括弧token,然后接着一个Statement。Expression(语句)和Statement(声明)本身都是非终端服。另一个例子中,句法都如此定义:
*ArgumentList*
*AssignmentExpression*
*ArgumentList, AssignmentExpression*
声明以下一个ArgumentList(参数列)或许表示一个单独的AssignmentExpression(赋值表达式)或者一个ArgumentList(参数列),然后跟着一个逗号,然后跟着AssignmentExpression(赋值表达式)。这种参数列定义的定义是递归的,即是,它自己定义自己。结果就是一个ArgumentList可能包含正数个由逗号分隔的参数,每个参数表达式都是一个AssignmentExpression。这种非终结符的递归定义很常见。
在一个终结符或者非终结符后面会出现下标“opt”,表明这是个可选符号。实际上包含可选符号的替代子包含两个右边,一个是省略可选元素的,另一个是包含可选元素的。这表示:
VariableDeclaration:
BindingIdentifire Initializer opt
是以下的简便缩写:
VariableDeclaration:
BindingIdentifier
BindingIdentifer Initializer
以及
IterationStatement:
for ( LexicalDeclaration Expression opt ; Expression opt ) Statement
是以下的简便缩写:
IterationStatement
for ( LexicalDeclearation ; Expression opt ) Statement
for ( LexicalDeclearation Expresstion ; Expression opt ) Statement
最终是以下的简写
IterationStatement
for ( LexicalDeclearation ) Statement
for ( LexicalDecleafation ; Expression ) Statement
for ( LexicalDeclearation Expression ; ) Statement
for ( LexicalDeclearation Expression ; Expression ) Statement
所以,在本例中,非终端迭代语句实际上有4个右侧符 (之前的版本是8个)
一个产生式也许由按照"[parameters]"结构的下标注释参数化。这个会被产生式定义成非终端符号的下标。“parametes(下标状态)”可能是一个单独的名称或者是由逗号分隔的名称数组。一个参数化的的产生式意思咧由参数名称定义的产生式的快速写法。由底层核心执行,最后直行程参数化非终端符号。如下所示
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
以及
StatementList:
ReturnStatement
ExpressionStatement[~In]
等同于
StatementList:
ReturnStatement
ExpressionStatement