12 ECMAScript 언어: 어휘 문법

ECMAScript Script 또는 Module의 소스 텍스트는 먼저 입력 요소들의 시퀀스로 변환되며, 이들은 토큰, 줄 종결자, 주석, 또는 공백이다. 소스 텍스트는 왼쪽에서 오른쪽으로 스캔되며, 가능한 한 가장 긴 코드 포인트 시퀀스를 다음 입력 요소로 반복해서 취한다.

어휘 입력 요소의 식별이 입력 요소를 소비하는 구문 문법 문맥에 민감한 여러 상황이 있다. 이 때문에 어휘 문법에는 여러 goal symbol이 필요하다. InputElementHashbangOrRegExp goal은 Script 또는 Module의 시작에서 사용된다. InputElementRegExpOrTemplateTail goal은 RegularExpressionLiteral, TemplateMiddle, 또는 TemplateTail이 허용되는 구문 문법 문맥에서 사용된다. InputElementRegExp goal symbol은 RegularExpressionLiteral은 허용되지만 TemplateMiddleTemplateTail도 허용되지 않는 모든 구문 문법 문맥에서 사용된다. InputElementTemplateTail goal은 TemplateMiddle 또는 TemplateTail은 허용되지만 RegularExpressionLiteral은 허용되지 않는 모든 구문 문법 문맥에서 사용된다. 그 외 모든 문맥에서는 InputElementDiv가 어휘 goal symbol로 사용된다.

Note

여러 어휘 goal을 사용하는 것은 자동 세미콜론 삽입에 영향을 줄 수 있는 어휘적 모호성이 없도록 보장한다. 예를 들어, 선행 division 또는 division-assignment와 선행 RegularExpressionLiteral이 모두 허용되는 구문 문법 문맥은 없다. 이것은 세미콜론 삽입의 영향을 받지 않는다(참조: 12.10); 다음과 같은 예에서:

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

LineTerminator 뒤의 첫 번째 비공백, 비주석 코드 포인트가 U+002F (SOLIDUS)이고 구문 문맥이 division 또는 division-assignment를 허용하는 경우, LineTerminator에 세미콜론은 삽입되지 않는다. 즉, 위 예시는 다음과 같은 방식으로 해석된다:

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

구문

InputElementDiv :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator RightBracePunctuator InputElementRegExp :: WhiteSpace LineTerminator Comment CommonToken RightBracePunctuator RegularExpressionLiteral InputElementRegExpOrTemplateTail :: WhiteSpace LineTerminator Comment CommonToken RegularExpressionLiteral TemplateSubstitutionTail InputElementTemplateTail :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator TemplateSubstitutionTail InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral

12.1 유니코드 형식 제어 문자

유니코드 형식 제어 문자(즉, LEFT-TO-RIGHT MARK 또는 RIGHT-TO-LEFT MARK와 같은 Unicode Character Database의 “Cf” 범주에 속하는 문자)는, 상위 수준 프로토콜(예: 마크업 언어)이 없는 상황에서 텍스트 범위의 형식을 제어하는 데 사용되는 제어 코드이다.

편집과 표시를 용이하게 하기 위해 소스 텍스트에서 형식 제어 문자를 허용하는 것이 유용하다. 모든 형식 제어 문자는 주석 안에서, 그리고 문자열 리터럴, 템플릿 리터럴, 정규식 리터럴 안에서 사용할 수 있다.

U+FEFF (ZERO WIDTH NO-BREAK SPACE)는 주로 텍스트 시작 부분에서 그것이 Unicode임을 표시하고 텍스트의 인코딩 및 바이트 순서를 감지할 수 있도록 하는 데 사용되는 형식 제어 문자이다. 이런 목적의 <ZWNBSP> 문자는 파일을 연결한 결과처럼 텍스트 시작 뒤에도 나타날 수 있다. ECMAScript 소스 텍스트에서 <ZWNBSP> 코드 포인트는 주석, 문자열 리터럴, 템플릿 리터럴, 정규식 리터럴 바깥에서는 공백 문자로 취급된다(참조: 12.2).

12.2 공백

공백 코드 포인트는 소스 텍스트의 가독성을 높이고 토큰(분해할 수 없는 어휘 단위)들을 서로 분리하는 데 사용되지만, 그 외에는 중요하지 않다. 공백 코드 포인트는 임의의 두 토큰 사이와 입력의 시작 또는 끝에 나타날 수 있다. 공백 코드 포인트는 StringLiteral, RegularExpressionLiteral, Template, 또는 TemplateSubstitutionTail 안에 나타날 수 있으며, 이 경우 리터럴 값의 일부를 이루는 중요한 코드 포인트로 간주된다. 또한 Comment 안에도 나타날 수 있지만, 다른 종류의 토큰 안에는 나타날 수 없다.

ECMAScript 공백 코드 포인트는 Table 30에 나열되어 있다.

Table 30: White Space Code Points
코드 포인트 이름 약어
U+0009 CHARACTER TABULATION <TAB>
U+000B LINE TABULATION <VT>
U+000C FORM FEED (FF) <FF>
U+FEFF ZERO WIDTH NO-BREAK SPACE <ZWNBSP>
general category “Space_Separator”에 속하는 임의의 코드 포인트 <USP>
Note 1

U+0020 (SPACE) 및 U+00A0 (NO-BREAK SPACE) 코드 포인트는 <USP>의 일부이다.

Note 2

Table 30에 나열된 코드 포인트를 제외하면, ECMAScript WhiteSpace는 유니코드 “White_Space” 속성을 가지지만 general category “Space_Separator” (“Zs”)로 분류되지 않는 모든 코드 포인트를 의도적으로 제외한다.

