このページはECMAScript® 2020 Language Specification11 ECMAScript Language: Lexical Grammar章をJavaScriptの学習目的で私的に日本語訳したものであり、直訳と意訳および推測が混在しています。そのため内容については正確ではない可能性があります。正確な情報を知りたい場合は、原文をご覧ください。また一部訳者によるコメントが含まれていることがあります。※このサイトの内容で損害や不利益を受けたとしても当方は一切の責任を負いません。

ECMAScriptScriptおよびModuleのソーステキストは、最初に一連の入力要素(トークン、行末記号、コメント、空白)に変換されます。 ソーステキストは左から右にスキャンされ、可能な限り長いコードポイントのシーケンスを次の入力要素として繰り返し取得します。入力された要素の識別が、入力要素を判定している構文文法コンテキストに影響される状況がいくつかあります。入力要素には、レキシカル文法に複数のゴールシンボルが必要です。 InputElementRegExpOrTemplateTailゴールは、RegularExpressionLiteralTemplateMiddle、またはTemplateTailが許可されている構文文法コンテキストで使用されます。InputElementRegExpゴールシンボルは、RegularExpressionLiteralが許可されていて、TemplateMiddleTemplateTailは許可されていない構文文法コンテキストで使用されます。InputElementTemplateTailゴールは、TemplateMiddleTemplateTailが許可されていて、RegularExpressionLiteralが許可されていない構文文法コンテキストで使用されます。他のコンテキストでは、InputElementDivがレキシカルゴールシンボルとして使用されます。

複数のレキシカルゴールを使用すると、セミコロンの自動挿入に影響するあいまいさがなくなります。 たとえば、先頭のディビジョンまたはディビジョン割り当て、および先頭のRegularExpressionLiteralの両方が許可されている構文文法コンテキストはありません。 これはセミコロン挿入の影響を受けません(11.9を参照)。例:

a = b
/hi/g.exec(c).map(d);

LineTerminatorの後の最初の非空白、非コメントコードポイントがU+002F(SOLIDUS)であり、構文コンテキストで除算または除算割り当てが許可されている場合、LineTerminatorにセミコロンは挿入されません。 つまり、上記の例は次のように解釈されます。

a = b / hi / g.exec(c).map(d);
U+002F は、 /

構文:

11.1 Unicodeフォーマット制御文字(Unicode Format-Control Characters)

Unicodeフォーマット制御文字(LEFT-TO-RIGHTマークなど、Unicode文字データベースのカテゴリ"Cf"の文字)は、これより上位のプロトコル(マークアップ言語など)がない場合に、一連のテキストのフォーマットを制御するために使用される制御コードです。

編集と表示を容易にするために、ソーステキストのフォーマット制御文字を許可すると便利です。 すべてのフォーマット制御文字は、コメント内、文字列リテラル、テンプレートリテラル、および正規表現リテラル内で使用できます。

U+200C(ZERO WIDTH NON-JOINER)および U+200D(ZERO WIDTH JOINER)は、特定の言語で単語または句の区別を行うために使用されるフォーマット制御文字です。 ECMAScriptソーステキストでは、これらのコードポイントは最初の文字の後のIdentifierNameでも使用できます。

U+FEFF(ZERO WIDTH NO-BREAK SPACE)はフォーマット制御文字です。主にテキストの先頭で使用され、Unicodeとしてマークし、テキストのエンコーディングとバイトオーダーを検出できるようにします。 この目的で使用する<ZWNBSP>文字は、たとえばファイルの連結の結果として、テキストの開始後に表示される場合があります。 ECMAScriptソーステキストでは、<ZWNBSP>コードポイントは空白文字として扱われます(11.2を参照)。

表31は、コメント、文字列リテラル、および正規表現リテラル以外の特定のフォーマット制御文字の扱いをまとめています。

表31: フォーマット制御コードポイントの使用法
コードポイント 名称 略称 使用法
U+200C ZERO WIDTH NON-JOINER <ZWNJ> IdentifierPart
U+200D ZERO WIDTH JOINER <ZWJ> IdentifierPart
U+FEFF ZERO WIDTH NO-BREAK SPACE <ZWNBSP> WhiteSpace

