May 30, 2007

ECMA-262试译:7.9 Automatic Semicolon Insertion

7.9 自动分号插入

空语句,变量语句,表达式语句,do-while 语句,continue 语句,break 语句,return 语句,以及 throw 语句,这些确定的 ECMAScript 语句必须以分号结束。这些分号可以总是明确地出现在源代码文本中。为方便起见,在特定的情况下,源代码文本中的这些分号可以被省略。在下面描述的这些情况中,分号被自动插入源代码托肯流。

7.9.1 自动分号插入的规则

  • 从左到右解析程序时,若遇到不被任何产生式允许的托肯(被称为 违规托肯), 于是,在下列情况一个或多个为真的违规托肯之前自动插入一个分号:
    1. 该违规托肯与前一个托肯之间以至少一个行结束符分隔开。
    2. 该违规托肯是 }
  • 从左到右解析程序时,若遇到输入托肯流的结尾,且解析器无法把此输入的托肯流解析为单个完整的 ECMAScript ,程序,于是在这个输入流的结束处自动插入一个分号。
  • 从左到右解析程序时,若遇到的托肯被一些文法的产生式允许,但该产生式是非严格产生式, 且此托肯是终结符或非终结符的第一个托肯,此终结符或非终结符后紧跟着的是非严格产生式中的记法"[no 行结束 符 here]"(因此这样的托肯被称为非严格托肯)。当非严格托肯与前一个托肯之间以至少一个行结束符分 隔开时,在此非严格托肯前自动插入一个分号。

不过,有一种附加的情况凌驾于优先规则:如果此分号将被解析为空语句,或那个分号将成为一个 for 语句头中的两个分号之一,决不自动插入分号(参见12.6.3)。

NOTE
这些是文法中仅有的非严格产生式。

后缀表达式 :
左侧表达式 [no LineTerminator here] ++
左侧表达式 [no 行结束符 here] --

Continue语句 :
continue [no 行结束符 here] 标识符opt ;

Break语句 :
break [no 行结 束符 here] 标识符opt ;

Return语句 :
return [no 行 结束符 here] 表达式opt ;

Throw语句 :
throw [no 行结 束符 here] 表达式 ;

这些非严格产生式的实际效果如下所示:

  • 若遇到托肯 ++-- ,解析器将视其为一个后缀运算符时,且在提前托肯与托肯 ++-- 之间有至少一个行结束符,则在托肯 ++-- 前自动插入一个分号。
  • 若遇到托肯 continue, break, return,throw,且在下一个托肯之前遇到一个 行 结束符,在 continue, break, return,throw 之后自动插入一个分号。

最后给 ECMAScript 程序员一些忠告:

  • ++-- 应和其操作数出现在同一行。
  • returnthrow 语句中的表达式应和托肯 returnthrow 出现在同一行。
  • breakcontinue 语句中的标签应和托肯 breakcontinue 出现在同一行。

7.9.2 自动分号插入的例子

源代码

{ 1 2 } 3

即使应用自动分号插入规则,它也不是 ECMAScript 文法中的合法句子。作为对比,源代码

{ 1

2 } 3

同样不是 ECMAScript 中的合法句子,却会被自动分号插入变形为下面的形式:

{ 1
;2 ;} 3;

这就是一个回复的 ECMAScript 句子了。

源代码

for (a; b
)

不是合法的 ECMAScript 句子,且因 for 语句头需要分号,句子无法被自动分号插入调整。自动分号插入决不插入 for 语句头中的两个分号之一。

源代码

return
a + b

被自动分号插入变形为下面的形式:

return;
a + b;

NOTE
这里的表达式 a + b 不被作为 return 语句的值返回,因为'行结束符'把它和托肯 return 分隔开了。

源代码

a = b
++c

被自动分号插入变形为下面的形式:

a = b;
++c;
NOTE
这里的托肯 ++ 不被视为应用于变量 b 的后缀运算符,因为在 b++ 之间存在一个'行结束符'。

源代码

if (a > b)
else c = d

不是合法的 ECMAScript 句子,且即使没有文法产生式引用于此,在 else 托肯之前的句子无法被自动分号插入调整,因为被自动插入的分号将被解析为一个空语句。

源代码

a = b + c
(d + e).print()

被自动分号插入变形,因为第二行开始的括号表达式可以解释为函数调用的参数列表:

a = b +c(d + e).print()

在这种状况下,赋值表达式必须以一个左括号为开始。在提前的语句结尾处提供一个清晰的分号而不依赖于自动分号插入,对于程序员来说是个好想法。


//这一篇好像很有用的样子~~

1 comment:

Anonymous said...

托肯就跟鲁棒性、艾真体一样读起来怪怪的……