구문

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

12.3 줄 종결자

공백 코드 포인트와 마찬가지로, 줄 종결자 코드 포인트는 소스 텍스트의 가독성을 높이고 토큰(분해할 수 없는 어휘 단위)들을 서로 분리하는 데 사용된다. 그러나 공백 코드 포인트와 달리, 줄 종결자는 구문 문법의 동작에 어느 정도 영향을 미친다. 일반적으로 줄 종결자는 임의의 두 토큰 사이에 나타날 수 있지만, 구문 문법에 의해 금지되는 몇몇 위치가 있다. 줄 종결자는 자동 세미콜론 삽입 과정에도 영향을 미친다(12.10). 줄 종결자는 StringLiteral, Template, 또는 TemplateSubstitutionTail을 제외한 어떤 토큰 안에도 나타날 수 없다. <LF> 및 <CR> 줄 종결자는 LineContinuation의 일부인 경우를 제외하면 StringLiteral 토큰 안에 나타날 수 없다.

줄 종결자는 MultiLineComment 안에는 나타날 수 있지만 SingleLineComment 안에는 나타날 수 없다.

줄 종결자는 정규식의 \s 클래스가 매치하는 공백 코드 포인트 집합에 포함된다.

ECMAScript 줄 종결자 코드 포인트는 Table 31에 나열되어 있다.

Table 31: Line Terminator Code Points
코드 포인트 유니코드 이름 약어
U+000A LINE FEED (LF) <LF>
U+000D CARRIAGE RETURN (CR) <CR>
U+2028 LINE SEPARATOR <LS>
U+2029 PARAGRAPH SEPARATOR <PS>

Table 31의 유니코드 코드 포인트만 줄 종결자로 취급된다. 다른 새 줄 또는 줄 바꿈 유니코드 코드 포인트는 줄 종결자로 취급되지 않지만, Table 30에 나열된 요구사항을 만족하면 공백으로 취급된다. <CR><LF> 시퀀스는 흔히 줄 종결자로 사용된다. 줄 번호를 보고하는 목적상 이것은 하나의 SourceCharacter로 간주되어야 한다.

구문

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

12.4 주석

주석은 단일 행 또는 여러 행일 수 있다. 여러 행 주석은 중첩될 수 없다.

단일 행 주석은 LineTerminator 코드 포인트를 제외한 임의의 유니코드 코드 포인트를 포함할 수 있고, 토큰은 항상 가능한 한 길다는 일반 규칙 때문에, 단일 행 주석은 항상 // 표시부터 줄 끝까지의 모든 코드 포인트로 구성된다. 그러나 줄 끝의 LineTerminator는 단일 행 주석의 일부로 간주되지 않으며; 어휘 문법에 의해 별도로 인식되어 구문 문법을 위한 입력 요소 스트림의 일부가 된다. 이 점은 매우 중요한데, 단일 행 주석의 존재 여부가 자동 세미콜론 삽입 과정에 영향을 주지 않음을 의미하기 때문이다(참조: 12.10).

주석은 공백처럼 동작하며 버려지지만, MultiLineComment가 줄 종결자 코드 포인트를 포함하는 경우에는 전체 주석이 구문 문법에 의한 파싱 목적상 LineTerminator로 간주된다.

구문

Comment :: MultiLineComment SingleLineComment MultiLineComment :: /* MultiLineCommentCharsopt */ MultiLineCommentChars :: MultiLineNotAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt PostAsteriskCommentChars :: MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt MultiLineNotAsteriskChar :: SourceCharacter but not * MultiLineNotForwardSlashOrAsteriskChar :: SourceCharacter but not one of / or * SingleLineComment :: // SingleLineCommentCharsopt SingleLineCommentChars :: SingleLineCommentChar SingleLineCommentCharsopt SingleLineCommentChar :: SourceCharacter but not LineTerminator

이 절의 여러 production에는 B.1.1 절에서 대체 정의가 제공된다

12.5 Hashbang 주석

Hashbang 주석은 위치에 민감하며, 다른 종류의 주석과 마찬가지로 구문 문법을 위한 입력 요소 스트림에서 버려진다.

구문

HashbangComment :: #! SingleLineCommentCharsopt

12.6 토큰

구문

CommonToken :: IdentifierName PrivateIdentifier Punctuator NumericLiteral StringLiteral Template Note

DivPunctuator, RegularExpressionLiteral, RightBracePunctuator, TemplateSubstitutionTail production은 CommonToken production에 포함되지 않는 추가 토큰을 도출한다.

12.7 이름과 키워드

IdentifierNameReservedWord는, 약간의 수정과 함께 Unicode Standard Annex #31, Identifier and Pattern Syntax에 주어진 Default Identifier Syntax에 따라 해석되는 토큰이다. ReservedWordIdentifierName의 열거된 부분집합이다. 구문 문법은 IdentifierReservedWord가 아닌 IdentifierName으로 정의한다. 유니코드 식별자 문법은 Unicode Standard에 명시된 문자 속성에 기반한다. Unicode Standard 최신 버전에서 지정된 범주에 속하는 유니코드 코드 포인트는 모든 적합한 ECMAScript 구현에서 그 범주에 속하는 것으로 취급되어야 한다. ECMAScript 구현은 Unicode Standard의 더 이후 판에서 정의된 식별자 코드 포인트를 인식할 수 있다.

Note 1

이 표준은 특정 코드 포인트 추가를 명시한다: U+0024 (DOLLAR SIGN)와 U+005F (LOW LINE)는 IdentifierName 어디에서나 허용된다.

구문