11.2 ホワイトスペース(White Space)

空白(White Space)コードポイントは、ソーステキストの読みやすさを向上させ、トークン(分割できない字句単位)を互いに分離するために使用されます。それ以外は重要ではありません。空白コードポイントは、任意の2つのトークン間、および入力の開始または終了時に発生する可能性があります。 空白コードポイントは、StringLiteralRegularExpressionLiteralTemplate、またはTemplateSubstitutionTail内で発生する可能性があり、リテラル値の一部を形成する重要なコードポイントと見なされます。 コメント内でも発生する可能性がありますが、他の種類のトークン内では使用できません。

ECMAScript空白コードポイントを表32に示します。

表32: 空白(ホワイトスペース)コードポイント
コードポイント 名称 略称
U+0009 CHARACTER TABULATION <TAB>
U+000B LINE TABULATION <VT>
U+000C FORM FEED (FF) <FF>
U+0020 SPACE <SP>
U+00A0 NO-BREAK SPACE <NBSP>
U+FEFF ZERO WIDTH NO-BREAK SPACE <ZWNBSP>
他のカテゴリ"Zs" その他のUnicode "Space_Separator"コードポイント <USP>

ECMAScript実装は、"Space_Separator""Zs")カテゴリにリストされているWhiteSpaceコードポイントとして認識する必要があります。

表32にリストされているコードポイント以外のECMAScriptWhiteSpaceは、Unicode "White_Space" プロパティを持ち、カテゴリ "Space_Separator" ("Zs") に分類されていないすべてのコードポイントを意図的に除外します。

構文:

WhiteSpace ::
<TAB>
<VT>
<FF>
<SP>
<NBSP>
<ZWNBSP>
<USP>

11.3 ラインターミネーター(Line Terminators)

空白コードポイントと同様に、ラインターミネータ(行末記号)コードポイントは、ソーステキストの読みやすさを向上させ、トークン(分割できない字句単位)を互いに分離するために使用されます。ただし、空白コードポイントとは異なり、ラインターミネータは構文文法の動作に影響を与えます。ラインターミネータは任意の2つのトークン間に出現する可能性がありますが、構文文法で禁止されている箇所がいくつかあります。ラインターミネータは、セミコロンの自動挿入のプロセスにも影響します(11.9)。StringLiteralTemplateTemplateSubstitutionTail以外のトークン内では、ラインターミネータを使用できません。 <LF>および<CR>行ターミネーターは、LineContinuationの一部として以外は、StringLiteralトークン内に出現できません。

ラインターミネータは、MultiLineComment内に出現できますが、SingleLineComment内には出現できません。

ラインターミネータは、正規表現の\sクラスと一致する空白コードポイントのセットに含まれています。

ECMAScriptのラインターミネータ(行末記号)コードポイントを表33に示します。

表33: ラインターミネータ(行末記号)コードポイント
コードポイント Unicode名 略称
U+000A LINE FEED (LF) <LF>
U+000D CARRIAGE RETURN (CR) <CR>
U+2028 LINE SEPARATOR <LS>
U+2029 PARAGRAPH SEPARATOR <PS>

表33のUnicodeコードポイントのみがラインターミネータとして扱われます。 その他の新しい行または改行Unicodeコードポイントは、ラインターミネータとして扱われませんが、表32にリストされている要件を満たしている場合は空白として扱われます。シーケンス<CR><LF>はラインターミネータとして使用されますが、 行番号を報告するためには、単一のSourceCharacterと見なす必要があります。

構文:

LineTerminator ::
<LF>
<CR>
<LS>
<PS>
LineTerminatorSequence ::
<LF>
<CR>[lookahead<LF>]
<LS>
<PS>
<CR><LF>

11.4 コメント(Comments)

コメントは単一行または複数行にすることができます。 複数行のコメントはネストできません。

