어휘 분석
어휘 분석 (Lexical Analysis)
D 소스 코드가 어떤 문자 집합으로 쓰이고, 어떻게 토큰으로 쪼개지는지 다루는 페이지입니다. 주석, 식별자, 각종 문자열 리터럴, 이스케이프, 문자·정수·부동소수점 리터럴, 키워드, 특수 토큰까지 D의 어휘(lexical) 규칙을 정리했어요.
본문
어휘 분석은 구문 파싱(syntax parsing)과 의미 분석(semantic analysis)과 독립적입니다. 어휘 분석기는 소스 텍스트를 토큰으로 나눕니다. 어휘 문법(lexical grammar)은 이 토큰들의 문법을 설명합니다. 그 문법은 고속 스캐닝에 적합하고 올바른 스캐너 구현을 용이하게 하도록 설계되었습니다. 특별한 규칙 수가 최소이고 단 한 번의 변환 단계만 있습니다.
소스 텍스트 (Source Text)
SourceFile:
ByteOrderMark Moduleopt
Shebang Moduleopt
Moduleopt
ByteOrderMark:
\uFEFF
Shebang:
#! Charactersopt EndOfShebang
EndOfShebang:
\u000A
EndOfFile
소스 텍스트는 다음 중 하나로 인코딩될 수 있습니다:
- ASCII (엄밀히 말해 7비트 ASCII)
- UTF-8
- UTF-16BE
- UTF-16LE
- UTF-32BE
- UTF-32LE
소스 텍스트의 시작에는 다음 UTF BOM(Byte Order Mark) 중 하나가 있을 수 있습니다:
| 형식 | BOM |
|---|---|
| UTF-8 | EF BB BF |
| UTF-16BE | FE FF |
| UTF-16LE | FF FE |
| UTF-32BE | 00 00 FE FF |
| UTF-32LE | FF FE 00 00 |
| ASCII | BOM 없음 |
소스 파일이 BOM으로 시작하지 않으면, 첫 문자는 U+0000007F 이하여야 합니다.
소스 텍스트는 소스 표현에서 유니코드 문자로 디코딩됩니다. 문자들은 다시 나뉩니다: WhiteSpace, EndOfLine, Comments, SpecialTokenSequences, Tokens. 그리고 소스는 EndOfFile로 종료됩니다.
소스 텍스트는 최대 밈(maximal munch) 알고리즘으로 토큰으로 나뉩니다. 즉 어휘 분석기는 가능한 가장 긴 토큰을 가정합니다. 예를 들어 >>는 오른쪽 시프트 토큰이지 두 개의 greater-than 토큰이 아닙니다. 이 규칙에는 두 가지 예외가 있습니다:
- 두 부동소수점 리터럴 사이에 보이는
..—1..2처럼 — 는 그..가 첫 정수에서 공백으로 분리된 것처럼 해석됩니다. 1.a는 세 토큰1,.,a로 해석되는 반면,1. a는 두 토큰1.과a로 해석됩니다.
문자 집합 (Character Set)
Character:
any Unicode character
파일 끝 (End of File)
EndOfFile:
physical end of the file
\u0000
\u001A
소스 텍스트는 먼저 오는 것에 의해 종료됩니다.
줄 끝 (End of Line)
EndOfLine:
\u000D
\u000A
\u000D \u000A
\u2028
\u2029
EndOfFile
공백 (White Space)
WhiteSpace:
Space
Space WhiteSpace
Space:
\u0020
\u0009
\u000B
\u000C
주석 (Comments)
Comment:
BlockComment
LineComment
NestingBlockComment
BlockComment:
/* Charactersopt */
LineComment:
// Charactersopt EndOfLine
NestingBlockComment:
/+ NestingBlockCommentCharactersopt +/
NestingBlockCommentCharacters:
NestingBlockCommentCharacter
NestingBlockCommentCharacter NestingBlockCommentCharacters
NestingBlockCommentCharacter:
Character
NestingBlockComment
Characters:
Character
Character Characters
주석에는 세 가지 종류가 있습니다:
- 블록 주석(Block comments)은 여러 줄에 걸칠 수 있지만 중첩되지는 않습니다.
- 줄 주석(Line comments)은 줄 끝에서 종료됩니다.
- 중첩 블록 주석(Nesting block comments)은 여러 줄에 걸칠 수 있고 중첩될 수 있습니다.
문자열과 주석의 내용은 토큰화되지 않습니다. 결과적으로, 문자열 안에서 발생하는 주석 시작은 주석을 시작하지 않고, 주석 안의 문자열 구분자는 주석 종료와 중첩된 /+ 주석 시작의 인식에 영향을 주지 않습니다. /+ 주석 안에서 발생하는 /+를 제외하고, 주석 안의 주석 시작은 무시됩니다.
a = /+ // +/ 1; // parses as if 'a = 1;'
a = /+ "+/" +/ 1"; // parses as if 'a = " +/ 1";'
a = /+ /* +/ */ 3; // parses as if 'a = */ 3;'
주석은 토큰 연결자로 사용될 수 없습니다. 예를 들어 abc/**/def는 abc와 def 두 토큰이지 하나의 abcdef 토큰이 아닙니다.
토큰 (Tokens)
Tokens:
Token
Token Tokens
Token:
{
}
TokenNoBraces
TokenNoBraces:
Identifier
StringLiteral
InterpolationExpressionSequence
CharacterLiteral
IntegerLiteral
FloatLiteral
Keyword
/
/=
.
..
...
&
&=
&&
|
|=
||
-
-=
--
+
+=
++
>=
>>=
>>>=
>>
>>>
!
!=
(
)
[
]
?
,
;
:
$
=
==
*
*=
%
%=
^
^=
^^
^^=
~
~=
@
=>
식별자 (Identifiers)
Identifier:
IdentifierStart
IdentifierStart IdentifierChars
IdentifierChars:
IdentifierChar
IdentifierChar IdentifierChars
IdentifierStart:
_
Letter
UniversalAlpha
IdentifierChar:
IdentifierStart
0
NonZeroDigit
식별자는 문자, _, 또는 유니버설 알파(universal alpha)로 시작하며, 그 뒤에 어떤 수의 문자, _, 숫자, 유니버설 알파가 올 수 있습니다. 유니버설 알파는 C99 표준의 ISO/IEC 9899:1999(E) 부록 D에 정의된 바와 같습니다. 식별자는 임의로 길 수 있고 대소문자를 구분합니다.
구현 정의 (Implementation Defined):
__(밑줄 두 개)로 시작하는 식별자는 예약되어 있습니다.
문자열 리터럴 (String Literals)
StringLiteral:
WysiwygString
AlternateWysiwygString
DoubleQuotedString
DelimitedString
TokenString
HexString
문자열 리터럴은 wysiwyg 따옴표 문자열, 이중 따옴표 문자열, 구분(delimited) 문자열, 토큰 문자열, 또는 16진 문자열 중 하나입니다.
모든 문자열 리터럴 형태에서 EndOfLine은 단일 \n 문자로 간주됩니다.
Wysiwyg 문자열 (Wysiwyg Strings)
WysiwygString:
r" WysiwygCharactersopt " StringPostfixopt
AlternateWysiwygString:
` WysiwygCharactersopt ` StringPostfixopt
WysiwygCharacters:
WysiwygCharacter
WysiwygCharacter WysiwygCharacters
WysiwygCharacter:
Character
EndOfLine
Wysiwyg("보이는 그대로", what you see is what you get) 따옴표 문자열은 두 문법 중 하나로 정의될 수 있습니다.
첫 번째 형태에서는 r"와 " 사이에 둘러싸입니다. r"와 " 사이의 모든 문자가 문자열의 일부입니다. wysiwyg 문자열 안에는 이스케이프 시퀀스가 없습니다.
r"I am Oz"
r"c:\games\Sudoku.exe"
r"ab\n" // string is 4 characters,
// 'a', 'b', '\', 'n'
또는 wysiwyg 문자열은 백쿼트(`) 문자를 사용해 둘러쌀 수 있습니다.
`the Great and Powerful.`
`c:\games\Empire.exe`
`The "lazy" dog`
`a"b\n` // string is 5 characters,
// 'a', '"', 'b', '\', 'n'
InterpolatedWysiwygLiteral도 참고하세요.
이중 따옴표 문자열 (Double Quoted Strings)
DoubleQuotedString:
" DoubleQuotedCharactersopt " StringPostfixopt
DoubleQuotedCharacters:
DoubleQuotedCharacter
DoubleQuotedCharacter DoubleQuotedCharacters
DoubleQuotedCharacter:
Character
EscapeSequence
EndOfLine
이중 따옴표 문자열은 " " 사이에 둘러싸입니다. EscapeSequence가 그 안에 포함될 수 있습니다.
"Who are you?"
"c:\\games\\Doom.exe"
"ab\n" // string is 3 characters,
// 'a', 'b', and a linefeed
"ab
" // string is 3 characters,
// 'a', 'b', and a linefeed
InterpolatedDoubleQuotedLiteral도 참고하세요.
구분 문자열 (Delimited Strings)
DelimitedString:
q" Delimiter WysiwygCharactersopt MatchingDelimiter " StringPostfixopt
q"( ParenDelimitedCharactersopt )" StringPostfixopt
q"[ BracketDelimitedCharactersopt ]" StringPostfixopt
q"{ BraceDelimitedCharactersopt }" StringPostfixopt
q"" StringPostfixopt
Delimiter:
Identifier
MatchingDelimiter:
Identifier
ParenDelimitedCharacters:
WysiwygCharacter
WysiwygCharacter ParenDelimitedCharacters
( ParenDelimitedCharactersopt )
BracketDelimitedCharacters:
WysiwygCharacter
WysiwygCharacter BracketDelimitedCharacters
[ BracketDelimitedCharactersopt ]
BraceDelimitedCharacters:
WysiwygCharacter
WysiwygCharacter BraceDelimitedCharacters
{ BraceDelimitedCharactersopt }
AngleDelimitedCharacters:
WysiwygCharacter
WysiwygCharacter AngleDelimitedCharacters
구분 문자열은 다양한 형태의 구분자(delimiter)를 사용합니다. 구분자는 문자든 식별자든 " 바로 뒤에 오며, 사이에 공백이 없어야 합니다. 종료 구분자는 닫는 " 바로 앞에 와야 하며 사이에 공백이 없어야 합니다. 중첩 구분자(nesting delimiter)는 중첩되며 다음 문자 중 하나입니다:
| 구분자 | 일치하는 구분자 |
|---|---|
[ |
] |
( |
) |
< |
> |
{ |
} |
q"(foo(xxx))" // "foo(xxx)"
q"[foo{]" // "foo{"
구분자가 식별자이면, 그 식별자 바로 뒤에 새 줄이 와야 하고, 일치하는 구분자는 줄의 시작에서 같은 식별자여야 합니다:
writeln(q"EOS
This
is a multi-line
heredoc string
EOS"
);
여는 식별자 뒤의 새 줄은 문자열의 일부가 아니지만, 닫는 식별자 앞의 마지막 새 줄은 문자열의 일부입니다. 닫는 식별자는 맨 왼쪽 칸의 자기 줄에 배치해야 합니다.
그렇지 않으면 일치하는 구분자는 구분자 문자와 같습니다:
q"/foo]/" // "foo]"
// q"/abc/def/" // error
토큰 문자열 (Token Strings)
TokenString:
q{ TokenStringTokensopt } StringPostfixopt
TokenStringTokens:
TokenStringToken
TokenStringToken TokenStringTokens
TokenStringToken:
TokenNoBraces
{ TokenStringTokensopt }
토큰 문자열은 q{ 문자로 열리고 토큰 }로 닫힙니다. 그 사이에는 유효한 D 토큰이 있어야 합니다. {와 } 토큰은 중첩됩니다. 문자열은 주석을 포함해 토큰 문자열이 열리고 닫히는 사이의 모든 문자로 형성됩니다.
q{this is the voice of} // "this is the voice of"
q{/*}*/ } // "/*}*/ "
q{ world(q{control}); } // " world(q{control}); "
q{ __TIME__ } // " __TIME__ "
// i.e. it is not replaced with the time
// q{ __EOF__ } // error
// __EOF__ is not a token, it's end of file
InterpolatedTokenLiteral도 참고하세요.
16진 문자열 (Hex Strings)
HexString:
x" HexStringCharsopt " StringPostfixopt
HexStringChars:
HexStringChar
HexStringChar HexStringChars
HexStringChar:
HexDigit
WhiteSpace
EndOfLine
16진 문자열은 16진 데이터를 사용해 문자열 리터럴을 만들 수 있게 합니다. 16진 데이터는 유효한 UTF 문자를 형성할 필요가 없습니다.
x"0A" // same as "\x0A"
x"00 FBCD 32FD 0A" // same as "\x00\xFB\xCD\x32\xFD\x0A"
공백과 새 줄은 무시되므로 16진 데이터를 쉽게 정렬할 수 있습니다. 16진 문자 수는 2의 배수여야 합니다.
문자열 접미사 (String Postfix)
StringPostfix:
c
w
d
선택적 StringPostfix 문자는 문자열에 구체적인 타입을 줍니다(문맥에서 추론되는 대신). 접미사 문자에 해당하는 타입은:
| 접미사 | 타입 | 별칭 |
|---|---|---|
c |
immutable(char)[] |
string |
w |
immutable(wchar)[] |
wstring |
d |
immutable(dchar)[] |
dstring |
"hello"c // string
"hello"w // wstring
"hello"d // dstring
문자열 리터럴은 UTF-8 char 배열로 조립되며, 접미사가 마지막 단계로 필요에 따라 wchar나 dchar로 변환하는 데 적용됩니다.
이스케이프 시퀀스 (Escape Sequences)
EscapeSequence:
\'
\"
\?
\\
\0
\a
\b
\f
\n
\r
\t
\v
\x HexDigit HexDigit
\ OctalDigit
\ OctalDigit OctalDigit
\ OctalDigit OctalDigit OctalDigit
\u HexDigit HexDigit HexDigit HexDigit
\U HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit
\ NamedCharacterEntity
OctalDigit:
0
1
2
3
4
5
6
7
| 이스케이프 시퀀스 | 의미 |
|---|---|
\' |
리터럴 작은따옴표: ' |
\" |
리터럴 큰따옴표: " |
\? |
리터럴 물음표: ? |
\\ |
리터럴 백슬래시: \ |
\0 |
이진 0 (NUL, U+0000). |
\a |
BEL(알람) 문자 (U+0007). |
\b |
백스페이스 (U+0008). |
\f |
폼 피드(FF) (U+000C). |
\n |
줄 끝 (U+000A). |
\r |
캐리지 리턴 (U+000D). |
\t |
수평 탭 (U+0009). |
\v |
수직 탭 (U+000B). |
\xnn |
16진 바이트 값. nn은 두 16진 숫자로 지정됩니다. 예: \xFF는 값 255의 문자를 나타냅니다. std.conv.hexString도 참고. |
\n \nn \nnn |
8진 바이트 값. 예: \101은 값 65('A')의 문자를 나타냅니다. 16진 문자와 유사하게, 가장 큰 바이트 값은 \377입니다(16진 \xFF, 10진 255). std.conv.octal도 참고. |
\unnnn |
유니코드 문자 U+nnnn. nnnn은 네 16진 숫자입니다. 예: \u03B3는 유니코드 문자 γ (U+03B3 — GREEK SMALL LETTER GAMMA)를 나타냅니다. |
\Unnnnnnnn |
유니코드 문자 U+nnnnnnnn. nnnnnnnn은 8개의 16진 숫자입니다. 예: \U0001F603는 유니코드 문자 U+1F603 (SMILING FACE WITH OPEN MOUTH)를 나타냅니다. |
\name |
HTML5 규격의 명명된 문자 엔티티. 이 이름은 &로 시작하고 ;로 끝납니다(예: €). NamedCharacterEntity를 참고. |
문자 리터럴 (Character Literals)
CharacterLiteral:
' SingleQuotedCharacter '
SingleQuotedCharacter:
Character
EscapeSequence
문자 리터럴은 작은따옴표로 둘러싸인 단일 문자 또는 이스케이프 시퀀스입니다.
'h' // the letter h
'\n' // newline
'\\' // the backslash character
문자 리터럴은 char, wchar, 또는 dchar 중 하나의 타입으로 해석됩니다(기본 데이터 타입 참고).
- 리터럴이
\u이스케이프 시퀀스이면wchar타입으로 해석됩니다. - 리터럴이
\U이스케이프 시퀀스이면dchar타입으로 해석됩니다. - 그 외에는 들어갈 수 있는 가장 작은 크기의 타입으로 해석됩니다.
정수 리터럴 (Integer Literals)
IntegerLiteral:
Integer
Integer IntegerSuffix
Integer:
DecimalInteger
BinaryInteger
HexadecimalInteger
IntegerSuffix:
L
u
U
Lu
LU
uL
UL
DecimalInteger:
0 Underscoresopt
NonZeroDigit
NonZeroDigit DecimalDigitsUS
Underscores:
_
Underscores _
NonZeroDigit:
1
2
3
4
5
6
7
8
9
DecimalDigits:
DecimalDigit
DecimalDigit DecimalDigits
DecimalDigitsUS:
DecimalDigitUS
DecimalDigitUS DecimalDigitsUS
DecimalDigitsNoSingleUS:
DecimalDigitsUSopt DecimalDigit DecimalDigitsUSopt
DecimalDigitsNoStartingUS:
DecimalDigit
DecimalDigit DecimalDigitsUS
DecimalDigit:
0
NonZeroDigit
DecimalDigitUS:
DecimalDigit
_
BinaryInteger:
BinPrefix BinaryDigitsNoSingleUS
BinPrefix:
0b
0B
BinaryDigitsNoSingleUS:
BinaryDigitsUSopt BinaryDigit BinaryDigitsUSopt
BinaryDigitsUS:
BinaryDigitUS
BinaryDigitUS BinaryDigitsUS
BinaryDigit:
0
1
BinaryDigitUS:
BinaryDigit
_
HexadecimalInteger:
HexPrefix HexDigitsNoSingleUS
HexDigits:
HexDigit
HexDigit HexDigits
HexDigitsUS:
HexDigitUS
HexDigitUS HexDigitsUS
HexDigitsNoSingleUS:
HexDigitsUSopt HexDigit HexDigitsUSopt
HexDigitsNoStartingUS:
HexDigit
HexDigit HexDigitsUS
HexDigit:
DecimalDigit
HexLetter
HexDigitUS:
HexDigit
_
HexLetter:
a
b
c
d
e
f
A
B
C
D
E
F
정수는 10진, 2진, 또는 16진으로 지정할 수 있습니다.
- 10진 정수는 10진 숫자의 연속입니다.
- 2진 정수는
0b또는0B가 앞에 오는 2진 숫자의 연속입니다. - C 스타일 8진 정수 표기(예:
0167)는 10진 표기와 혼동하기 너무 쉬워; 문자열 리터럴에서만 완전히 지원됩니다. D는 여전히std.conv.octal템플릿을 통해 컴파일 타임에 해석되는 8진 정수 리터럴을 지원합니다. 예:octal!167. - 16진 정수는
0x또는0X가 앞에 오는 16진 숫자의 연속입니다.
10 // decimal
0b1010 // binary
0xA // hex
정수는 가독성을 위해 숫자 뒤에 _ 문자를 포함할 수 있으며, 이는 무시됩니다.
20_000 // leagues under the sea
867_5309 // number on the wall
1_522_000 // thrust of F1 engine (lbf sea level)
0xBAAD_F00D // magic number for debugging
정수는 바로 뒤에 하나의 L 또는 u/U 중 하나 또는 둘 다가 올 수 있습니다. l(소문자 l) 접미사는 없다는 점에 유의하세요.
정수의 타입은 다음과 같이 해석됩니다:
| 표기 | 리터럴 | 타입 |
|---|---|---|
| 일반 10진 표기 | 0 .. 2_147_483_647 |
int |
2_147_483_648 .. 9_223_372_036_854_775_807 |
long |
|
9_223_372_036_854_775_808 .. 18_446_744_073_709_551_615 |
ulong |
|
| 명시적 접미사 | 0L .. 9_223_372_036_854_775_807L |
long |
0U .. 4_294_967_295U |
uint |
|
4_294_967_296U .. 18_446_744_073_709_551_615U |
ulong |
|
0UL .. 18_446_744_073_709_551_615UL |
ulong |
|
| 16진 표기 | 0x0 .. 0x7FFF_FFFF |
int |
0x8000_0000 .. 0xFFFF_FFFF |
uint |
|
0x1_0000_0000 .. 0x7FFF_FFFF_FFFF_FFFF |
long |
|
0x8000_0000_0000_0000 .. 0xFFFF_FFFF_FFFF_FFFF |
ulong |
|
| 명시적 접미사 16진 | 0x0L .. 0x7FFF_FFFF_FFFF_FFFFL |
long |
0x8000_0000_0000_0000L .. 0xFFFF_FFFF_FFFF_FFFFL |
ulong |
|
0x0U .. 0xFFFF_FFFFU |
uint |
|
0x1_0000_0000U .. 0xFFFF_FFFF_FFFF_FFFFU |
ulong |
|
0x0UL .. 0xFFFF_FFFF_FFFF_FFFFUL |
ulong |
정수 리터럴은 이 값들을 초과할 수 없습니다.
모범 사례 (Best Practices): 8진 정수 표기는 정수 리터럴에 지원되지 않습니다. 다만 8진 정수 리터럴은
std.conv.octal템플릿을 통해 컴파일 타임에 해석될 수 있습니다(예:octal!167).
부동소수점 리터럴 (Floating Point Literals)
FloatLiteral:
Float Suffixopt
Integer FloatSuffix ImaginarySuffixopt
Integer RealSuffixopt ImaginarySuffix
Float:
DecimalFloat
HexFloat
DecimalFloat:
LeadingDecimal . DecimalDigitsNoStartingUSopt
LeadingDecimal . DecimalDigitsNoStartingUS DecimalExponent
. DecimalDigitsNoStartingUS DecimalExponentopt
LeadingDecimal DecimalExponent
DecimalExponent:
DecimalExponentStart DecimalDigitsNoSingleUS
DecimalExponentStart:
e
E
e+
E+
e-
E-
HexFloat:
HexPrefix HexDigitsNoSingleUS . HexDigitsNoStartingUS HexExponent
HexPrefix . HexDigitsNoStartingUS HexExponent
HexPrefix HexDigitsNoSingleUS HexExponent
HexPrefix HexExponent
HexPrefix:
0x
0X
HexExponent:
HexExponentStart DecimalDigitsNoSingleUS
HexExponentStart:
p
P
p+
P+
p-
P-
Suffix:
FloatSuffix ImaginarySuffixopt
RealSuffix ImaginarySuffixopt
ImaginarySuffix
FloatSuffix:
f
F
RealSuffix:
L
ImaginarySuffix:
i
LeadingDecimal:
DecimalInteger
0 DecimalDigitsNoSingleUS
부동소수점은 10진 또는 16진 형식일 수 있으며, 최소 하나의 숫자와 소수점, 지수, 또는 FloatSuffix 중 하나를 가져야 합니다.
10진 부동소수점은 e 또는 E 뒤에 10의 지수 역할을 하는 10진 숫자가 오는 지수를 가질 수 있습니다.
-1.0
1e2 // 100.0
1e-2 // 0.01
-1.175494351e-38F // float.min
16진 부동소수점은 0x 또는 0X가 앞에 오고, 지수는 p 또는 P 뒤에 2의 지수 역할을 하는 10진 숫자가 옵니다.
0xAp0 // 10.0
0x1p2 // 4.0
0x1.FFFFFFFFFFFFFp1023 // double.max
0x1p-52 // double.epsilon
부동소수점 리터럴은 가독성을 위해 숫자 뒤에 _ 문자를 포함할 수 있으며, 이는 무시됩니다.
2.645_751
6.022140857E+23
6_022.140857E+20
6_022_.140_857E+20_
접미사가 없는 부동소수점 리터럴은 double 타입입니다. f 또는 F가 뒤에 오는 부동소수점 리터럴은 float 타입입니다. L이 뒤에 오는 부동소수점 리터럴은 real 타입입니다.
0.0 // double
0F // float
0.0L // real
리터럴은 타입의 범위를 초과할 수 없습니다. 리터럴은 타입의 유효 숫자(significant digits)에 맞게 반올림됩니다.
부동소수점 리터럴에 .과 타입 접미사가 있으면, 사이에 최소 하나의 숫자가 있어야 합니다:
1f; // OK, float
1.f; // error
1.; // OK, double
참고: 허수 부동소수점 값을 나타내는
i가 뒤에 오는 부동소수점 리터럴은 폐기(deprecated)되었습니다.
키워드 (Keywords)
키워드는 예약된 식별자입니다.
Keyword:
abstract
alias
align
asm
assert
auto
body
bool
break
byte
case
cast
catch
cdouble
cent
cfloat
char
class
const
continue
creal
dchar
debug
default
delegate
delete
deprecated
do
double
else
enum
export
extern
false
final
finally
float
for
foreach
foreach_reverse
function
goto
idouble
if
ifloat
immutable
import
in
inout
int
interface
invariant
ireal
is
lazy
long
macro
mixin
module
new
nothrow
null
out
override
package
pragma
private
protected
public
pure
real
ref
return
scope
shared
short
static
struct
super
switch
synchronized
template
this
throw
true
try
typeid
typeof
ubyte
ucent
uint
ulong
union
unittest
ushort
version
void
wchar
while
with
__FILE__
__FILE_FULL_PATH__
__FUNCTION__
__LINE__
__MODULE__
__PRETTY_FUNCTION__
__gshared
__parameters
__rvalue
__traits
__vector
특수 토큰 (Special Tokens)
이 토큰들은 다음 표에 따라 다른 토큰으로 교체됩니다:
| 특수 토큰 | 교체됨 |
|---|---|
__DATE__ |
컴파일 날짜의 문자열 리터럴 "mmm dd yyyy" |
__EOF__ |
스캐너가 이 토큰 이후 모든 것을 무시하라고 지시 |
__TIME__ |
컴파일 시간의 문자열 리터럴 "hh:mm:ss" |
__TIMESTAMP__ |
컴파일 날짜·시간의 문자열 리터럴 "www mmm dd hh:mm:ss yyyy" |
__VENDOR__ |
컴파일러 공급업체 문자열 |
__VERSION__ |
정수인 컴파일러 버전 |
구현 정의 (Implementation Defined):
__VENDOR__의 교체 문자열 리터럴과__VERSION__의 교체 정수 값.
특수 토큰 시퀀스 (Special Token Sequences)
SpecialTokenSequence:
# line IntegerLiteral Filespecopt EndOfLine
# line __LINE__ Filespecopt EndOfLine
Filespec:
" DoubleQuotedCharactersopt "
특수 토큰 시퀀스는 어휘 분석기에 의해 처리되며, 다른 토큰들 사이 어디에나 나타날 수 있고 구문 파싱에 영향을 주지 않습니다.
특수 토큰 시퀀스는 시퀀스 시작의 첫 # 토큰 뒤에 오는 첫 새 줄에 의해 종료됩니다.
현재 #line이라는 하나의 특수 토큰 시퀀스만 있습니다.
이것은 다음 소스 줄의 줄 번호를 IntegerLiteral로, 선택적으로 현재 소스 파일 이름을 Filespec으로 설정합니다. 다음 소스 텍스트 줄부터 적용됩니다.
예를 들어:
int #line 6 "pkg/mod.d"
x; // this is now line 6 of file pkg/mod.d
구현 정의 (Implementation Defined): 소스 파일과 줄 번호는 전형적으로 오류 메시지를 출력하고 생성된 코드를 심볼릭 디버깅 출력의 소스로 매핑하는 데 사용됩니다.
더 알아보기
- Introduction — 컴파일 단계 개요.
- Interpolation Expression Sequence — 토큰화와 관련된 보간 표현식 시퀀스.
- Grammar — D 문법 전체 정의.