PrivateIdentifier :: # IdentifierName IdentifierName :: IdentifierStart IdentifierName IdentifierPart IdentifierStart :: IdentifierStartChar \ UnicodeEscapeSequence IdentifierPart :: IdentifierPartChar \ UnicodeEscapeSequence IdentifierStartChar :: UnicodeIDStart $ _ IdentifierPartChar :: UnicodeIDContinue $ AsciiLetter :: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z UnicodeIDStart :: 유니코드 속성 “ID_Start”를 가진 임의의 유니코드 코드 포인트 UnicodeIDContinue :: 유니코드 속성 “ID_Continue”를 가진 임의의 유니코드 코드 포인트

비단말 UnicodeEscapeSequence의 정의는 12.9.4에 주어진다.

Note 2

비단말 IdentifierPartUnicodeIDContinue를 통해 _를 도출한다.

Note 3

유니코드 속성 “ID_Start”와 “ID_Continue”를 가진 코드 포인트 집합은 각각 유니코드 속성 “Other_ID_Start”와 “Other_ID_Continue”를 가진 코드 포인트를 포함한다.

12.7.1 식별자 이름

유니코드 이스케이프 시퀀스는 IdentifierName 안에서 허용되며, 이때 그것들은 UnicodeEscapeSequenceIdentifierCodePoint와 같은 하나의 유니코드 코드 포인트를 기여한다. UnicodeEscapeSequence 앞의 \는 어떤 코드 포인트도 기여하지 않는다. UnicodeEscapeSequence는 그 코드 포인트가 원래는 유효하지 않았을 IdentifierName에 코드 포인트를 기여하는 데 사용할 수 없다. 즉, \ UnicodeEscapeSequence 시퀀스를 그것이 기여하는 SourceCharacter로 대체했을 때, 결과는 여전히 유효한 IdentifierName이어야 하며 원래 IdentifierName와 정확히 같은 SourceCharacter 요소 시퀀스를 가져야 한다. 이 명세 안에서 IdentifierName에 대한 모든 해석은, 특정 코드 포인트를 기여하는 데 이스케이프 시퀀스가 사용되었는지 여부와 관계없이, 그 실제 코드 포인트에 기반한다.

Unicode Standard에 따라 canonical equivalent한 두 IdentifierName은, 각 UnicodeEscapeSequence를 치환한 뒤 정확히 같은 코드 포인트 시퀀스로 표현되지 않는 한, 같지 않다.

12.7.1.1 Static Semantics: Early Errors

IdentifierStart :: \ UnicodeEscapeSequence IdentifierPart :: \ UnicodeEscapeSequence

12.7.1.2 Static Semantics: IdentifierCodePoints

The syntax-directed operation IdentifierCodePoints takes no arguments and returns a List of code points. It is defined piecewise over the following productions:

IdentifierName :: IdentifierStart
  1. cpIdentifierStartIdentifierCodePoint라고 하자.
  2. « cp »를 반환한다.
IdentifierName :: IdentifierName IdentifierPart
  1. cps를 도출된 IdentifierNameIdentifierCodePoints라고 하자.
  2. cpIdentifierPartIdentifierCodePoint라고 하자.
  3. cps와 « cp »의 list-concatenation을 반환한다.

12.7.1.3 Static Semantics: IdentifierCodePoint

The syntax-directed operation IdentifierCodePoint takes no arguments and returns a code point. It is defined piecewise over the following productions:

IdentifierStart :: IdentifierStartChar
  1. IdentifierStartChar에 매치된 코드 포인트를 반환한다.
IdentifierPart :: IdentifierPartChar
  1. IdentifierPartChar에 매치된 코드 포인트를 반환한다.
UnicodeEscapeSequence :: u Hex4Digits
  1. 수치 값이 Hex4Digits의 MV인 코드 포인트를 반환한다.
UnicodeEscapeSequence :: u{ CodePoint }
  1. 수치 값이 CodePoint의 MV인 코드 포인트를 반환한다.

12.7.2 키워드와 예약어

키워드IdentifierName에 매치되는 토큰이지만, 동시에 구문적 용법도 가진다; 즉, 어떤 구문 production 안에서 fixed width 글꼴로 문자 그대로 나타난다. ECMAScript의 키워드에는 if, while, async, await 등 많은 것들이 포함된다.

예약어는 식별자로 사용할 수 없는 IdentifierName이다. 많은 키워드가 예약어이지만, 일부는 그렇지 않고, 일부는 특정 문맥에서만 예약된다. ifwhile은 예약어이다. await는 async 함수와 모듈 내부에서만 예약된다. async는 예약어가 아니다; 제한 없이 변수 이름이나 문장 라벨로 사용할 수 있다.

이 명세는 문법 production과 early error 규칙의 조합을 사용하여 어떤 이름이 유효한 식별자이고 어떤 이름이 예약어인지 명시한다. 아래 ReservedWord 목록의 모든 토큰은 awaityield를 제외하고는 무조건 예약된다. awaityield에 대한 예외는 13.1에서 매개변수화된 구문 production을 사용하여 명시된다. 마지막으로, 여러 early error 규칙이 유효한 식별자의 집합을 제한한다. 13.1.1, 14.3.1.1, 14.7.5.1, 그리고 15.7.1를 보라. 요약하면, 식별자 이름에는 다섯 가지 범주가 있다:

  • Math, window, toString, _처럼, 항상 식별자로 허용되고 키워드가 아닌 것들;

  • awaityield를 제외한 아래 나열된 ReservedWord들처럼, 절대로 식별자로 허용되지 않는 것들;

  • awaityield처럼, 문맥적으로 식별자로 허용되는 것들;

  • strict mode 코드에서 문맥적으로 식별자로 허용되지 않는 것들: let, static, implements, interface, package, private, protected, public;

  • 항상 식별자로 허용되지만, Identifier가 허용되지 않는 특정 구문 production 안에서는 키워드로도 나타나는 것들: as, async, from, get, meta, of, set, target.