単一行コメントには、LineTerminatorコードポイントを除く任意のUnicodeコードポイントを含めることができます。トークンは可能な限り長いという一般的なルールにより、単一行コメントは//マーカーから行末までのすべてのコードポイントで構成されます。 ただし、行末のLineTerminatorは、単一行コメントの一部とは見なされません。 レキシカル文法によって個別に認識され、構文文法の入力要素のストリームの一部になります。 これは非常に重要です。単一行コメントの有無がセミコロンの自動挿入のプロセスに影響しないことを意味するからです(11.9を参照)。

コメントは空白のように動作し、破棄されます。ただし、MultiLineCommentにラインターミネータコードポイントが含まれている場合、構文文法による解析のためにコメント全体がLineTerminatorと見なされます。

例えば、

コード /* コメント\n
コメント\n
コメント */

のとき、
/* から */ までが、改行とみなされる

構文:

11.5 トークン(Tokens)

構文:

DivPunctuatorRegularExpressionLiteralRightBracePunctuator、およびTemplateSubstitutionTailプロダクションは、CommonTokenプロダクションに含まれていない追加のトークンを導出します。

11.6 名前とキーワード(Names and Keywords)

IdentifierNameReservedWordは、いくつかの小さな変更を伴う 「Unicode Standard Annex #31, Identifier and Pattern Syntax」での、既定の識別子構文に従って解釈されるトークンです。 ReservedWordは、IdentifierNameの列挙サブセットです。 構文文法では、IdentifierReservedWordではないIdentifierNameとして定義しています。 Unicode識別子の文法は、Unicode規格で指定されている文字プロパティに基づいています。 最新バージョンのUnicode規格の指定されたカテゴリにあるUnicodeコードポイントは、準拠するすべてのECMAScript実装によって、それらのカテゴリと同様に処理する必要があります。 ECMAScript実装は、Unicode規格の新しいエディションで定義された識別子コードポイントを認識する場合があります。

この規格では、特定の追加コードポイントが指定されています。U+0024(DOLLAR SIGN)およびU+005F(LOW LINE)はIdentifierNameの任意の場所で許可されます。コードポイントU+200C(ZERO WIDTH NON-JOINER)およびU+200D(ZERO WIDTH JOINER)は、IdentifierNameの最初のコードポイントの後であればどこでも許可されます。

Unicodeエスケープシーケンスは、IdentifierNameで使用できます。IdentifierNameでは、単一のUnicodeコードポイントが提供されます。コードポイントは、UnicodeEscapeSequenceCodePointによって表されます(11.8.4を参照)。UnicodeEscapeSequenceの前に\と、uおよび{ }コードユニットがある場合、それらはIdentifierNameにコードポイントを提供しません。UnicodeEscapeSequenceを使用して、コードポイントをIdentifierNameに配置することはできません。つまり、\UnicodeEscapeSequenceシーケンスが、それが提供するSourceCharacterによって置き換えられたとしても、元のIdentifierNameとまったく同じSourceCharacter要素のシーケンスを持つ有効なIdentifierName
である必要があります。この仕様において、すべてのIdentifierNameの解釈は、特定のコードポイントを提供するためにエスケープシーケンスが使用されたかどうかに関係なく、実際のコードポイントに基づきます。

Unicode標準に従って正規に同等である2つのIdentifierNameは、各UnicodeEscapeSequenceを置き換えた後、まったく同じコードポイントのシーケンスで表されない限り、等しくありません。

構文:

UnicodeIDStart ::
Unicodeプロパティが "ID_Start" のUnicodeコードポイント
UnicodeIDContinue ::
Unicodeプロパティが "ID_Continue" のUnicodeコードポイント

非終端UnicodeEscapeSequenceの定義は、11.8.4にあります。

非終端IdentifierPartは、UnicodeIDContinueを介して_を得ます。
Unicodeプロパティが"ID_Start""ID_Continue"のコードポイントのセットのとき、Unicodeプロパティには"Other_ID_Start""Other_ID_Continue"のコードポイントがそれぞれ含まれています。

11.6.1 識別子名(Identifier Names)

11.6.1.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)

UnicodeEscapeSequenceSV"$""_"以外の場合、または、<ZWNJ><ZWJ>UTF16Encodingの場合、またはUnicodeIDContinueレキシカル文法生成と一致するUnicodeコードポイントのUTF16Encodingの場合は、構文エラーです。

