5.1 構文文法とレキシカル文法(Syntactic and Lexical Grammars)
5.1.1 文脈自由文法(Context-Free Grammars)
文脈自由文法は多くのプロダクションで構成されています。各プロダクションには、左側に非終端シンボルと呼ばれる抽象的なシンボルがあり、右側に0個以上の非終端シンボルと終端シンボルのシーケンスがあります。 文法ごとに、終端シンボルは指定されたアルファベットから描かれます。
次のような定義がプロダクション。
ArgumentList :
AssignmentExpression
ArgumentList , AssignmentExpression
ArgumentListというプロダクションの内容を定義している。
終端シンボル:そのままソース上に入力する文字
非終端シンボル:プロダクション名。
true ←終端シンボル
false ←終端シンボル
連鎖プロダクションとは、右側に非終端シンボルが1つだけあり、0個以上の終端シンボルがあるプロダクションです。
ゴールシンボルと呼ばれる非終端記号から始まり、与えられた文脈自由文法は言語を特定します。すなわち、プロダクションは右側の非終端シンボルが、対応するプロダクトと置き換わり、最終的に終端シンボルになるまで繰り返えします。
ということ。
5.1.2 レキシカルと正規表現の文法(The Lexical and RegExp Grammars)
ECMAScriptのレキシカル文法は、11章で説明されています。この文法は、10.1で定義されているSourceCharacterの規則に準拠するUnicodeコードポイントを終端シンボルとして持っています。
ゴールシンボル
これは、一連のプロダクションを定義し、ゴールシンボル(InputElementDiv、InputElementTemplateTail、InputElementRegExp、またはInputElementRegExpOrTemplateTail)から始まり、そのようなコードポイントのシーケンスが入力要素のシーケンスにどのように変換されるかを記述します。
空白とコメント以外の入力要素は、ECMAScriptの構文文法の終端シンボルを形成し、ECMAScriptトークンと呼ばれます。これらのトークンは、ECMAScript言語の予約語、識別子、リテラル、および句読点です。さらに、ラインターミネーターはトークンとは見なされませんが、入力要素のストリームの一部にもなり、自動セミコロン挿入のプロセスをガイドします(11.9)。単純な空白と単一行コメントは破棄され、構文文法の入力要素のストリームには表示されません。MultiLineComment(つまり、複数行にまたがるかどうかに関係なく、/ *…* /の形式のコメント)も、行末記号が含まれていない場合は単純に破棄されます。ただし、MultiLineCommentに1つ以上の行ターミネーターが含まれている場合は、単一の行ターミネーターに置き換えられ、構文文法の入力要素のストリームの一部になります。
ECMAScriptの正規表現文法は21.2.1にあります。 この文法は、SourceCharacterで定義されているコードポイントを終端シンボルとしても持っています。これは、一連のコードポイントのシーケンスが正規表現パターンにどのように変換されるかを記述する、ゴールシンボルパターンから始まる一連の生成を定義します。
この仕様で2つのコロン「::」を使用している式は、レキシカル文法と正規表現文法です。字句および正規表現文法は、いくつかの結果を共有します。
5.1.3 数値文字列文法(The Numeric String Grammar)
数値文字列文法は、文字列を数値に変換するために使用されます。この文法は、数値リテラルに関連する字句文法の一部に似ており、その終端シンボルとしてSourceCharacterを持っています。この文法は7.1.4.1で解説しています。
この仕様で3つのコロン「:::」を記載している式は、数値文字列文法です。
5.1.4 構文文法(The Syntactic Grammar)
ECMAScriptの構文文法は、11、12、13、14、および15章に記載されています。この文法には、レキシカル文法によって終端シンボルとして定義されたECMAScriptトークンがあります(5.1.2)。これは、2つの代替目標シンボルであるScriptとModuleから始まる一連の生成を定義し、トークンのシーケンスがECMAScriptプログラムの構文的に正しい独立したコンポーネントをどのように形成するかを記述します。
コードポイントのストリームをECMAScriptスクリプトまたはモジュールとして解析する場合、まず、レキシカル文法を繰り返し適用することにより、入力要素のストリームに変換されます。この入力要素のストリームは、構文文法の単一のアプリケーションによって解析されます。入力要素のストリーム内のトークンを目的の非終端(ScriptまたはModule)の単一インスタンスとして解析できず、トークンが残っていない場合、入力ストリームは構文的にエラーになります。
パースノード
解析が成功すると解析ツリー、つまり各ノードがパース(解析)ノードであるルート化されたツリー構造を構築します。各パースノードは、文法内のシンボルのインスタンスです。これは、そのシンボルから派生できるソーステキストの範囲を表します。ソーステキスト全体を表す解析ツリーのルートノードは、解析のゴールシンボルのインスタンスです。パースノードが非終端シンボルのインスタンスである場合、それはその非終端シンボルを左側に持ついくつかのプロダクションのインスタンスでもあります。さらに、プロダクションの右側にあるシンボルごとに1つずつ、0個以上の子があります。各子は、対応するシンボルのインスタンスであるパースノードです。
同じパースノード
新しいパースノードはパーサーの呼び出しごとにインスタンス化され、同一のソーステキストであっても、パース間で再利用されることはありません。パースノードは、ソーステキストの同じスパンを表し、同じ文法シンボルのインスタンスであり、同じパーサー呼び出しの結果である場合に限り、同じパースノードと見なされます。
let str = "1 + 1;"; eval(str); eval(str);
evalを呼び出すたびに、strの値がECMAScriptソーステキストに変換され、独立した解析を実行して、独自の個別の解析ノードのツリーを作成します。各解析は同じString値から派生したソーステキストを操作しますが、ツリーは異なります。
この仕様で3つのコロン「:」を一つだけ記載されている式は、構文文法です。
12、13、14、および15章に示されている構文文法は、どんなトークンシーケンスが正しいECMAScriptScriptまたはModuleとして受け入れられるかを完全に説明するものではありません。特定の追加のトークンシーケンスも受け入れられます。つまり、シーケンスに特定の場所(行終端文字の前など)でセミコロンのみが追加された場合に文法で記述されるトークンシーケンスも受け入れられます。さらに、文法で記述されている特定のトークンシーケンスは、行のターミネーター文字が特定の「ぎこちない」場所にある場合、許容できないと見なされます。
カバー
あいまいさを回避するために特定のケースにおいて構文文法は、有効なECMAScriptScriptまたはModuleを形成しないトークンシーケンスを許可する一般化された生成を使用します。たとえば、この手法はオブジェクトリテラルとオブジェクトの構造化パターンに使用されます。このような場合、より制限の厳しい補足文法が提供され、許容可能なトークンシーケンスがさらに制限されます。通常、初期エラールールは、「PがNをカバーしていない」場合にエラー条件を定義します。Pは解析ノード(一般化されたプロダクションのインスタンス)であり、Nは補足文法の非終端です。ここでは、最初にPと一致したトークンのシーケンスが、Nを目標シンボルとして再び解析されます。(Nが文法パラメーターを取る場合、Pが最初に解析されたときに使用されたものと同じ値に設定されます。)トークンのシーケンスをNの単一インスタンスとして解析できず、トークンが残っていない場合、エラーが発生します。その後、アルゴリズムは、「PによってカバーされるN」という形式の句を使用して、解析の結果にアクセスします。これは常に解析ノード(Nのインスタンス、特定のPに固有)になります。これは、解析の失敗は初期のエラールールによって検出されるためです。
5.1.5 文法表記(Grammar Notation)
この仕様で文法は、テキストが終端シンボルを直接参照する場合は常に、終端シンボルは固定幅フォントで表示されます。これらは、記述されているとおりにスクリプトに表示されます。この方法で指定されたすべての終端シンボルコードポイントは、他のUnicode範囲からの同様に見えるコードポイントとは対照的に、基本ラテン語範囲からの適切なUnicodeコードポイントとして理解されます。 終端シンボルのコードポイントは、\ UnicodeEscapeSequenceでは表現できません。
非終端シンボルはイタリック体で示されています。 非終端シンボル(「プロダクション」とも呼ばれる)は、後ろに1つ以上のコロンが続いている文字です。(コロンの数は、プロダクションがどの文法に属するかを示します。)非終端記号の右側は、後続の行に続きます。
たとえば、次のような構文の定義があるとします。
WhileStatement :
while ( Expression ) Statement
非終端シンボルのWhileStatementは、whileトークンから始まり、その後に左括弧トークン、式、右括弧トークン、ステートメントが続く、ということを示しています。ExpressionとStatementの出現自体は非終端です。
別の例を挙げます。
ArgumentListは、単一のAssignmentExpressionまたはArgumentListのいずれかを表し、その後にコンマが続き、AssignmentExpressionが続くことを示しています。 このArgumentListの定義は再帰的です。つまり、それ自体で定義されます。その結果、ArgumentListには、コンマで区切られた引数を含めることができます。各引数式は、AssignmentExpressionです。非終端では、そのような再帰的な定義は一般的です。
ArgumentListは、次の形式をとる。
(1)ArgumentList = 引数
(2)ArgumentList = ArgumentList , 引数
(2)の右辺のArgumentListを、(2)に置き換える。
ArgumentList = ArgumentList , 引数 , 引数
(1)に置き換えるまで、再帰的に(2)を適用できる。
つまり、複数の引数をカンマで指定できる。
端末または非端末の後に表示される添え字付きのサフィックス「opt」は、オプションの記号を示します。オプションのシンボルを含む選択肢は、実際には2つの右辺を指定します。1つはオプションの要素を省略し、もう1つはそれを含みます。
例:
上の例は、次の定義を省略したものです。
別の例を挙げます。
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
このようにこの例では、IterationStatementには4つの形式があります。
プロダクションは、[parameters]形式の添え字付きアノテーションによってパラメーター化できます。これは、プロダクションによって定義された非終端シンボルのサフィックスとして表示される場合があります。[parameters]は、単一の名前またはコンマで区切られた名前のリストのいずれかです。パラメーター化されたプロダクションは、パラメーター名のすべての組み合わせを定義する一連のプロダクションの省略形であり、アンダースコアが前に付けられ、パラメーター化された非終端記号に追加されます。
例:
StatementList[Return] :
ReturnStatement
ExpressionStatement
上の例は、次の2つの定義を省略したものです。
別の例を挙げます。
StatementList[Return,In] :
ReturnStatement
ExpressionStatement
上の例は、次の4つの定義を省略したものです。
複数のパラメーターの組み合わせの数だけプロダクションが生成されますが、必ずしもすべてが完全な文法で参照されるわけではありません。
プロダクションの右側にある非終端への参照もパラメーター化できます。
例:
これは次と同じです。
StatementList :
ReturnStatement
ExpressionStatement_In
次のようなケースもあります。
これは次と同じです。
非終端参照には、[params]リストとoptサフィックスの両方を含めることができます。
例:
VariableDeclaration :
BindingIdentifier Initializer[+In]opt
次のようになります。
VariableDeclaration :
BindingIdentifier
BindingIdentifier Initializer_In
右側の非終端参照でパラメータ名の前に「?」を付けると、そのパラメーター値は、現在のプロダクションのパラメーター名で使用されているかどうかに依存します。
例:
VariableDeclaration[In] :
BindingIdentifier Initializer[?In]
次の2つにわけることができます。
VariableDeclaration_In :
BindingIdentifier Initializer_In
右辺の前に[+parameter]が付いている場合、プロダクションの非終端シンボルの参照に使用された場合にのみ使用できます。
StatementList[Return] :
[+Return]ReturnStatement
ExpressionStatement
次の2つにわけることができます。
別の例:
StatementList[Return] :
[~Return]ReturnStatement
ExpressionStatement
次の2つにわけることができます。
文法定義で「どれかひとつ」という単語がコロンの後に続く場合、次の行または複数の行の各終端シンボルから一つが選択されることを示しています。 たとえば、ECMAScriptの字句文法には次のようなものがあります。
NonZeroDigit :: どれかひとつ
1 2 3 4 5 6 7 8 9
次のように展開されます。
NonZeroDigit :: どれかひとつ
1
2
3
4
5
6
7
8
9
[empty]という語句がプロダクションの右側に記述されている場合は、プロダクションの右側に終端シンボルがないか、非終端であることを示しています。
プロダクションの右側に[lookahead ∉ set]というフレーズが記述されていて、直後に特定のセットがある場合、プロダクションを使用できないことを示しています。セットは、中かっこで囲まれた1つまたは2つの要素の端子シーケンスのコンマ区切りリストとして記述できます。便宜上、セットは非終端シンボルとしても記述できます。その場合、非終端シンボルが展開できるすべてのセットを表します。セットが単一のシンボルで構成されている場合、[lookahead ≠ terminal]というフレーズを使用できます。
例:
DecimalDigit :: どれかひとつ
1 2 3 4 5 6 7 8 9
LookaheadExample ::
n [lookahead ∉ { 1, 3, 5, 7, 9 }] DecimalDigits
DecimalDigit [lookahead ∉ DecimalDigit]
このときLookaheadExampleは、偶数である(1, 3, 5, 7, 9ではない)文字nとそれに続く1つ以上の10進数字、または10進数字の後に10進数字が続いていない10進数字のどちらかに一致します。
同様に、[lookahead ∈ set]というフレーズがプロダクションの右側に記述されているとき、直後の入力トークンシーケンスが特定のセットのメンバーである場合にのみ使用できることを示します。 セットが単一のシンボルで構成されている場合、[lookahead = terminal]というフレーズを使用できます。
プロダクションの右側に[no LineTerminator here]というフレーズが記述されているとき、指定された位置の入力ストリームで LineTerminator が発生した場合は使用できません。
例:
ThrowStatement ::
throw [no LineTerminator here] Expression ;
スロートークンとExpressionの間のスクリプトでLineTerminatorが発生した場合、プロダクションを使用できないことを示しています。
制限されたプロダクションによって LineTerminator の存在が禁止されていない限り、スクリプトの構文の受け入れ可能性に影響を与えることなく、LineTerminatorの出現は、入力要素のストリーム内の任意の2つの連続するトークンの間に出現する可能性があります。
レキシカル文法または数値文字列文法の生成における代替がマルチコードポイントトークンのように見える場合、それはそのようなトークンを構成するコードポイントのシーケンスを表します。
プロダクションの右側は、「ただし~ではない」という語句で除外する拡張を示します。
例:
コードシーケンスがReservedWordとして置き換えられなかった場合、Identifierを、IdentifierNameを置き換えることができるコードポイントのシーケンスとして扱うことができることを意味します。
最後に、すべての選択肢を記述することが非現実的である場合、sans-serifの説明句で記述されています。
SourceCharacter ::
任意のUnicodeコードポイント
5.2 アルゴリズム規約(Algorithm Conventions)
この仕様では、番号付きリストを使用してアルゴリズムのステップを指定しています。これらのアルゴリズムは、ECMAScript言語構造の必要なセマンティクスを正確に指定するために使用されます。しかし、特定の実装手法の使用を示唆するものではありません。実際には、より効率的なアルゴリズムがある場合があります。
アルゴリズムは明示的にパラメーター化できます。その場合、パラメーターの名前と使用法をアルゴリズムの定義の一部として提供しています。
アルゴリズムのステップは、連続したサブステップに細分していることがあります。サブステップはインデントされており、さらにサブステップに細分されている場合があります。アウトライン番号付け規則は、小文字のアルファベット文字でラベル付けされた第1レベルのサブステップと小文字のローマ数字でラベル付けされた第2レベルのサブステップでサブステップを識別するために使用されます。 4つ以上のレベルが必要な場合、これらのルールは数値ラベルを使用して4番目のレベルで繰り返されます。
- Top-level step
- Substep.
- Substep.
- Subsubstep.
- Subsubsubstep.
- Subsubsubsubstep.
- Subsubsubsubstep.
- Subsubsubsubstep.
- Subsubsubstep.
- Subsubstep.
ステップまたはサブステップは、ifを記述できます。 ifは、述語が真の場合にのみサブステップが適用されます。ステップまたはサブステップがelseという語で始まる場合、同じレベルの先行するifが偽のとき適用されます。
ステップは、そのサブステップの反復適用を指定できます。
Assert
Assert: で始まるステップは、アルゴリズムの暗黙的な不変条件を提示します。このようなアサーションは追加のセマンティック要件を追加しないので、実装でチェックする必要はありません。これらは単にアルゴリズムを明確にするために使用されます。
アルゴリズムのステップでは、「someValue を x とする」の形式を使用して、値の名前付きエイリアスを宣言できます。これらのエイリアスは、x と someValue の両方が同じ基本データを参照します。そのため、一方の変更がもう一方に影響するという点で参照に似ています。この参照のような動作を回避するアルゴリズムのステップでは、右側のコピーを明示的に作成する必要があります。「someValue のコピーを x とする」は、someValue のシャロ―コピーを作成します。
いったん宣言されると、エイリアスは後続のステップで参照される可能性があり、エイリアスの宣言の前のステップから参照してはなりません。エイリアスは、「someOtherValue を x にセットする」の形式を使用して変更できます。
5.2.1 抽象操作(Abstract Operations)
抽象演算と呼ばれる一部のアルゴリズムは、他のアルゴリズム内から参照できるように名前が付けられ、パラメーター化された関数形式で記述されてます。抽象操作は通常、OperationName(arg1、arg2)などのアプリケーションスタイルを使用して参照されます。一部の抽象操作は、クラスのような仕様抽象化の多態的にディスパッチされたメソッドとして扱われ、通常、someValue.OperationName(arg1、arg2)などのメソッドアプリケーションスタイルを使用して参照されます。
5.2.2 構文指向の操作(Syntax-Directed Operations)
構文指向の操作は、定義がアルゴリズムで構成される名前付き操作です。各アルゴリズムは、1つのECMAScript文法が1つ以上のプロダクションに関連付けられています。複数の代替定義を持つプロダクションは、通常、代替ごとに異なるアルゴリズムを持っています。アルゴリズムが文法プロダクションに関連付けられている場合、アルゴリズムのパラメーターとして、代替プロダクションの終端記号と非終端記号を参照する場合があります。この方法で使用される場合、非終端記号は、ソーステキストの解析時に一致する実際の代替定義を指します。文法プロダクションに一致するソーステキストは、一致対象の最初の終端記号の先頭から、最後の終端記号の末尾までのソーステキストです。
アルゴリズムがプロダクション選択肢に関連付けられているとき、選択肢は通常、[]文法注釈なしで表示されます。このような注釈は、選択肢の構文認識にのみ影響し、選択肢の関連するセマンティクスには影響しません。
構文指定の操作は、次のアルゴリズムの手順1、3、および4の規則を使用して、解析ノードと、オプションで他のパラメーターで呼び出されます。
- SomeNonTerminal の SyntaxDirectedOperation を status とする
- いくつかのソーステキストの解析結果を someParseNode とする
- someParseNode の SyntaxDirectedOperation を実行する
- 引数 "value" を使用して someParseNode の SyntaxDirectedOperation を実行する。
特に明記されていない限り、すべての連鎖プロダクションには、そのプロダクションの左側の非終端シンボルに適用される可能性があるすべての操作に対して暗黙的な定義があります。暗黙的な定義は、同じ操作がある場合は、同じ操作をチェーンプロダクションの唯一の右側の非終端に再適用し、結果を返します。
たとえば、一部のアルゴリズムに「Blockを評価した結果を返す」という形式のステップがありプロダクションがあると仮定します。
Block :
{ StatementList }
ただし、評価操作はアルゴリズムをそのプロダクションに関連付けません。その場合、評価操作には次のような関連付けが暗黙的に含まれます。
ランタイムセマンティクスの評価操作:
Block : { StatementList }
- StatementList を評価した結果を返す
5.2.3 ランタイムセマンティクス(Runtime Semantics)
呼び出すセマンティクスを実行時に指定するアルゴリズムは、ランタイムセマンティクスと呼ばれます。ランタイムセマンティクスは、抽象演算または構文指向の演算によって定義されます。このようなアルゴリズムは常に完了レコードを返します。
5.2.3.1 暗黙の完了値(Implicit Completion Values)
この仕様のアルゴリズムは、暗黙的に[[Type]]が"normal"であるCompletionレコードを返すことがあります。
例:
- "Infinity"を返す
これは、次のように置き換えられます。
- NormalCompletion("Infinity")の結果を返す
ただし、「を返す」ステートメントの値式が完了レコード構築リテラルの場合、結果の完了レコードが返されます。値式が抽象操作の呼び出しである場合、「を返す」ステートメントは、抽象操作によって生成された完了レコードを返すだけです。
抽象演算Completion(completionRecord)は、以前に計算された完了レコードが返されていることを強調するために使用されます。Completion抽象操作は、単一の引数completionRecordを取り、次の手順を実行します。
値のない「を返す」ステートメントは、以下と同じことを意味します。
- NormalCompletion(undefined)の結果を返す
完全な完了レコード値を明示的していない完了レコード値への参照は、完了レコードが突然の完了でない限り、完了レコード値の[[Value]]フィールドへの明示的な参照と同等です。
5.2.3.2 例外を投げる(Throw an Exception)
次の例は、例外をスローするアルゴリズムのステップです。
- TypeError例外をスローする
- ThrowCompletion(新しく作成したTypeErrorオブジェクト)の結果を返す
5.2.3.3 ReturnIfAbrupt
次の、または同等のアルゴリズムステップがあるとします。
- ReturnIfAbrupt( argument )
これは、次のような処理をおこないます。
また次のように実行された場合、
- ReturnIfAbrupt(AbstractOperation())
次のような処理をおこないます。
hygienicTemp は、ReturnIfAbrupt に関連するステップでのみ使用されます。
また次のように実行された場合、
- AbstractOperation(ReturnIfAbrupt(argument)) の結果を result とする
次のような処理をおこないます。
5.2.3.4 ReturnIfAbrupt省略表記(ReturnIfAbrupt Shorthands)
操作の前に?が付加された場合
抽象操作および構文指定操作の前に?がついている場合、各々の結果(Completion Record)に対してReturnIfAbruptが適用されます。
例:
- ? OperationName()
次のような処理をおこないます。
- ReturnIfAbrupt(OperationName())を実行する
同様に、メソッドアプリケーションスタイルの場合、ステップは次のとおりです。
- ? someValue.OperationName()
↓
- ReturnIfAbrupt(someValue.OperationName())を実行する
操作の前に!が付加された場合
抽象操作および構文指定操作の前に!がついている場合、各々の処理結果は突然の完了にならない。そして処理結果の[[Value]]フィールドを操作の戻り値として使用する。
例:
- ! OperationName()の結果を val とする
↓
- OperationName()の結果を、val とする
- Assert:val は 突然の完了 ではない
- val が Completion Record なら、val を val.[[Value]]にセット
実行時セマンティクスの構文指定操作での例:
- ! NonTerminal の SyntaxDirectedOperation を実行する
5.2.4 静的セマンティクス(Static Semantics)
文脈自由文法は、有効なECMAScriptScriptまたはModuleを、すべてのルールにおいて表現できているわけではありません。 状況によっては、ECMAScriptアルゴリズムの規則やその他の要件を使用して表現される追加ルールが必要です。このようなルールは常に文法のプロダクションに関連付けられ、プロダクションの静的セマンティクスと呼ばれます。
静的セマンティックルール
静的セマンティックルールには名前があり、通常はアルゴリズムを使用して定義されます。 通常、複数の代替定義を持つプロダクションは各代替に対して、適用可能な名前付き静的セマンティックルールごとに異なるアルゴリズムを持っています。
暗黙的Contains
特に明記されていない限り、この仕様のすべての文法プロダクションの選択肢には暗黙的に、Containsという静的セマンティックルールの定義があります。そして、関連するプロダクションを含む文法の終端または非終端の値であるsymbolという引数を取ります。Containsのデフォルトの定義は次のとおりです。
- 解析ノードの子ノードをのchildとし、各childごとに以下を実行する
- child が symbol のインスタンスなら、trueを返す
- child が非終端インスタンスなら、
- child を含むsymbolの結果を contained とする
- contains が true なら、trueを返す
- falseを返す
特定のプロダクションでは、上記の定義が明示的に上書きされます。
早期エラールールは、特別な静的セマンティックルールです。 早期エラールールは、特定の文法プロダクションに関連する早期エラー条件(16章を参照)を定義します。この仕様のアルゴリズム内では、ほとんどの早期エラールール評価は明示的に呼び出されません。適合実装は、ScriptまたはModuleの最初の評価前に、そのScriptまたはModuleの解析に使用されるプロダクションのすべての早期エラールールを検証する必要があります。早期エラールールに違反している場合、ScriptまたはModuleは無効であり、評価できません。
5.2.5 数学演算(Mathematical Operations)
この仕様では、2種類の数値を使用しています。
- Number(数値):IEEE 754-2019倍精度浮動小数点値。デフォルトの数値型。
- Mathematical value(数学値):特定の状況で使用される任意の実数。
この仕様では、数値と演算(加算、減算、否定、乗算、除算、比較を含む)は、添え字を使用して上記の2種類を区別します。下付き文字はNumber(数値)を表し、下付き文字はMathematical value(数学的な値)を表します。添え字は、各数値と演算の後に使用されます。
ただし簡潔化のため、Number値の添え字は省略されていることがあります。パラメータの1つに特定の添え字がない限り、添え字のない演算はNumberでの演算と解釈します。演算結果は、元と同じ種類となります。 たとえば、1+2=3はMathematical valueに関するステートメントであり、1 + 2 = 3はNumberに関するステートメントです。
この仕様において「yの長さ」または「4桁の16進数で表される整数...」のように種類を明示的に指定しない数値は、Numberです。
Mathematical valueを参照する場合は、たとえば、「...のコードポイント数の数学的な値」といった注釈がつけられます。
算術演算または比較演算で数値と数学値を混在させることは定義されていません。このような未定義の演算は、この仕様書では編集上のエラーになります。
算術演算または比較演算で数値と数学値を混在させることは定義されていません。このような未定義の演算は、この仕様書では編集上のエラーになります。
数値0、または0と表記されるものは、倍精度浮動小数点の正のゼロ値として定義されます。特定のコンテキストでは、わかりやすくするために+0と表記されることもあります。
この仕様は、10を底とするほとんどの数値を示します。また、0xの形式の数値と、それに続く数字0-9またはA-Fを基数16の値として使用します。
特定のコンテキストでは、NumberとMathematical valueを固定しない演算が指定されています。この場合、添え字が変数になっています(tがよく使用されます)。 たとえば、5t × 10t = 50tです。
数値と数学的数値間の変換は暗黙的ではなく、このドキュメントで常に明示されています。
数学的数値
Mathematical valueからNumberへの変換は「xの数値」として示され、6.1.6.1で定義されています。
NumberからMathematical valueへの変換は「xの数学値」または(x)として示されます。
非有限の数学値は定義されておらず、+0および-0の数学値は数学値0であることに注意してください。
整数
この仕様で整数という用語が使用されている場合、特に明記されていないかぎり、Mathematical valueが整数のセットに含まれるNumberを指します。
数学的整数
この仕様で数学的整数(mathematical integer)という用語が使用されている場合、Mathematical valueに含まれる整数のセットを指します。
省略形として、integerttを使用できます。
abs()
数学関数abst(x)は、xの絶対値を生成します。これは、x <t 0tの場合は-txで、それ以外の場合はxです。
min()
max()
数学関数mint(x1、x2、…、xN)は、x1からxNまでの数学的に最小のものを取得します。 数学関数maxt(x1、x2、...、xN)は、数学的に最大のx1からxNを生成します。 これらの数学関数の領域と範囲には、+∞と-∞が含まれます。
剰余(modulo)
「x modulot y」という表記(yは有限で非ゼロでなければならない)は、abst(k) <t abst(y)およびx -t k = q ×t yとなるように、y(またはゼロ)と同じ符号の値kを計算します(qは整数)。
-100 modulo 3 は、1
floor()
数学関数floort(x)は、x以下の最大の整数(正の無限大に最も近い)を生成します。
floor(-100.5) => -100.5 - (-100.5 modulo 1) => -100.5 - (0.5) => -101
5.2.6 値の表記(Value Notation)
この仕様では、ECMAScript言語の値は太字で表示されています。 例には、null、true、または"hello"が含まれます。 これらは、Function.prototype.applyまたはlet n = 42;などのECMAScriptコードシーケンスとは区別されます。
仕様上の、ECMAScriptコードから直接参照できない内部値は、sans-serif書体で示されます。たとえば、完了レコードの[[Type]]フィールドは、normal、return、throwなどの値を取ります。