조건부 키워드 또는 문맥 키워드라는 용어는 때때로 마지막 세 범주에 속하는 키워드를 가리키는 데 사용되며, 따라서 어떤 문맥에서는 식별자로, 다른 문맥에서는 키워드로 사용될 수 있다.

구문

ReservedWord :: one of await break case catch class const continue debugger default delete do else enum export extends false finally for function if import in instanceof new null return super switch this throw true try typeof var void while with yield Note 1

5.1.5에 따라, 문법 안의 키워드는 특정 SourceCharacter 요소들의 문자 그대로의 시퀀스에 매치된다. 키워드 안의 코드 포인트는 \ UnicodeEscapeSequence로 표현될 수 없다.

IdentifierName\ UnicodeEscapeSequence를 포함할 수 있지만, els\u{65}라고 써서 "else"라는 이름의 변수를 선언하는 것은 불가능하다. 13.1.1의 early error 규칙은 예약어와 같은 StringValue를 가지는 식별자를 배제한다.

Note 2

enum은 현재 이 명세에서 키워드로 사용되지 않는다. 이것은 미래 언어 확장에서 키워드로 사용하기 위해 남겨둔 미래 예약어이다.

마찬가지로, implements, interface, package, private, protected, publicstrict mode 코드에서 미래 예약어이다.

Note 3

argumentseval이라는 이름은 키워드는 아니지만, strict mode 코드에서는 몇 가지 제한을 받는다. 13.1.1, 8.6.4, 15.2.1, 15.5.1, 15.6.1, 그리고 15.8.1를 보라.

12.8 구두점

구문

Punctuator :: OptionalChainingPunctuator OtherPunctuator OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] OtherPunctuator :: one of { ( ) [ ] . ... ; , < > <= >= == != === !== + - * % ** ++ -- << >> >>> & | ^ ! ~ && || ?? ? : = += -= *= %= **= <<= >>= >>>= &= |= ^= &&= ||= ??= => DivPunctuator :: / /= RightBracePunctuator :: }

12.9 리터럴

12.9.1 Null 리터럴

구문

NullLiteral :: null

12.9.2 Boolean 리터럴

구문

BooleanLiteral :: true false

12.9.3 숫자 리터럴

구문

NumericLiteralSeparator :: _ NumericLiteral :: DecimalLiteral DecimalBigIntegerLiteral NonDecimalIntegerLiteral[+Sep] NonDecimalIntegerLiteral[+Sep] BigIntLiteralSuffix LegacyOctalIntegerLiteral DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix NonZeroDigit DecimalDigits[+Sep]opt BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits[+Sep] BigIntLiteralSuffix NonDecimalIntegerLiteral[Sep] :: BinaryIntegerLiteral[?Sep] OctalIntegerLiteral[?Sep] HexIntegerLiteral[?Sep] BigIntLiteralSuffix :: n DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits[+Sep]opt ExponentPart[+Sep]opt . DecimalDigits[+Sep] ExponentPart[+Sep]opt DecimalIntegerLiteral ExponentPart[+Sep]opt DecimalIntegerLiteral :: 0 NonZeroDigit NonZeroDigit NumericLiteralSeparatoropt DecimalDigits[+Sep] NonOctalDecimalIntegerLiteral DecimalDigits[Sep] :: DecimalDigit DecimalDigits[?Sep] DecimalDigit [+Sep] DecimalDigits[+Sep] NumericLiteralSeparator DecimalDigit DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9 ExponentPart[Sep] :: ExponentIndicator SignedInteger[?Sep] ExponentIndicator :: one of e E SignedInteger[Sep] :: DecimalDigits[?Sep] + DecimalDigits[?Sep] - DecimalDigits[?Sep] BinaryIntegerLiteral[Sep] :: 0b BinaryDigits[?Sep] 0B BinaryDigits[?Sep] BinaryDigits[Sep] :: BinaryDigit BinaryDigits[?Sep] BinaryDigit [+Sep] BinaryDigits[+Sep] NumericLiteralSeparator BinaryDigit BinaryDigit :: one of 0 1 OctalIntegerLiteral[Sep] :: 0o OctalDigits[?Sep] 0O OctalDigits[?Sep] OctalDigits[Sep] :: OctalDigit OctalDigits[?Sep] OctalDigit [+Sep] OctalDigits[+Sep] NumericLiteralSeparator OctalDigit LegacyOctalIntegerLiteral :: 0 OctalDigit LegacyOctalIntegerLiteral OctalDigit NonOctalDecimalIntegerLiteral :: 0 NonOctalDigit LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit NonOctalDecimalIntegerLiteral DecimalDigit LegacyOctalLikeDecimalIntegerLiteral :: 0 OctalDigit LegacyOctalLikeDecimalIntegerLiteral OctalDigit OctalDigit :: one of 0 1 2 3 4 5 6 7 NonOctalDigit :: one of 8 9 HexIntegerLiteral[Sep] :: 0x HexDigits[?Sep] 0X HexDigits[?Sep] HexDigits[Sep] :: HexDigit HexDigits[?Sep] HexDigit [+Sep] HexDigits[+Sep] NumericLiteralSeparator HexDigit HexDigit :: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

NumericLiteral 바로 뒤의 SourceCharacterIdentifierStart 또는 DecimalDigit이어서는 안 된다.

Note