11.6.1.2 静的セマンティクス:StringValue(Static Semantics: StringValue)

  1. IdentifierNameに一致するソーステキストを idText とする
  2. idText 内の \UnicodeEscapeSequenceの出現箇所をUnicodeEscapeSequenceで表されるコードポイントに置き換えた結果を、idTextUnescaped とする。
  3. ! UTF16Encode(idTextUnescaped)を返す

11.6.2 キーワードと予約語(Keywords and Reserved Words)

キーワード

キーワードは、IdentifierNameに一致するトークンです。ただし、一部の構文プロダクション中の固定幅フォントは、その文字通り適用されます。 ECMAScriptのキーワードには、ifwhileasyncawaitなどが含まれます。

予約語

予約語は、識別子として使用できないIdentifierNameです。 多くのキーワードは予約語ですが、一部はそうではなく、特定のコンテキストでのみ予約されています。 ifwhileは予約語です。 awaitは、非同期関数およびモジュール内でのみ予約されています。 asyncは予約されていません。 制限なしで変数名またはステートメントラベルとして使用できます。

この仕様では、文法的なプロダクションと早期エラールールの組み合わせを使用して、有効な識別子名と予約語名を指定します。 以下の構文:ReservedWordとしてリストされているすべてのトークンは、awaityieldを除いて、無条件に予約されています。awaityieldの例外は、12.1でパラメーター化された構文プロダクションを使用して指定されています。 最後に、いくつかの早期エラールールは、有効な識別子の組み合わせを制限します。 12.1.113.3.1.113.7.5.114.6.1を参照してください。 大きく分けて、識別子名には5つのカテゴリがあります。

  • 識別子として常に許可されており、キーワードではないもの(MathwindowtoString_など)。
  • 識別子として決して許可されないもの(awaityieldを除いて、以下の構文:にリストされているReservedWord)。
  • 識別子としてコンテキスト上許可されているもの(awaityield)。
  • strictモードコードで、識別子としてコンテキスト上許可されていないもの(letstaticimplementsinterfacepackageprivateprotectedpublic)。
  • 識別子として常に許可されているが、Identifierが許可されていない場所(asasyncfromgetofsettarget)で特定の構文プロダクション内のキーワードとしても表示されるもの。

条件付きキーワードまたはコンテキストキーワードという用語は、最後の3つのカテゴリに分類されるキーワードを指すために使用されることがあります。そのため、この二つのキーワードは、一部のコンテキストでは識別子として、別のコンテキストではキーワードとして使用できます。

構文:

ReservedWord :: どれかひとつ
awaitbreakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimportininstanceofnewnullreturnsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield
5.1.5により、文法のキーワードは特定のSourceCharacter要素のリテラルシーケンスと一致します。 キーワードのコードポイントは、\ UnicodeEscapeSequenceでは表現できません。IdentifierNameには\ UnicodeEscapeSequenceを含めることができますが、 "else"という名前の変数をels\u{65}のように宣言することはできません。 12.1.1早期エラールールは、予約語と同じStringValueを持つ識別子を除外します。

enumは現在、キーワードとして使用されていません。 これは将来の予約語であり、将来の言語拡張でキーワードとして使用するために予約してあります。strictモードコードでは、implementsinterfacepackageprivateprotectedpublicが、将来の予約語です。

argumentsevalはキーワードではありません。ただし、strictモードコードではいくつかの制限を受けます。 12.1.112.1.314.1.214.4.114.5.1、および14.7.1を参照してください。

11.7 句読点(Punctuators)

構文:

