5.1 Syntactic and Lexical Grammars
5.1.1 Context-Free Grammars
context-free grammar는 여러 production으로 구성됩니다. 각 production은 left-hand side로서 nonterminal이라고 하는 abstract symbol을 가지며, right-hand side로서 0개 이상의 nonterminal 및 terminal symbol의 sequence를 가집니다. 각 grammar에 대해 terminal symbol은 지정된 alphabet에서 가져옵니다.
chain production은 right-hand side에 정확히 하나의 nonterminal symbol과 0개 이상의 terminal symbol을 가진 production입니다.
goal symbol이라고 하는 하나의 distinguished nonterminal로 이루어진 sentence에서 시작하여, 주어진 context-free grammar는 하나의 language, 즉 sequence 안의 nonterminal을 그 nonterminal이 left-hand side인 production의 right-hand side로 반복해서 대체함으로써 얻을 수 있는 가능한 terminal symbol sequence의 (아마도 무한한) 집합을 명시합니다.
5.1.2 Lexical 및 RegExp Grammars
ECMAScript의 lexical grammar는 clause 12에 제시됩니다. 이 grammar는 11.1에 정의된 SourceCharacter 규칙을 따르는 Unicode code point를 terminal symbol로 가집니다. 이는 goal symbol InputElementDiv, InputElementTemplateTail, InputElementRegExp, InputElementRegExpOrTemplateTail, 또는 InputElementHashbangOrRegExp에서 시작하여, 그러한 code point의 sequence가 input element의 sequence로 어떻게 변환되는지를 설명하는 production의 집합을 정의합니다.
white space와 comment 이외의 input element는 ECMAScript의 syntactic grammar를 위한 terminal symbol을 형성하며 ECMAScript tokens라고 불립니다. 이러한 token은 ECMAScript 언어의 reserved word, identifier, literal, punctuator입니다. 또한 line terminator는 token으로 간주되지는 않지만 input element의 stream의 일부가 되어 automatic semicolon insertion 과정(12.10)을 안내합니다. 단순 white space와 single-line comment는 버려지며 syntactic grammar를 위한 input element의 stream에 나타나지 않습니다. MultiLineComment(즉, 여러 줄에 걸치는지와 관계없이 /*…*/ 형식의 comment)도 line terminator를 포함하지 않으면 마찬가지로 단순히 버려집니다. 그러나 MultiLineComment가 하나 이상의 line terminator를 포함하면, 이는 하나의 line terminator로 대체되어 syntactic grammar를 위한 input element의 stream의 일부가 됩니다.
ECMAScript의 RegExp grammar는 22.2.1에 제시됩니다. 이 grammar도 SourceCharacter로 정의된 code point를 terminal symbol로 가집니다. 이는 goal symbol Pattern에서 시작하여 code point의 sequence가 regular expression pattern으로 어떻게 변환되는지를 설명하는 production의 집합을 정의합니다.
lexical 및 RegExp grammar의 production은 분리 punctuation으로 두 개의 colon “::”을 가진다는 점으로 구분됩니다. lexical 및 RegExp grammar는 일부 production을 공유합니다.
5.1.3 Numeric String Grammar
numeric string grammar는 7.1.4.1에 나타납니다. 이는 SourceCharacter를 terminal symbol로 가지며, goal symbol StringNumericLiteral에서 시작하여 String을 numeric value로 변환하는 데 사용됩니다(이는 numeric literal을 위한 lexical grammar와 유사하지만 구별됩니다).
numeric string grammar의 production은 punctuation으로 세 개의 colon “:::”을 가진다는 점으로 구분되며, source text를 parsing하는 데 사용되지 않습니다.
5.1.4 Syntactic Grammar
ECMAScript의 syntactic grammar는 clauses 13 through 16에 제시됩니다. 이 grammar는 lexical grammar에 의해 정의된 ECMAScript token을 terminal symbol로 가집니다(5.1.2). 이는 두 alternative goal symbol Script와 Module에서 시작하여, token의 sequence가 ECMAScript 프로그램의 syntactically correct independent component를 어떻게 형성하는지를 설명하는 production의 집합을 정의합니다.
code point의 stream을 ECMAScript Script 또는 Module로 parsing하려면, 먼저 lexical grammar의 반복 적용에 의해 input element의 stream으로 변환됩니다. 그런 다음 이 input element의 stream은 syntactic grammar를 한 번 적용하여 parsed됩니다. input element의 stream 안의 token이 goal nonterminal(Script 또는 Module)의 단일 instance로, token을 남기지 않고 parsed될 수 없으면 input stream은 syntactically in error입니다.
parse가 성공하면, root가 있는 tree structure인 parse tree를 구성하며, 이 tree의 각 node는 Parse Node입니다. 각 Parse Node는 grammar 안의 symbol의 instance입니다. 이는 그 symbol로부터 derivable한 source text의 span을 나타냅니다. parse tree의 root node는 source text 전체를 나타내며 parse의 goal symbol의 instance입니다. Parse Node가 nonterminal의 instance일 때, 이는 또한 그 nonterminal을 left-hand side로 갖는 어떤 production의 instance입니다. 또한 이는 0개 이상의 children을 가지며, production의 right-hand side에 있는 각 symbol마다 하나씩 존재합니다. 각 child는 해당 symbol의 instance인 Parse Node입니다.
New Parse Node는 parser의 각 invocation마다 instantiated되며, 동일한 source text의 parse 사이에서도 결코 재사용되지 않습니다. Parse Node는 같은 source text span을 나타내고, 같은 grammar symbol의 instance이며, 같은 parser invocation에서 나온 경우에만 the same Parse Node로 간주됩니다.
Note 1
같은 String을 여러 번 parsing하면 서로 다른 Parse Node가 생성됩니다. 예를 들어 다음을 고려하십시오:
let str = "1 + 1;";
eval(str);
eval(str);
eval 호출 각각은 str의 값을 ECMAScript source text로 변환하고, 독립적인 parse를 수행하여 자신만의 별도 Parse Node tree를 생성합니다. 각 parse가 같은 String value에서 derived된 source text에 대해 동작하더라도 tree들은 distinct합니다.
Note 2Parse Node는 specification artefact이며, implementation은 유사한 data structure를 사용할 필요가 없습니다.
syntactic grammar의 production은 punctuation으로 단 하나의 colon “:”을 가진다는 점으로 구분됩니다.
clauses 13 through 16에 제시된 syntactic grammar는 어떤 token sequence가 올바른 ECMAScript Script 또는 Module로 받아들여지는지에 대한 완전한 설명이 아닙니다. 특정 위치(예: line terminator character 앞)에 semicolon을 추가하기만 하면 grammar가 설명할 수 있는 token sequence도 추가로 허용됩니다. 또한 grammar에 의해 설명되는 특정 token sequence라도 line terminator character가 특정 “awkward” 위치에 나타나면 허용 가능한 것으로 간주되지 않습니다.
어떤 경우에는 ambiguity를 피하기 위해 syntactic grammar가 유효한 ECMAScript Script 또는 Module을 형성하지 않는 token sequence를 허용하는 generalized production을 사용합니다. 예를 들어 이 기법은 object literal과 object destructuring pattern에 사용됩니다. 그런 경우 허용 가능한 token sequence를 더 제한하는 보다 제한적인 supplemental grammar가 제공됩니다. 일반적으로 early error rule은 특정 context에서 “p must cover an n”이라고 명시하며, 여기서 p는 Parse Node(generalized production의 instance)이고 n은 supplemental grammar의 nonterminal입니다. 이는 다음을 의미합니다:
- 원래 p에 의해 match된 token sequence는 n을 goal symbol로 사용하여 다시 parsed됩니다. n이 grammatical parameter를 취하면, 이는 p가 원래 parsed될 때 사용된 값과 같은 값으로 설정됩니다.
- token sequence가 token을 남기지 않고 n의 단일 instance로 parsed될 수 있으면, 다음과 같습니다:
- 그 n의 instance(주어진 p에 대해 unique한 Parse Node)를 “p에 의해 covered되는 n”이라고 부릅니다.
- n과 그 derived production에 대한 모든 Early Error rule도 p에 의해 covered되는 n에 적용됩니다.
- 그렇지 않으면(parse가 실패하면) early Syntax Error입니다.
5.1.5 Grammar Notation
5.1.5.1 Terminal Symbols
ECMAScript grammar에서 일부 terminal symbol은 fixed-width font로 표시됩니다. 이들은 source text에 쓰인 그대로 나타나야 합니다. 이런 방식으로 명시된 모든 terminal symbol code point는 다른 Unicode range의 비슷하게 보이는 code point가 아니라 Basic Latin block의 적절한 Unicode code point로 이해되어야 합니다. terminal symbol 안의 code point는 \ UnicodeEscapeSequence로 표현될 수 없습니다.
terminal symbol이 개별 Unicode code point인 grammar(즉 lexical, RegExp, numeric string grammar)에서 production에 나타나는 여러 fixed-width code point의 contiguous run은 standalone terminal symbol로 쓰인 같은 code point sequence에 대한 단순한 shorthand입니다.
예를 들어 production:
HexIntegerLiteral ::
0x
HexDigits
은 다음에 대한 shorthand입니다:
HexIntegerLiteral ::
0
x
HexDigits
반대로 syntactic grammar에서는 fixed-width code point의 contiguous run이 하나의 terminal symbol입니다.
Terminal symbol은 두 가지 다른 형식으로도 나타납니다:
5.1.5.2 Nonterminal Symbols and Productions
Nonterminal symbol은 italic type으로 표시됩니다. nonterminal의 정의(“production”이라고도 함)는 정의되는 nonterminal의 name과 그 뒤에 오는 하나 이상의 colon으로 시작됩니다. (colon의 수는 production이 어떤 grammar에 속하는지를 나타냅니다.) 그런 다음 nonterminal에 대한 하나 이상의 alternative right-hand side가 다음 줄들에 이어집니다. 예를 들어 syntactic definition:
WhileStatement :
while
(
Expression
)
Statement
은 nonterminal WhileStatement가 token while, 그 뒤의 left parenthesis token, 그 뒤의 Expression, 그 뒤의 right parenthesis token, 그 뒤의 Statement를 나타낸다고 명시합니다. Expression과 Statement의 occurrence는 그 자체로 nonterminal입니다. 또 다른 예로, syntactic definition:
ArgumentList :
AssignmentExpression
ArgumentList
,
AssignmentExpression
은 ArgumentList가 하나의 AssignmentExpression을 나타내거나, ArgumentList 뒤에 comma가 오고 그 뒤에 AssignmentExpression이 오는 것을 나타낼 수 있다고 명시합니다. ArgumentList의 이 정의는 recursive합니다. 즉 자신을 기준으로 정의됩니다. 그 결과 ArgumentList는 comma로 구분된 임의의 양수 개수의 argument를 포함할 수 있으며, 각 argument expression은 AssignmentExpression입니다. 이러한 nonterminal의 recursive definition은 흔합니다.
5.1.5.3 Optional Symbols
terminal 또는 nonterminal 뒤에 나타날 수 있는 subscripted suffix “opt”는 optional symbol을 나타냅니다. optional symbol을 포함하는 alternative는 실제로 optional element를 생략한 것과 포함한 것, 두 right-hand side를 명시합니다. 이는 다음을 의미합니다:
VariableDeclaration :
BindingIdentifier
Initializeropt
은 다음에 대한 편리한 abbreviation입니다:
VariableDeclaration :
BindingIdentifier
BindingIdentifier
Initializer
그리고 다음도:
ForStatement :
for
(
LexicalDeclaration
Expressionopt
;
Expressionopt
)
Statement
다음에 대한 편리한 abbreviation입니다:
ForStatement :
for
(
LexicalDeclaration
;
Expressionopt
)
Statement
for
(
LexicalDeclaration
Expression
;
Expressionopt
)
Statement
이는 다시 다음에 대한 abbreviation입니다:
ForStatement :
for
(
LexicalDeclaration
;
)
Statement
for
(
LexicalDeclaration
;
Expression
)
Statement
for
(
LexicalDeclaration
Expression
;
)
Statement
for
(
LexicalDeclaration
Expression
;
Expression
)
Statement
따라서 이 예에서 nonterminal ForStatement는 실제로 네 개의 alternative right-hand side를 가집니다.
5.1.5.4 Grammatical Parameters
production은 정의되는 production의 nonterminal symbol에 suffix로 나타날 수 있는 “[parameters]” 형식의 subscripted annotation으로 parameterized될 수 있습니다. “parameters”는 하나의 name이거나 comma로 구분된 name의 list일 수 있습니다. parameterized production은 parameterized nonterminal symbol에 underscore를 앞에 붙인 parameter name의 모든 조합을 덧붙여 정의하는 production 집합에 대한 shorthand입니다. 이는 다음을 의미합니다:
StatementList[Return] :
ReturnStatement
ExpressionStatement
은 다음에 대한 편리한 abbreviation입니다:
StatementList :
ReturnStatement
ExpressionStatement
StatementList_Return :
ReturnStatement
ExpressionStatement
그리고 다음도:
StatementList[Return, In] :
ReturnStatement
ExpressionStatement
다음에 대한 abbreviation입니다:
StatementList :
ReturnStatement
ExpressionStatement
StatementList_Return :
ReturnStatement
ExpressionStatement
StatementList_In :
ReturnStatement
ExpressionStatement
StatementList_Return_In :
ReturnStatement
ExpressionStatement
여러 parameter는 combinatoric number의 production을 생성하며, 그 모두가 완전한 grammar에서 반드시 참조되는 것은 아닙니다.
production의 right-hand side에 있는 nonterminal reference도 parameterized될 수 있습니다. 예를 들어:
StatementList :
ReturnStatement
ExpressionStatement[+In]
은 다음과 말하는 것과 equivalent합니다:
StatementList :
ReturnStatement
ExpressionStatement_In
그리고:
StatementList :
ReturnStatement
ExpressionStatement[~In]
은 다음과 equivalent합니다:
StatementList :
ReturnStatement
ExpressionStatement
nonterminal reference는 parameter list와 “opt” suffix를 모두 가질 수 있습니다. 예를 들어:
VariableDeclaration :
BindingIdentifier
Initializer[+In]opt
은 다음에 대한 abbreviation입니다:
VariableDeclaration :
BindingIdentifier
BindingIdentifier
Initializer_In
right-hand side nonterminal reference에서 parameter name 앞에 “?”를 붙이면, 그 parameter value는 현재 production의 left-hand side symbol에 대한 reference에서 parameter name이 occurrence하는지에 따라 달라집니다. 예를 들어:
VariableDeclaration[In] :
BindingIdentifier
Initializer[?In]
은 다음에 대한 abbreviation입니다:
VariableDeclaration :
BindingIdentifier
Initializer
VariableDeclaration_In :
BindingIdentifier
Initializer_In
right-hand side alternative 앞에 “[+parameter]”가 붙으면, 그 alternative는 production의 nonterminal symbol을 참조할 때 named parameter가 사용된 경우에만 available합니다. right-hand side alternative 앞에 “[~parameter]”가 붙으면, 그 alternative는 production의 nonterminal symbol을 참조할 때 named parameter가 사용되지 않은 경우에만 available합니다. 이는 다음을 의미합니다:
StatementList[Return] : [+Return]
ReturnStatement
ExpressionStatement
은 다음에 대한 abbreviation입니다:
StatementList :
ExpressionStatement
StatementList_Return :
ReturnStatement
ExpressionStatement
그리고 다음도:
StatementList[Return] : [~Return]
ReturnStatement
ExpressionStatement
다음에 대한 abbreviation입니다:
StatementList :
ReturnStatement
ExpressionStatement
StatementList_Return :
ExpressionStatement
5.1.5.5 one of
grammar definition에서 colon(s) 뒤에 “one of”라는 단어가 오면, 이는 다음 line 또는 lines의 각 terminal symbol이 alternative definition임을 의미합니다. 예를 들어 ECMAScript의 lexical grammar에는 다음 production이 포함됩니다:
NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9
이는 단지 다음에 대한 편리한 abbreviation입니다:
NonZeroDigit ::
1
2
3
4
5
6
7
8
9
5.1.5.6 [empty]
production의 right-hand side에 “[empty]”라는 phrase가 나타나면, 이는 그 production의 right-hand side가 terminal이나 nonterminal을 포함하지 않음을 나타냅니다.
5.1.5.7 Lookahead Restrictions
production의 right-hand side에 “[lookahead = seq]”라는 phrase가 나타나면, 이는 immediately following input token sequence의 prefix가 token sequence seq인 경우에만 그 production을 사용할 수 있음을 나타냅니다. 마찬가지로 “[lookahead ∈ set]”에서 set이 token sequence의 finite non-empty set이면, immediately following token sequence의 prefix가 set의 어떤 element인 경우에만 그 production을 사용할 수 있음을 나타냅니다. 편의를 위해 set은 nonterminal로도 쓸 수 있으며, 이 경우 그 nonterminal이 expand될 수 있는 모든 token sequence의 집합을 나타냅니다. nonterminal이 무한히 많은 distinct token sequence로 expand될 수 있으면 이는 editorial error로 간주됩니다.
이러한 condition은 negated될 수 있습니다. “[lookahead ≠ seq]”는 containing production이 seq가 immediately following input token sequence의 prefix가 아닌 경우에만 사용될 수 있음을 나타내며, “[lookahead ∉ set]”는 immediately following token sequence의 prefix가 set의 어떤 element도 아닌 경우에만 production을 사용할 수 있음을 나타냅니다.
예를 들어 다음 정의가 주어졌을 때:
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]
letter n 뒤에 하나 이상의 decimal digit가 오며 그 첫 번째가 even인 경우, 또는 다른 decimal digit가 뒤따르지 않는 decimal digit 중 하나와 match합니다.
이 phrase들이 syntactic grammar에서 사용될 때는, 이후 token을 결정하려면 이후 위치에서 어떤 lexical goal symbol을 사용할지 알아야 하기 때문에 immediately following token sequence를 unambiguously identify할 수 없을 수도 있습니다. 따라서 syntactic grammar에서 이것들이 사용될 때, lexical goal symbol 선택이 resulting token sequence의 prefix가 seq인지 여부를 바꿀 수 있다면 token sequence seq가 lookahead restriction에(시퀀스 집합의 일부로 포함되는 경우도 포함) 나타나는 것은 editorial error로 간주됩니다.
syntactic grammar의 production의 right-hand side에 “[no LineTerminator here]”라는 phrase가 나타나면, 이는 그 production이 restricted production임을 나타냅니다. 즉 indicated position의 input stream에 LineTerminator가 occurrence하면 사용할 수 없습니다. 예를 들어 production:
ThrowStatement :
throw
[no LineTerminator here]
Expression
;
은 script에서 throw token과 Expression 사이에 LineTerminator가 occurrence하면 그 production을 사용할 수 없음을 나타냅니다.
LineTerminator의 존재가 restricted production에 의해 forbidden되지 않는 한, LineTerminator는 input element의 stream에서 연속된 두 token 사이에 임의의 횟수로 나타날 수 있으며 script의 syntactic acceptability에 영향을 주지 않습니다.
5.1.5.9 but not
production의 right-hand side는 “but not”이라는 phrase를 사용한 다음 excluded될 expansion을 표시하여 특정 expansion이 허용되지 않음을 명시할 수 있습니다. 예를 들어 production:
Identifier ::
IdentifierName but not ReservedWord
은 nonterminal Identifier가 IdentifierName을 replace할 수 있는 어떤 code point sequence로도 replace될 수 있되, 같은 code point sequence가 ReservedWord를 replace할 수 없는 경우에 한한다는 의미입니다.
5.1.5.10 Descriptive Phrases
마지막으로, 모든 alternative를 나열하는 것이 비실용적인 경우에는 몇몇 nonterminal symbol이 sans-serif type의 descriptive phrase로 설명됩니다:
SourceCharacter ::
any Unicode code point
5.2 Algorithm Conventions
이 명세는 algorithm의 step을 명시하기 위해 numbered list를 자주 사용합니다. 이러한 algorithm은 ECMAScript language construct의 요구되는 semantics를 정밀하게 명시하는 데 사용됩니다. algorithm은 특정 implementation technique의 사용을 함의하도록 의도되지 않습니다. 실제로 주어진 feature를 구현하는 데 더 효율적인 algorithm이 있을 수 있습니다.
algorithm은 algorithm step 안에서 해당 위치에 전달된 argument를 참조하는 데 사용할 수 있는 alias name의 ordered, comma-separated sequence로 명시적으로 parameterized될 수 있습니다. optional parameter는 surrounding brackets([ , name ])로 표시되며 algorithm step 안에서는 required parameter와 다르지 않습니다. rest parameter는 parameter list의 끝에 나타날 수 있으며, leading ellipsis(, ...name)로 표시됩니다. rest parameter는 required 및 optional parameter 뒤에 제공된 모든 argument를 List로 capture합니다. 그러한 additional argument가 없으면 그 List는 empty입니다.
algorithm step은 sequential substep으로 세분될 수 있습니다. substep은 indented되며 그 자체가 다시 indented substep으로 더 나뉠 수 있습니다. outline numbering convention은 substep을 식별하는 데 사용되며, 첫 번째 수준의 substep은 lowercase alphabetic character로, 두 번째 수준의 substep은 lowercase roman numeral로 labelled됩니다. 세 수준보다 더 많은 수준이 필요하면 이 규칙이 반복되며 네 번째 수준은 numeric label을 사용합니다. 예를 들어:
- Top-level step
- Substep.
- Substep.
- Subsubstep.
- Subsubsubstep
- Subsubsubsubstep
- Subsubsubsubsubstep
step 또는 substep은 그 substep을 condition하는 “if” predicate로 작성될 수 있습니다. 이 경우 substep은 predicate가 true일 때만 적용됩니다. step 또는 substep이 “else”라는 단어로 시작하면, 이는 같은 level의 preceding “if” predicate step의 negation인 predicate입니다.
step은 그 substep의 iterative application을 명시하기 위해 “For each” 또는 “Repeat”로 시작할 수 있습니다.
“Assert:”로 시작하는 step은 algorithm의 invariant condition을 assertion합니다. 이러한 assertion은 그렇지 않으면 암시적일 algorithmic invariant를 명시적으로 만들기 위해 사용됩니다. 마찬가지로 “NOTE:”로 시작하는 step은 nearby step에 관련된 context를 제공합니다. Assertion step과 note step은 strictly informative입니다. 이는 추가 semantic requirement를 더하지 않으므로 implementation이 check할 필요가 없습니다.
algorithm step은 “Let x be someValue” 형식을 사용하여 어떤 value에 대해서도 named alias를 선언할 수 있습니다. 이러한 alias는 x와 someValue 모두 같은 underlying data를 참조하고 어느 쪽에 대한 modification도 양쪽에 보인다는 점에서 reference-like입니다. 이 reference-like behaviour를 피하고자 하는 algorithm step은 right-hand side의 copy를 명시적으로 만들어야 합니다. “Let x be a copy of someValue”는 someValue의 shallow copy를 만듭니다.
일단 선언되면, alias는 이후의 어떤 step에서도 참조될 수 있으며 alias의 declaration 이전 step에서 참조되어서는 안 됩니다. alias는 “Set x to someOtherValue” 형식을 사용하여 수정될 수 있습니다.
5.2.1 Evaluation Order
complex expression이 algorithm step에 나타날 때, 이는 left-to-right, inside-to-outside order로 evaluated되는 것으로 이해해야 합니다. 예를 들어 step
- Return A(B(), C.[[D]]) + E(F()).
은 다음과 equivalent합니다
- Let tmp1 be B().
- Let tmp2 be C.[[D]].
- Let tmp3 be A(tmp1, tmp2).
- Let tmp4 be F().
- Let tmp5 be E(tmp4).
- Let tmp6 be tmp3 + tmp5.
- Return tmp6.
여기서 여러 tmpN alias는 ephemeral하며 이 step들 안에서만 visible합니다.
5.2.2 Abstract Operations
이 명세의 여러 부분에서 사용하기 쉽도록, abstract operations라고 하는 일부 algorithm은 이름을 가지며 parameterized functional form으로 작성되어 다른 algorithm 안에서 이름으로 참조될 수 있습니다. abstract operation은 보통 OperationName(arg1, arg2)와 같은 functional application style을 사용하여 참조됩니다. 일부 abstract operation은 class-like specification abstraction의 polymorphically dispatched method로 취급됩니다. 그러한 method-like abstract operation은 보통 someValue.OperationName(arg1, arg2)와 같은 method application style을 사용하여 참조됩니다.
5.2.3 Syntax-Directed Operations
syntax-directed operation은 named operation이며, 그 정의는 algorithm들로 구성되고, 각 algorithm은 ECMAScript grammar 중 하나의 하나 이상의 production과 associated됩니다. 여러 alternative definition을 가진 production은 보통 각 alternative마다 distinct algorithm을 가집니다. algorithm이 grammar production과 associated될 때, 이는 production alternative의 terminal 및 nonterminal symbol을 algorithm의 parameter인 것처럼 참조할 수 있습니다. 이런 방식으로 사용될 때 nonterminal symbol은 source text를 parsing할 때 match되는 실제 alternative definition을 참조합니다. grammar production 또는 그로부터 derived된 Parse Node가 matched by한 source text는 match에 참여한 첫 번째 terminal의 시작에서 시작하여 match에 참여한 마지막 terminal의 끝에서 끝나는 source text 부분입니다.
algorithm이 production alternative와 associated될 때, alternative는 보통 “[ ]” grammar annotation 없이 표시됩니다. 그러한 annotation은 alternative의 syntactic recognition에만 영향을 주어야 하며 alternative에 associated된 semantics에는 영향을 주지 않아야 합니다.
Syntax-directed operation은 다음 algorithm의 steps 1, 3, 그리고 4에 있는 convention을 사용하여 parse node와, 선택적으로, 다른 parameter와 함께 invoked됩니다:
- Let status be SyntaxDirectedOperation of SomeNonTerminal.
- Let someParseNode be the parse of some source text.
- Perform SyntaxDirectedOperation of someParseNode.
- Perform SyntaxDirectedOperation of someParseNode with argument "value".
명시적으로 달리 specified되지 않는 한, 모든 chain production은 그 production의 left-hand side nonterminal에 적용될 수 있는 모든 operation에 대해 implicit definition을 가집니다. implicit definition은 같은 operation을 같은 parameter가 있으면 그대로, chain production의 sole right-hand side nonterminal에 다시 적용하고 그 결과를 반환합니다. 예를 들어 어떤 algorithm에 “Return Evaluation of Block” 형식의 step이 있고 다음 production이 있다고 가정합니다:
Block :
{
StatementList
}
그러나 Evaluation operation이 그 production에 algorithm을 associate하지 않는 경우, Evaluation operation은 다음 형식의 association을 implicitly 포함합니다:
Runtime Semantics: Evaluation
Block :
{
StatementList
}
- Return Evaluation of StatementList.
5.2.4 Runtime Semantics
runtime에 호출되어야 하는 semantics를 명시하는 algorithm은 runtime semantics라고 합니다. Runtime semantics는 abstract operation 또는 syntax-directed operation에 의해 정의됩니다.
5.2.4.1 Completion ( completionRecord )
The abstract operation Completion takes argument completionRecord (a Completion Record) and returns a Completion Record. Completion Record가 반환되고 있음을 강조하는 데 사용됩니다. It performs the following steps when called:
- Assert: completionRecord is a Completion Record.
- Return completionRecord.
5.2.4.2 Throw
algorithm step에서 “throw”라는 단어는 ThrowCompletion을 호출한 결과를 반환하는 것에 대한 shorthand입니다. 예를 들어,
- If result.[[Error]] is not none, throw result.[[Error]].
은 다음과 equivalent합니다
- If result.[[Error]] is not none, return ThrowCompletion(result.[[Error]]).
특정 type의 exception을 throw하라고 말하는 algorithm step은 throw될 그 type의 exception을 construct합니다. 예를 들어,
- Throw a TypeError exception.
은 다음과 equivalent합니다
- Return ThrowCompletion(a newly created TypeError object).
5.2.4.3 Completion Record를 Unwrap하기 위한 Shorthand
prefix “?”와 “!”는 Completion Record를 unwrap하는 shorthand로 사용됩니다. “?”는 abrupt completion을 caller에게 propagate하거나, 그렇지 않으면 normal completion을 unwrap하는 데 사용됩니다. “!”는 Completion Record가 normal임을 assert하고 unwrap하는 데 사용됩니다. 형식적으로 step
- Let result be ? record.
은 다음과 equivalent합니다
- Assert: record is a Completion Record.
- If record is an abrupt completion, return record.
- Let result be record.[[Value]].
마찬가지로 step
- Let result be ! record.
은 다음과 equivalent합니다
- Assert: record is a normal completion.
- Let result be record.[[Value]].
“?” 또는 “!”가 다른 context에서 사용될 때는, 먼저 이 rule이 적용될 수 있을 때까지 Evaluation Order에 주어진 rewrite를 적용한 다음 이 rule을 적용합니다. 예를 들어 step
- Perform AO(? Other()).
은 다음으로 rewrite될 수 있습니다
- Let tmp1 be Other().
- Let tmp2 be ? tmp1.
- Perform AO(tmp2).
이는 다시 다음으로 expands됩니다
- Let tmp1 be Other().
- Assert: tmp1 is a Completion Record.
- If tmp1 is an abrupt completion, return tmp1.
- Let tmp2 be tmp1.[[Value]].
- Perform AO(tmp2).
5.2.4.4 Implicit Normal Completion
Completion Record를 반환하도록 declared된 abstract operation 안의 algorithm과 모든 built-in function 안에서는, 반환된 value가 먼저 NormalCompletion에 전달되고 그 결과가 대신 사용됩니다. 이 rule은 Completion algorithm 안이나 반환되는 value가 그 step에서 명확하게 Completion Record로 표시된 경우에는 적용되지 않습니다. 이러한 경우는 다음과 같습니다:
그러한 abstract operation에서 Completion Record가 다른 수단을 통해 반환되면 editorial error입니다. 예를 들어 이러한 abstract operation 안에서,
- Return true.
은 다음 중 어느 것과도 같은 의미입니다
- Return NormalCompletion(true).
또는
- Let completion be NormalCompletion(true).
- Return Completion(completion).
또는
- Return Completion Record { [[Type]]: normal, [[Value]]: true, [[Target]]: empty }.
? shorthand expansion을 통해, 다음 예는 허용된다는 점에 유의하십시오. expanded step 안에서 abrupt case에는 Completion을 적용한 결과가 직접 반환되고, normal case에는 unwrapping 후 implicit NormalCompletion application이 발생하기 때문입니다.
- Return ? completion.
다음 예는 Completion Record가 그 step에서 annotated되지 않은 채 반환되므로 editorial error입니다.
- Let completion be NormalCompletion(true).
- Return completion.
5.2.5 Static Semantics
Context-free grammar는 input element의 stream이 evaluated될 수 있는 유효한 ECMAScript Script 또는 Module을 형성하는지 정의하는 모든 rule을 표현할 만큼 충분히 강력하지 않습니다. 어떤 상황에서는 ECMAScript algorithm convention 또는 prose requirement를 사용하여 표현될 수 있는 additional rule이 필요합니다. 그러한 rule은 항상 grammar의 production과 associated되며 production의 static semantics라고 불립니다.
Static Semantic Rule은 name을 가지며 보통 algorithm을 사용하여 정의됩니다. Named Static Semantic Rule은 grammar production과 associated되며, 여러 alternative definition을 가진 production은 보통 각 applicable named static semantic rule에 대해 각 alternative마다 distinct algorithm을 가집니다.
특별한 종류의 static semantic rule은 Early Error Rule입니다. Early error rule은 특정 grammar production과 associated된 early error condition을 정의합니다(절 17 참조). 대부분의 early error rule의 evaluation은 이 명세의 algorithm 안에서 명시적으로 invoked되지 않습니다. conforming implementation은 Script 또는 Module의 첫 evaluation 이전에, 해당 Script 또는 Module을 parse하는 데 사용된 production의 모든 early error rule을 validate해야 합니다. early error rule 중 하나라도 위반되면 Script 또는 Module은 invalid이며 evaluated될 수 없습니다.
5.2.6 Mathematical Operations
이 명세는 다음 종류의 numeric value를 참조합니다:
이 명세의 언어에서 numerical value는 subscript suffix를 사용하여 서로 다른 numeric kind 사이에서 구분됩니다. subscript 𝔽는 Number를 가리키고, subscript ℤ는 BigInt를 가리킵니다. subscript suffix가 없는 numeric value는 mathematical value를 가리킵니다. 이 명세는 대부분의 numeric value를 base 10으로 나타내며, 0x 뒤에 digit 0-9 또는 A-F가 오는 형식의 numeric value도 base-16 value로 사용합니다.
일반적으로 이 명세가 “the length of y” 또는 “the integer represented by the four hexadecimal digits ...”와 같은 phrase에서 numeric kind를 명시적으로 지정하지 않고 numerical value를 참조하면, 그 phrase는 mathematical value를 가리킵니다. Number 또는 BigInt value를 가리키는 phrase는 명시적으로 그렇게 annotated됩니다. 예를 들어 “the Number value for the number of code points in …” 또는 “the BigInt value for …”와 같습니다.
이 명세에서 integer라는 term이 사용될 때, 달리 stated되지 않는 한 이는 integer 집합에 속하는 mathematical value를 가리킵니다. 이 명세에서 integral Number라는 term이 사용될 때, 이는 mathematical value가 integer 집합에 속하는 finite Number value를 가리킵니다.
+, ×, =, ≥와 같은 numeric operator는 operand의 type에 따라 결정되는 operation을 가리킵니다. mathematical value에 적용될 때, operator는 일반적인 mathematical operation을 가리킵니다. extended mathematical value에 적용될 때, operator는 extended real number에 대한 일반적인 mathematical operation을 가리킵니다. indeterminate form은 정의되지 않으며, 이 명세에서 그 사용은 editorial error로 간주되어야 합니다. Number에 적용될 때, operator는 IEEE 754-2019 안의 관련 operation을 가리킵니다. BigInt에 적용될 때, operator는 BigInt의 mathematical value에 적용되는 일반적인 mathematical operation을 가리킵니다. mixed-type operand(예: Number와 mathematical value)에 적용된 numeric operator는 정의되지 않으며 이 명세에서 editorial error로 간주되어야 합니다.
mathematical value와 Number 또는 BigInt 사이의 conversion은 이 문서에서 항상 explicit합니다. mathematical value 또는 extended mathematical value x에서 Number로의 conversion은 “the Number value for x” 또는 𝔽(x)로 표시되며 6.1.6.1에 정의됩니다. integer x에서 BigInt로의 conversion은 “the BigInt value for x” 또는 ℤ(x)로 표시됩니다. Number 또는 BigInt x에서 mathematical value로의 conversion은 “the mathematical value of x”, 또는 ℝ(x)로 표시됩니다. +0𝔽와 -0𝔽의 mathematical value는 mathematical value 0입니다. non-finite value의 mathematical value는 정의되지 않습니다. x의 extended mathematical value of는 finite value의 경우 x의 mathematical value이며, +∞𝔽와 -∞𝔽의 경우 각각 +∞와 -∞입니다. NaN에 대해서는 정의되지 않습니다.
mathematical function abs(x)는 x의 absolute value를 생성하며, 이는 x < 0이면 -x, 그렇지 않으면 x 자체입니다.
mathematical function ln(x)는 x의 natural logarithm을 생성합니다. mathematical function log10(x)는 x의 base 10 logarithm을 생성합니다. mathematical function log2(x)는 x의 base 2 logarithm을 생성합니다.
mathematical function min(x1, x2, … , xN)는 x1부터 xN까지 중 mathematically smallest인 것을 생성합니다. mathematical function max(x1, x2, ..., xN)는 x1부터 xN까지 중 mathematically largest인 것을 생성합니다. 이러한 mathematical function의 domain과 range는 extended mathematical value입니다.
notation “x modulo y”(y는 finite이고 non-zero여야 함)은 abs(k) < abs(y) 그리고 x - k = q × y가 어떤 integer q에 대해 성립하도록, y와 같은 sign(또는 zero)을 가진 값 k를 계산합니다.
phrase “the result of clamping x between lower and upper”(x는 extended mathematical value이고 lower와 upper는 lower ≤ upper인 mathematical value)는 x < lower이면 lower를 생성하고, x > upper이면 upper를 생성하며, 그렇지 않으면 x를 생성합니다.
mathematical function floor(x)는 x보다 크지 않은 가장 큰 integer(+∞에 가장 가까운)를 생성합니다.
Note
floor(x) = x - (x modulo 1).
mathematical function truncate(x)는 x를 zero 쪽으로 rounding하여 fractional part를 제거하며, x < 0이면 -floor(-x)를 생성하고 그렇지 않으면 floor(x)를 생성합니다.
mathematical function min, max, abs, floor, truncate는 Number와 BigInt에 대해 정의되지 않으며, non-mathematical value argument를 가진 이러한 method의 어떤 사용도 이 명세에서 editorial error가 됩니다.
lower bound a에서 upper bound b까지의 interval은 같은 numeric type의 numeric value로 이루어진 possibly-infinite, possibly-empty set입니다. 각 bound는 inclusive 또는 exclusive 중 하나로 설명되며 둘 다일 수는 없습니다. interval에는 다음 네 종류가 있습니다:
- a(inclusive)에서 b(inclusive)까지의 interval, 또한 a에서 b까지의 inclusive interval이라고도 하며, a ≤ x ≤ b인 같은 numeric type의 모든 value x를 포함하고 그 외에는 포함하지 않습니다.
- a(inclusive)에서 b(exclusive)까지의 interval은 a ≤ x < b인 같은 numeric type의 모든 value x를 포함하고 그 외에는 포함하지 않습니다.
- a(exclusive)에서 b(inclusive)까지의 interval은 a < x ≤ b인 같은 numeric type의 모든 value x를 포함하고 그 외에는 포함하지 않습니다.
- a(exclusive)에서 b(exclusive)까지의 interval은 a < x < b인 같은 numeric type의 모든 value x를 포함하고 그 외에는 포함하지 않습니다.
예를 들어 1(inclusive)에서 2(exclusive)까지의 interval은 1과 2 사이의 모든 mathematical value로 구성되며, 1을 포함하고 2를 포함하지 않습니다. interval을 정의하는 목적상, -0𝔽 < +0𝔽입니다. 따라서 예를 들어 lower bound가 +0𝔽인 inclusive interval은 +0𝔽를 포함하지만 -0𝔽는 포함하지 않습니다. NaN은 interval에 결코 포함되지 않습니다.
5.2.7 Value Notation
이 명세에서 ECMAScript language value는 bold로 표시됩니다. 예에는 null, true, 또는 "hello"가 포함됩니다. 이는 Function.prototype.apply 또는 let n = 42;와 같은 ECMAScript source text와 구별됩니다.
5.2.8 Identity
이 명세에서는 specification value와 ECMAScript language value 모두가 equality를 위해 비교됩니다. equality를 비교할 때 value는 두 category 중 하나에 속합니다. Values without identity는 integer의 magnitude나 sequence의 length와 같은 모든 innate characteristic이 같으면 다른 value without identity와 equal합니다. value without identity는 그 characteristic을 완전히 설명함으로써 prior reference 없이 manifest될 수 있습니다. 반대로 각 value with identity는 unique하므로 자기 자신과만 equal합니다. value with identity는 value without identity와 비슷하지만 identity라고 하는 추가적인 unguessable, unchangeable, universally-unique characteristic을 가집니다. identity 자체는 indescribable이므로 existing value with identity에 대한 reference는 단순히 설명함으로써 manifest될 수 없습니다. 대신 이러한 value에 대한 reference는 한 곳에서 다른 곳으로 명시적으로 전달되어야 합니다. 일부 value with identity는 mutable하므로 그 characteristic(identity 제외)을 in-place로 변경할 수 있으며, 그 value를 보유한 모든 이는 새로운 characteristic을 observe하게 됩니다. value without identity는 value with identity와 결코 equal하지 않습니다.
이 명세의 관점에서, “is”라는 단어는 “If bool is true, then ...”에서처럼 두 value를 equality로 비교하는 데 사용되고, “contains”라는 단어는 “If list contains a Record r such that r.[[Foo]] is true, then ...”에서처럼 equality comparison을 사용하여 list 안에서 value를 search하는 데 사용됩니다. value의 specification identity는 이러한 comparison의 결과를 결정하며 이 명세에서 axiomatic입니다.
ECMAScript 언어의 관점에서, language value는 SameValue abstract operation과 그것이 transitively 호출하는 abstract operation을 사용하여 equality로 비교됩니다. 이러한 comparison abstract operation의 algorithm은 ECMAScript language value의 language identity를 결정합니다.
specification value의 경우, specification identity가 없는 value의 예에는 다음이 포함되지만 이에 한정되지 않습니다: mathematical value와 extended mathematical value; ECMAScript source text, surrogate pair, Directive Prologue 등; UTF-16 code unit; Unicode code point; enum; syntax-directed operation, host hook 등을 포함한 abstract operation; 그리고 ordered pair. specification identity가 있는 specification value의 예에는 다음이 포함되지만 이에 한정되지 않습니다: Property Descriptor, PrivateElement 등을 포함한 모든 종류의 Record; Parse Node; List; Set과 Relation; Abstract Closure; Data Block; Private Name; execution context와 execution context stack; agent signifier; 그리고 WaiterList Record.
specification identity는 Symbol.for에 의해 생성된 Symbol value를 제외한 모든 ECMAScript language value에 대해 language identity와 일치합니다. specification identity도 language identity도 없는 ECMAScript language value는 undefined, null, Booleans, Strings, Numbers, 그리고 BigInts입니다. specification identity와 language identity를 모두 가진 ECMAScript language value는 Symbol.for에 의해 생성되지 않은 Symbols와 Objects입니다. Symbol.for에 의해 생성된 Symbol value는 specification identity를 가지지만 language identity는 가지지 않습니다.