예를 들어: 3in은 오류이며 두 개의 입력 요소 3in이 아니다.

12.9.3.1 Static Semantics: Early Errors

NumericLiteral :: LegacyOctalIntegerLiteral DecimalIntegerLiteral :: NonOctalDecimalIntegerLiteral
  • IsStrict(this production)가 true이면 Syntax Error이다.
Note
non-strict 코드에서 이 구문은 레거시이다.

12.9.3.2 Static Semantics: MV

숫자 리터럴은 Number 타입 또는 BigInt 타입의 값을 나타낸다.

12.9.3.3 Static Semantics: NumericValue

The syntax-directed operation NumericValue takes no arguments and returns a Number or a BigInt. It is defined piecewise over the following productions:

NumericLiteral :: DecimalLiteral
  1. RoundMVResult(MV of DecimalLiteral)를 반환한다.
NumericLiteral :: NonDecimalIntegerLiteral
  1. 𝔽(MV of NonDecimalIntegerLiteral)를 반환한다.
NumericLiteral :: LegacyOctalIntegerLiteral
  1. 𝔽(MV of LegacyOctalIntegerLiteral)를 반환한다.
NumericLiteral :: NonDecimalIntegerLiteral BigIntLiteralSuffix
  1. NonDecimalIntegerLiteral의 MV에 대한 BigInt 값을 반환한다.
DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix
  1. 0를 반환한다.
DecimalBigIntegerLiteral :: NonZeroDigit BigIntLiteralSuffix
  1. NonZeroDigit의 MV에 대한 BigInt 값을 반환한다.
DecimalBigIntegerLiteral :: NonZeroDigit DecimalDigits BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits BigIntLiteralSuffix
  1. nNumericLiteralSeparator의 모든 발생을 제외한 DecimalDigits의 코드 포인트 개수라고 하자.
  2. mv를 (NonZeroDigit의 MV × 10n)에 DecimalDigits의 MV를 더한 값이라고 하자.
  3. (mv)를 반환한다.

12.9.4 문자열 리터럴

Note 1

문자열 리터럴은 작은따옴표 또는 큰따옴표로 둘러싸인 0개 이상의 유니코드 코드 포인트이다. 유니코드 코드 포인트는 이스케이프 시퀀스를 사용해 표현될 수도 있다. 닫는 따옴표 코드 포인트, U+005C (REVERSE SOLIDUS), U+000D (CARRIAGE RETURN), U+000A (LINE FEED)를 제외한 모든 코드 포인트는 문자열 리터럴 안에 문자 그대로 나타날 수 있다. 어떤 코드 포인트든 이스케이프 시퀀스 형태로 나타날 수 있다. 문자열 리터럴은 ECMAScript String 값으로 평가된다. 이 String 값을 생성할 때 유니코드 코드 포인트는 11.1.1에 정의된 대로 UTF-16으로 인코딩된다. Basic Multilingual Plane에 속하는 코드 포인트는 문자열의 하나의 코드 단위 요소로 인코딩된다. 그 외 모든 코드 포인트는 문자열의 두 개 코드 단위 요소로 인코딩된다.

구문

StringLiteral :: " DoubleStringCharactersopt " ' SingleStringCharactersopt ' DoubleStringCharacters :: DoubleStringCharacter DoubleStringCharactersopt SingleStringCharacters :: SingleStringCharacter SingleStringCharactersopt DoubleStringCharacter :: SourceCharacter but not one of " or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation SingleStringCharacter :: SourceCharacter but not one of ' or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation LineContinuation :: \ LineTerminatorSequence EscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence HexEscapeSequence UnicodeEscapeSequence CharacterEscapeSequence :: SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter :: one of ' " \ b f n r t v NonEscapeCharacter :: SourceCharacter but not one of EscapeCharacter or LineTerminator EscapeCharacter :: SingleEscapeCharacter DecimalDigit x u LegacyOctalEscapeSequence :: 0 [lookahead ∈ { 8, 9 }] NonZeroOctalDigit [lookahead ∉ OctalDigit] ZeroToThree OctalDigit [lookahead ∉ OctalDigit] FourToSeven OctalDigit ZeroToThree OctalDigit OctalDigit NonZeroOctalDigit :: OctalDigit but not 0 ZeroToThree :: one of 0 1 2 3 FourToSeven :: one of 4 5 6 7 NonOctalDecimalEscapeSequence :: one of 8 9 HexEscapeSequence :: x HexDigit HexDigit UnicodeEscapeSequence :: u Hex4Digits u{ CodePoint } Hex4Digits :: HexDigit HexDigit HexDigit HexDigit

비단말 HexDigit의 정의는 12.9.3에 주어진다. SourceCharacter11.1에 정의되어 있다.

Note 2

<LF>와 <CR>은 빈 코드 포인트 시퀀스를 생성하는 LineContinuation의 일부인 경우를 제외하고 문자열 리터럴 안에 나타날 수 없다. 문자열 리터럴의 String 값 안에 이들 중 하나를 포함하는 올바른 방법은 \n 또는 \u000A 같은 이스케이프 시퀀스를 사용하는 것이다.

12.9.4.1 Static Semantics: Early Errors

EscapeSequence :: LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence
  • IsStrict(this production)가 true이면 Syntax Error이다.
Note 1
non-strict 코드에서 이 구문은 레거시이다.
Note 2

문자열 리터럴이, 둘러싼 코드를 strict mode로 두는 Use Strict 지시어보다 앞에 올 수도 있으며, 구현은 그러한 리터럴에 대해서도 위 규칙을 강제하도록 주의해야 한다. 예를 들어, 다음 소스 텍스트는 Syntax Error를 포함한다:

function invalid() { "\7"; "use strict"; }

12.9.4.2 Static Semantics: SV

The syntax-directed operation SV takes no arguments and returns a String.

문자열 리터럴은 String 타입의 값을 나타낸다. SV는 문자열 리터럴의 여러 부분에 재귀적으로 적용되어 문자열 리터럴의 String 값을 생성한다. 이 정의 일부로, 문자열 리터럴 안의 일부 유니코드 코드 포인트는 아래 또는 12.9.3에 설명된 대로 수학적 값을 가지는 것으로 해석된다.

Table 32: String Single Character Escape Sequences
이스케이프 시퀀스 코드 단위 값 유니코드 문자 이름 기호
\b 0x0008 BACKSPACE <BS>
\t 0x0009 CHARACTER TABULATION <HT>
\n 0x000A LINE FEED (LF) <LF>
\v 0x000B LINE TABULATION <VT>
\f 0x000C FORM FEED (FF) <FF>
\r 0x000D CARRIAGE RETURN (CR) <CR>
\" 0x0022 QUOTATION MARK "
\' 0x0027 APOSTROPHE '
\\ 0x005C REVERSE SOLIDUS \

12.9.4.3 Static Semantics: MV

12.9.5 정규식 리터럴

Note 1

정규식 리터럴은, 그 리터럴이 평가될 때마다 RegExp 객체(참조: 22.2)로 변환되는 입력 요소이다. 프로그램 안의 두 정규식 리터럴은, 두 리터럴의 내용이 동일하더라도, 서로 ===로 비교해 같아지는 정규식 객체로 평가되지 않는다. RegExp 객체는 new RegExp 또는 RegExp 생성자를 함수로 호출함으로써 런타임에 생성될 수도 있다(참조: 22.2.4).

아래 production은 정규식 리터럴의 구문을 설명하며, 입력 요소 스캐너가 정규식 리터럴의 끝을 찾는 데 사용된다. RegularExpressionBodyRegularExpressionFlags를 구성하는 소스 텍스트는 이후 더 엄격한 ECMAScript 정규식 문법(22.2.1)을 사용하여 다시 파싱된다.

구현은 22.2.1에 정의된 ECMAScript 정규식 문법을 확장할 수 있지만, 아래 정의된 RegularExpressionBodyRegularExpressionFlags production이나 이 production들이 사용하는 production은 확장해서는 안 된다.

구문

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags RegularExpressionBody :: RegularExpressionFirstChar RegularExpressionChars RegularExpressionChars :: [empty] RegularExpressionChars RegularExpressionChar RegularExpressionFirstChar :: RegularExpressionNonTerminator but not one of * or \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionChar :: RegularExpressionNonTerminator but not one of \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionBackslashSequence :: \ RegularExpressionNonTerminator RegularExpressionNonTerminator :: SourceCharacter but not LineTerminator RegularExpressionClass :: [ RegularExpressionClassChars ] RegularExpressionClassChars :: [empty] RegularExpressionClassChars RegularExpressionClassChar RegularExpressionClassChar :: RegularExpressionNonTerminator but not one of ] or \ RegularExpressionBackslashSequence RegularExpressionFlags :: [empty] RegularExpressionFlags IdentifierPartChar Note 2

정규식 리터럴은 비어 있을 수 없다; 빈 정규식 리터럴을 나타내는 대신, 코드 단위 시퀀스 //는 단일 행 주석을 시작한다. 빈 정규식을 명시하려면 /(?:)/를 사용하라.

12.9.5.1 Static Semantics: BodyText

The syntax-directed operation BodyText takes no arguments and returns source text. It is defined piecewise over the following productions:

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags
  1. RegularExpressionBody로 인식된 소스 텍스트를 반환한다.

12.9.5.2 Static Semantics: FlagText

The syntax-directed operation FlagText takes no arguments and returns source text. It is defined piecewise over the following productions:

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags
  1. RegularExpressionFlags로 인식된 소스 텍스트를 반환한다.

12.9.6 템플릿 리터럴 어휘 구성 요소

구문