OtherPunctuator :: どれかひとつ
{()[]....;,<><=>===!====!==+-*%**++--<<>>>>>&|^!~&&||???:=+=-=*=%=**=<<=>>=>>>=&=|=^==>

11.8 リテラル(Literals)

11.8.1 Nullリテラル(Null Literals)

構文:

NullLiteral ::
null

11.8.2 Booleanリテラル(Boolean Literals)

構文:

BooleanLiteral ::
true
false

11.8.3 数値リテラル(Numeric Literals)

構文:

DecimalDigit :: どれかひとつ
0123456789
NonZeroDigit :: どれかひとつ
123456789
ExponentIndicator :: どれかひとつ
eE
BinaryDigit :: どれかひとつ
01
OctalDigit :: どれかひとつ
01234567
HexDigit :: どれかひとつ
0123456789abcdefABCDEF

NumericLiteralの直後のSourceCharacterは、IdentifierStartまたはDecimalDigitであってはなりません。

例:3inはエラーであり、2つの入力要素3inではありません。

B.1.1で説明されているように、準拠実装はstrictモードコードを処理するときに、NumericLiteralの構文を拡張してLegacyOctalIntegerLiteralを含めたり、DecimalIntegerLiteralの構文を拡張してNonOctalDecimalIntegerLiteralを含めたりしてはなりません。

11.8.3.1 静的セマンティクス(Static Semantics):MV

数値リテラルは、Number型またはBigInt型の値を表します。

MV:mathematical value(数学的数値)

11.8.3.2 静的セマンティクス(Static Semantics):NumericValue

  1. DecimalLiteralMVを以下の方法により丸めた結果の数値を返す
  1. NonDecimalIntegerLiteralMVを以下の方法により丸めた結果の数値を返す

数値リテラルの正確なMVが決定後、数値タイプの値に丸めます。MV0の場合、丸めた値は+0です。MV0でなく、リテラルがDecimalLiteralで有効桁数が20桁以下の場合、丸めた値はMVの数値(6.1.6.1)です。この場合、数値は数値のいずれかになります。有効桁数が20桁を超える場合、リテラル上の20桁目以降を0に置き換えた値、または置き換え後20桁目を+1した値のMVのNumber値になります。 ExponentPartの一部ではない場合、数字は有効です。そして、

  • それは 0 ではありません。 または、
  • 左側にゼロ以外の数字があり、その右側にExponentPartではない非ゼロの数字があります。
  1. NonDecimalIntegerLiteralMVを表すBigInt値を返す
  1. 0を表すBigInt値を返す
  1. NonZeroDigitMVを表すBigInt値を返す
  1. DecimalDigitsのコードポイントの数学的整数 を n とする
  2. (NonZeroDigitMV × 10n) + DecimalDigitsMVmv とする
  3. mvを表すBigInt値を返す

11.8.4 文字列リテラル(String Literals)

文字列リテラルは、一重引用符または二重引用符で囲まれた0個以上のUnicodeコードポイントです。 Unicodeコードポイントは、エスケープシーケンスで表すこともできます。 終了引用符のコードポイント、U+005C(REVERSE SOLIDUS)、U+000D(CARRIAGE RETURN)、およびU+000A(LINE FEED)を除いて、すべてのコードポイントは文字列リテラルにそのまま組み込まれます。 コードポイントはエスケープシーケンスの形式で表示されます。 文字列リテラルはECMAScript String値として評価されます。 String値は、UnicodeコードポイントをUTF-16でエンコードして生成されます(10.1.1)。 Basic Multilingual Planeに属するコードポイントは、単一のコードユニット要素としてエンコードされます。 その他のコードポイントは、2つのコードユニット要素としてエンコードされます。

構文:

strictモードコードを処理する場合、準拠実装は、B.1.2で説明されているようにLegacyOctalEscapeSequenceを含めるようにEscapeSequenceの構文を拡張してはいけません。

SingleEscapeCharacter :: どれかひとつ
'"\bfnrtv

非終端HexDigitの定義は11.8.3にあります。 SourceCharacter10.1で定義しています。

空のコードポイントシーケンスを生成するLineContinuationの一部として以外は、<LF><CR>を文字列リテラルに含めることはできません。 これらを文字列リテラルとして使用するには、\n\u000Aなどのエスケープシーケンスが適切です。

11.8.4.1 静的セマンティクス(Static Semantics):StringValue

  1. コード単位がStringLiteralSVであるString値を返す

11.8.4.2 静的セマンティクス(Static Semantics):SV

文字列リテラルは、String型の値を表します。 String値(SV:String value)は、さまざまなパーツからなる文字列リテラルから生成されます。 一部の生成プロセスでは、文字列リテラル内の一部のUnicodeコードポイントを、以下のリストや11.8.3のように、数学値(MV)として解釈されます。

11.8.5 正規表現リテラル(Regular Expression Literals)

正規表現リテラルは、リテラルが評価されるたびにRegExpオブジェクト(21.2を参照)に変換される入力要素です。 プログラム内では、同じ内容の正規表現リテラルであっても、===での比較結果が同じではない正規表現オブジェクトが生成されます。 RegExpオブジェクトは、実行時にnew RegExpによって、または関数としてRegExpコンストラクターを呼び出すことで作成できます(21.2.3を参照)。

以下のプロダクションは、正規表現リテラルの構文の説明です。プロダクションは、正規表現リテラルの終わりを見つけるために使用されます。 次に、RegularExpressionBodyRegularExpressionFlagsを構成するソーステキストを、より厳密なECMAScript正規表現文法(21.2.1)で再度解析します。

実装は21.2.1で定義されたECMAScript正規表現文法を拡張できますが、以下で定義されたRegularExpressionBodyRegularExpressionFlagsプロダクション、またはこれらのプロダクションで使用されるプロダクションを拡張してはいけません。

構文:

正規表現リテラルは空にできません。 //は単一行コメントとして解釈されます。 空の正規表現は、/(?:)/を使用します。

11.8.5.1 静的セマンティクス:早期エラー(Static Semantics: Early Errors)

  • IdentifierPart にUnicodeエスケープシーケンスが含まれている場合は、構文エラーです。

11.8.5.2 静的セマンティクス(Static Semantics):BodyText

  1. RegularExpressionBody として認識されたソーステキストを返す

11.8.5.3 静的セマンティクス(Static Semantics):FlagText

  1. RegularExpressionFlags として認識されたソーステキストを返す

11.8.6 テンプレートリテラルレキシカルコンポーネント(Template Literal Lexical Components)

構文:

NotCodePoint ::
HexDigits HexDigitsMV > 0x10FFFF
CodePoint ::
HexDigits HexDigitsMV ≦ 0x10FFFF

準拠実装は、TemplateCharacterの解析で、B.1.2で説明されているEscapeSequenceの拡張定義を使用しないでください。

11.8.6.1 静的セマンティクス:TVTRV(Static Semantics: TV and TRV)

テンプレートリテラルコンポーネントは、Unicodeコードポイントのシーケンスとして解釈されます。リテラルコンポーネントのテンプレート値(TV)は、さまざまなテンプレートリテラルコンポーネントのパーツからなるコードユニット値(SV:11.8.4)から生成されます。特定のプロセスでは、一部のUnicodeコードポイントは、数学的な値を持つと解釈されます(MV:11.8.3)。TVを決定する際、エスケープシーケンスは、UnicodeコードポイントのUTF-16コードユニットに置き換えられます。 テンプレートRaw値(TRV)はテンプレート値に似ていますが、TRVではエスケープシーケンスが文字どおりに解釈される点が異なります。

TVには LineContinuation のコードユニットが含まれていませんが、TRVには含まれています。 <CR><LF>および <CR>LineTerminatorSequenceは、TVTRVの両方で<LF>に正規化されます。 <CR>または<CR><LF>シーケンスを含めるには、明示的なEscapeSequenceが必要です。

11.9 セミコロンの自動挿入(Automatic Semicolon Insertion)

ほとんどのECMAScriptステートメントと宣言は、セミコロンで終了する必要があります。 ただし、便宜上、特定の状況でセミコロンはソーステキストから省略される場合があります。 これらの状況では、セミコロンが自動的にソースコードトークンストリームに挿入されます。

11.9.1 セミコロンの自動挿入のルール(Rules of Automatic Semicolon Insertion)

以下の規則では、「トークン」は、11章で説明されている現在のレキシカルゴールシンボルを使用して決定された、実際に認識された字句トークンを意味します。

セミコロン挿入には3つの基本的ルールがあります。

  1. ソーステキスト解析中に、プロダクションで許可されていないトークン(問題のトークンとする)が検出され、次の条件に一つ以上該当する場合、問題のトークンの前にセミコロンが挿入されます。
    • 問題のトークンの前に、1つ以上のLineTerminatorがある
    • 問題のトークンは、} である
    • 問題のトークンの前のトークンが ) である。挿入されたセミコロンは、do-whileステートメントの終了セミコロンとして解析される(13.7.2
  2. ソーステキスト解析中にトークンの入力ストリームの終わりが検出され、入力トークンストリームをゴール非終端の単一インスタンスとして解析できない場合、入力ストリームの終わりにセミコロンが挿入されます。
  3. ソーステキスト解析中に検出されたプロダクションが下記の制限されたプロダクションで、トークンがそのプロダクション内の注釈"[no LineTerminator here]"直後のトークンのとき、そのトークンは制限付きトークンと呼ばれます。制限付きトークンが、1つ以上のLineTerminatorによって前のトークンから分離されているとき、制限付きトークンの前にセミコロンが挿入されます。

前述のルールには追加のオーバーライド条件があります。セミコロンが空のステートメントとして解析される場合、またはセミコロンがforステートメントのヘッダー内2つのセミコロンの1つになる場合、セミコロンは自動的に挿入されません(13.7.4を参照)。

文法で制限されていプロダクションは次のとおりです。

UpdateExpression[Yield, Await] :
LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here]++
LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here]--
ContinueStatement[Yield, Await] :
continue;
continue[no LineTerminator here]LabelIdentifier[?Yield, ?Await] ;
BreakStatement[Yield, Await] :
break;
break[no LineTerminator here]LabelIdentifier[?Yield, ?Await] ;
ReturnStatement[Yield, Await] :
return;
return[no LineTerminator here]Expression[+In, ?Yield, ?Await] ;
ThrowStatement[Yield, Await] :
throw[no LineTerminator here]Expression[+In, ?Yield, ?Await] ;
ArrowFunction[In, Yield, Await] :
ArrowParameters[?Yield, ?Await] [no LineTerminator here]=>ConciseBody[?In]
YieldExpression[In, Await] :
yield
yield[no LineTerminator here]AssignmentExpression[?In, +Yield, ?Await]
yield[no LineTerminator here]*AssignmentExpression[?In, +Yield, ?Await]

制限されたプロダクションの実際的な効果:

  • 後置演算子++または--トークンが検出され、前のトークンと++または--トークンの間に1つ以上のLineTerminator
    がある場合、セミコロンが++または--の前に自動的に挿入されます。
  • continuebreakreturnthrowyieldトークンが検出され、LineTerminator
    が次のトークンの前に検出されると、continuebreakreturnthrowyieldトークンの後にセミコロンが自動的に挿入されます。

ECMAScriptプログラマーへの実用的なアドバイス:

  • 後置++または--演算子は、そのオペランドと同じ行にある必要があります。
  • returnまたはthrowステートメントの式、またはyield式のAssignmentExpressionは、returnthrow、またはyieldトークンと同じ行で開始する必要があります。
  • breakまたはcontinueステートメントのLabelIdentifierは、breakまたはcontinueトークンと同じ行にある必要があります。
いろいろ面倒な制限を覚えるより、セミコロンを省略しないことが実用的なアドバイスではないかと思う。

11.9.2 セミコロンの自動挿入の例(Examples of Automatic Semicolon Insertion)

このセクションは非規範的です。

次のソースがあるとします。

{ 1 2 } 3

これは自動セミコロン挿入ルールがあっても、ECMAScript文法では有効な文ではありません。

次のソースがあるとします。