Template :: NoSubstitutionTemplate TemplateHead NoSubstitutionTemplate :: ` TemplateCharactersopt ` TemplateHead :: ` TemplateCharactersopt ${ TemplateSubstitutionTail :: TemplateMiddle TemplateTail TemplateMiddle :: } TemplateCharactersopt ${ TemplateTail :: } TemplateCharactersopt ` TemplateCharacters :: TemplateCharacter TemplateCharactersopt TemplateCharacter :: $ [lookahead ≠ {] \ TemplateEscapeSequence \ NotEscapeSequence LineContinuation LineTerminatorSequence SourceCharacter but not one of ` or \ or $ or LineTerminator TemplateEscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence NotEscapeSequence :: 0 DecimalDigit DecimalDigit but not 0 x [lookahead ∉ HexDigit] x HexDigit [lookahead ∉ HexDigit] u [lookahead ∉ HexDigit] [lookahead ≠ {] u HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit HexDigit [lookahead ∉ HexDigit] u { [lookahead ∉ HexDigit] u { NotCodePoint [lookahead ∉ HexDigit] u { CodePoint [lookahead ∉ HexDigit] [lookahead ≠ }] NotCodePoint :: HexDigits[~Sep] but only if the MV of HexDigits > 0x10FFFF CodePoint :: HexDigits[~Sep] but only if the MV of HexDigits ≤ 0x10FFFF Note

TemplateSubstitutionTailInputElementTemplateTail 대체 어휘 goal에 사용된다.

12.9.6.1 Static Semantics: TV

The syntax-directed operation TV takes no arguments and returns a String or undefined. 템플릿 리터럴 구성 요소는 TV에 의해 String 타입의 값으로 해석된다. TV는 템플릿 객체의 인덱스된 구성 요소(구어적으로 템플릿 값)를 구성하는 데 사용된다. TV에서는 이스케이프 시퀀스가 그 이스케이프 시퀀스가 나타내는 유니코드 코드 포인트의 UTF-16 코드 단위(들)로 치환된다.

12.9.6.2 Static Semantics: TRV

The syntax-directed operation TRV takes no arguments and returns a String. 템플릿 리터럴 구성 요소는 TRV에 의해 String 타입의 값으로 해석된다. TRV는 템플릿 객체의 raw 구성 요소(구어적으로 템플릿 raw 값)를 구성하는 데 사용된다. TRV는 TV와 유사하지만, TRV에서는 이스케이프 시퀀스가 리터럴 안에 나타난 그대로 해석된다는 차이가 있다.

Note

TVLineContinuation의 코드 단위를 제외하지만 TRV는 포함한다. <CR><LF> 및 <CR> LineTerminatorSequenceTV와 TRV 모두에서 <LF>로 정규화된다. <CR> 또는 <CR><LF> 시퀀스를 포함하려면 명시적인 TemplateEscapeSequence가 필요하다.

12.10 자동 세미콜론 삽입

대부분의 ECMAScript 문장과 선언은 세미콜론으로 끝나야 한다. 그러한 세미콜론은 언제나 소스 텍스트에 명시적으로 나타날 수 있다. 그러나 편의를 위해, 어떤 상황에서는 그러한 세미콜론을 소스 텍스트에서 생략할 수 있다. 이러한 상황은 그런 경우 소스 코드 토큰 스트림에 세미콜론이 자동으로 삽입된다고 설명된다.

12.10.1 자동 세미콜론 삽입 규칙

다음 규칙에서 “token”은 12 절에 설명된 대로 현재 어휘 goal symbol을 사용하여 결정된 실제 인식된 어휘 토큰을 의미한다.

세미콜론 삽입에는 세 가지 기본 규칙이 있다:

  1. 소스 텍스트를 왼쪽에서 오른쪽으로 파싱할 때, 문법의 어떤 production에도 허용되지 않는 토큰(이를 문제가 되는 토큰이라고 부른다)을 만나면, 다음 조건 중 하나 이상이 참일 경우 문제가 되는 토큰 앞에 세미콜론이 자동으로 삽입된다:

    • 문제가 되는 토큰이 이전 토큰과 적어도 하나의 LineTerminator로 분리되어 있다.
    • 문제가 되는 토큰이 }이다.
    • 이전 토큰이 )이고, 삽입된 세미콜론이 do-while 문(14.7.2)의 종료 세미콜론으로 파싱된다.
  2. 소스 텍스트를 왼쪽에서 오른쪽으로 파싱할 때, 토큰 입력 스트림의 끝에 도달했고 파서가 그 입력 토큰 스트림을 goal 비단말의 단일 인스턴스로 파싱할 수 없으면, 입력 스트림 끝에 세미콜론이 자동으로 삽입된다.
  3. 소스 텍스트를 왼쪽에서 오른쪽으로 파싱할 때, 문법의 어떤 production에는 허용되지만 그 production이 제한된 production이고, 그 토큰이 제한된 production 안에서 “[no LineTerminator here]” 주석 바로 뒤의 terminal 또는 nonterminal에 대한 첫 번째 토큰이 될 경우(따라서 그런 토큰을 제한된 토큰이라 부른다), 그리고 제한된 토큰이 이전 토큰과 적어도 하나의 LineTerminator로 분리되어 있으면, 제한된 토큰 앞에 세미콜론이 자동으로 삽입된다.

그러나 앞선 규칙들에 대한 추가적인 우선 조건이 있다: 그 세미콜론이 빈 문장으로 파싱되거나, 또는 그 세미콜론이 for 문의 헤더 안의 두 세미콜론 중 하나가 된다면(참조: 14.7.4), 세미콜론은 결코 자동으로 삽입되지 않는다.

Note

문법에서 제한된 production은 다음뿐이다:

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] ; YieldExpression[In, Await] : yield yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await] yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await] ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In] AsyncFunctionDeclaration[Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod[Yield, Await] : async [no LineTerminator here] ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncGeneratorDeclaration[Yield, Await, Default] : async [no LineTerminator here] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no LineTerminator here] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no LineTerminator here] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [no LineTerminator here] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncArrowFunction[In, Yield, Await] : async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In] AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]

이러한 제한된 production의 실질적 효과는 다음과 같다:

  • 파서가 ++ 또는 -- 토큰을 후위 연산자로 처리하려는 위치에서 그것을 만났고, 이전 토큰과 ++ 또는 -- 토큰 사이에 적어도 하나의 LineTerminator가 있었다면, ++ 또는 -- 토큰 앞에 세미콜론이 자동으로 삽입된다.
  • continue, break, return, throw, 또는 yield 토큰을 만났고 다음 토큰 전에 LineTerminator를 만나면, continue, break, return, throw, 또는 yield 토큰 뒤에 세미콜론이 자동으로 삽입된다.
  • 화살표 함수의 매개변수 뒤에 => 토큰 전에 LineTerminator가 오면, 세미콜론이 자동으로 삽입되고 그 구두점은 syntax error를 일으킨다.
  • async 토큰 뒤에 function 또는 IdentifierName 또는 ( 토큰 전에 LineTerminator가 오면, 세미콜론이 자동으로 삽입되고 async 토큰은 뒤따르는 토큰들과 같은 표현식 또는 클래스 요소의 일부로 취급되지 않는다.
  • async 토큰 뒤에 * 토큰 전에 LineTerminator가 오면, 세미콜론이 자동으로 삽입되고 그 구두점은 syntax error를 일으킨다.

이에 따른 ECMAScript 프로그래머에 대한 실질적 조언은 다음과 같다:

  • 후위 ++ 또는 -- 연산자는 그 피연산자와 같은 줄에 있어야 한다.
  • return 또는 throw 문 안의 Expression이나 yield 표현식 안의 AssignmentExpressionreturn, throw, 또는 yield 토큰과 같은 줄에서 시작해야 한다.
  • break 또는 continue 문 안의 LabelIdentifierbreak 또는 continue 토큰과 같은 줄에 있어야 한다.
  • 화살표 함수 매개변수의 끝과 그 =>는 같은 줄에 있어야 한다.
  • 비동기 함수 또는 메서드 앞의 async 토큰은 바로 다음 토큰과 같은 줄에 있어야 한다.

12.10.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 1

표현식 a + breturn 문이 반환할 값으로 취급되지 않는데, 그것이 return 토큰과 LineTerminator로 분리되어 있기 때문이다.

소스

a = b
++c

는 자동 세미콜론 삽입에 의해 다음과 같이 변환된다:

a = b;
++c;
Note 2

토큰 ++는 변수 b에 적용되는 후위 연산자로 취급되지 않는데, b++ 사이에 LineTerminator가 있기 때문이다.

소스

if (a > b)
else c = d

는 유효한 ECMAScript 문장이 아니며, 그 지점에서 문법의 어떤 production도 적용되지 않더라도, 자동으로 삽입된 세미콜론이 빈 문장으로 파싱되기 때문에 else 토큰 앞에서 자동 세미콜론 삽입에 의해 변경되지 않는다.

소스

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

는 자동 세미콜론 삽입에 의해 변환되지 않는다. 왜냐하면 두 번째 줄을 시작하는 괄호로 둘러싸인 표현식은 함수 호출의 인수 목록으로 해석될 수 있기 때문이다:

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

대입문이 반드시 왼쪽 괄호로 시작해야 하는 상황에서는, 프로그래머가 자동 세미콜론 삽입에 의존하기보다 앞선 문장의 끝에 명시적인 세미콜론을 제공하는 것이 좋다.

12.10.3 자동 세미콜론 삽입의 흥미로운 경우

이 절은 비규범적이다.

ECMAScript 프로그램은 자동 세미콜론 삽입에 의존하여 매우 적은 수의 세미콜론만 사용하는 스타일로 작성될 수 있다. 위에서 설명했듯이, 세미콜론은 모든 개행마다 삽입되는 것이 아니며, 자동 세미콜론 삽입은 줄 종결자를 가로지르는 여러 토큰에 의존할 수 있다.

새로운 구문 기능이 ECMAScript에 추가되면, 그 앞에서 자동 세미콜론 삽입에 의존하던 줄이 파싱될 때 다른 문법 production으로 바뀌게 만드는 추가 문법 production이 추가될 수 있다.

이 절의 목적상, 자동 세미콜론 삽입의 경우는 그것 앞에 오는 소스 텍스트에 따라 세미콜론이 삽입될 수도 있고 안 될 수도 있는 위치라면 흥미로운 것으로 간주된다. 이 절의 나머지는 이 버전의 ECMAScript에서 나타나는 자동 세미콜론 삽입의 여러 흥미로운 경우를 설명한다.

12.10.3.1 문장 목록에서의 자동 세미콜론 삽입의 흥미로운 경우

StatementList 안에서 많은 StatementListItem은 세미콜론으로 끝나며, 이는 자동 세미콜론 삽입을 사용해 생략할 수 있다. 위 규칙의 결과로, 표현식으로 끝나는 줄의 끝에서는 다음 줄이 다음 중 하나로 시작하면 세미콜론이 필요하다:

  • 여는 괄호 ((). 세미콜론이 없으면 두 줄은 함께 CallExpression으로 취급된다.
  • 여는 대괄호 ([). 세미콜론이 없으면 두 줄은 ArrayLiteral 또는 ArrayAssignmentPattern이 아니라 프로퍼티 접근으로 함께 취급된다.
  • 템플릿 리터럴 (`). 세미콜론이 없으면 두 줄은 이전 표현식을 MemberExpression로 하는 태그된 Template(13.3.11)로 함께 해석된다.
  • 단항 + 또는 -. 세미콜론이 없으면 두 줄은 대응하는 이항 연산자의 사용으로 함께 해석된다.
  • RegExp 리터럴. 세미콜론이 없으면 두 줄은 대신 / MultiplicativeOperator로 파싱될 수 있는데, 예를 들어 RegExp에 플래그가 있는 경우 그렇다.

12.10.3.2 자동 세미콜론 삽입과 “[no LineTerminator here]”의 경우

이 절은 비규범적이다.

ECMAScript는 “[no LineTerminator here]”를 포함하는 문법 production을 가진다. 이러한 production은 때때로 문법 안에서 선택적 피연산자를 두기 위한 수단이다. 이런 위치에 LineTerminator를 도입하면 선택적 피연산자가 없는 문법 production을 사용하게 되어 소스 텍스트의 문법 production이 바뀌게 된다.

이 절의 나머지는 이 버전의 ECMAScript에서 “[no LineTerminator here]”를 사용하는 여러 production을 설명한다.

12.10.3.2.1 선택적 피연산자와 “[no LineTerminator here]”를 가진 문법 production 목록