{ 1
2 } 3

これも有効なECMAScript文ではありませんが、セミコロンの自動挿入によって次のように変換されます。

{ 1
;2 ;} 3;

これは有効なECMAScript文です。

次のソースがあるとします。

for (a; b
)

これは有効なECMAScript文でありません。forステートメントのヘッダーにセミコロンが必要なため、セミコロンの自動挿入によって変更されません。 セミコロンの自動挿入では、forステートメントのヘッダーに2つのセミコロンのいずれかが挿入されることはありません。

次のソースがあるとします。

return
a + b

これはセミコロンの自動挿入によって次のように変換されます。

return;
a + b;

a + bは、LineTerminatorがトークンreturnから分離するため、returnステートメントによって返される値として扱われません。

次のソースがあるとします。

a = b
++c

これはセミコロンの自動挿入によって次のように変換されます。

a = b;
++c;

トークン++は、変数bに適用される後置演算子としては扱われません。これは、b++の間にLineTerminatorが発生するためです。

次のソースがあるとします。

if (a > b)
else c = d

これは有効なECMAScript文ではありません。elseトークンの前はセミコロンの自動挿入によって変更されません。ただし、自動挿入されたセミコロンは空のステートメントとして解析されるため、その時点では文法のプロダクションは適用されません。

次のソースがあるとします。

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

このソースは、2行目の括弧を一行目のcという関数の引数リストとして解釈できるため、セミコロンが自動挿入されません。

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

代入ステートメントが左括弧で始まる必要がある状況では、自動セミコロンの挿入に依存するよりも、プログラマーが前のステートメントの終わりに明示的なセミコロンを提供することをお勧めします。

(再)いろいろ面倒な制限を覚えるより、セミコロンを省略しないことが実用的なアドバイスではないかと思う。

11.10 自動セミコロン挿入の興味深いケース(Interesting Cases of Automatic Semicolon Insertion)

このセクションは非規範的です。

ECMAScriptプログラムは、セミコロンの自動挿入により、セミコロンがほとんどないスタイルで記述できます。 上記のように、セミコロンはすべての改行に挿入されるわけではありません。セミコロンの自動挿入は、行の終了記号にまたがる複数のトークンに依存する可能性があります。

ECMAScriptに新しい構文機能が追加されると、文法プロダクションが増えます。結果として、正しく解釈されていたソーステキストが、文法追加により正しく解釈されない可能性があります。

セミコロンの自動挿入は、先行するソーステキストに応じて、セミコロンが挿入される場合と挿入されない場合があります。 このセクションの残りの部分では、ECMAScriptのこのバージョンでのセミコロンの自動挿入の興味深いケースについて説明します。

11.10.1 ステートメントリストでのセミコロンの自動挿入の興味深いケース(Interesting Cases of Automatic Semicolon Insertion in Statement Lists)

StatementListは、多くのStatementListItem
がセミコロンで終了します。ただし、セミコロンの自動挿入を使用して省略できます。 上記のルールの結果として、式を終了する行の終わりで、次の行が次のいずれかで始まる場合はセミコロンが必要です。

  • 左括弧 "(" 。セミコロンがない場合、2つの行はCallExpressionとして扱われます。
  • 開き角括弧 "[" 。 セミコロンがない場合、2つの行は、プロパティアクセスとして扱われます。ArrayLiteralまたはArrayAssignmentPatternではありません。
  • テンプレートリテラル "`"。 セミコロンがない場合、2つの行はタグ付きテンプレート(12.3.11)として、前の式はMemberExpressionとして解釈されます。
  • 単項+または-。 セミコロンがない場合、2つの行は、2項演算子を使用しているとして解釈されます。
  • RegExpリテラル。 セミコロンがない場合、たとえば、RegExpにフラグがある場合、2つの行が一緒に/MultiplicativeOperatorとして解析されることがあります。

11.11 セミコロン自動挿入の事例と"[no LineTerminator here]"(Cases of Automatic Semicolon Insertion and “[no LineTerminator here]”)

このセクションは非規範的です。

ECMAScriptには、"[no LineTerminator here]" を含んでいる文法プロダクションがあります。 これらのプロダクションは、オプションのオペランドを持つ場合があります。 これらの場所にLineTerminatorを導入すると、オプションのオペランドなしで文法プロダクションを使用することにより、ソーステキストの文法生成が変更されます。

このセクションの残りの部分では、このバージョンのECMAScriptで"[no LineTerminator here]"を使用する多くのプロダクションについて説明します。

11.11.1 オプションのオペランドと"[no LineTerminator here]"を含む文法プロダクションのリスト(List of Grammar Productions with Optional Operands and “[no LineTerminator here]”)