D 言語のコンパイラは、コンパイル手順が明確に定められています。 コンパイル時には、まずソースファイルに使われている文字コードを調べ、適切な解析を行います。 使用できる文字コードは ASCII か UTF 形式のいずれかと定められています。
コードは、他の多くのプログラミング言語の解析方法と同様に、トークンと呼ばれる最小単位に分解されます。 トークンとは、英文における個々の英単語のような存在です。 英単語のように、それ単体で意味を成すものから、熟語のように周囲のトークンと連帯して意味を発生させることもあります。
アルファベットなどの一連の文字は 1 つのトークンとして認識され、トークンは 1 つい上の空白か定められている記号で分解されます。 空白とは、1 文字以上のスペース文字、タブ文字、改行文字、そしてコメントであると定められています。
コメントは、C 言語と C++ 言語で採用されている一般的なコメントを利用することができます。 C 言語のコメントは /* で始まり */ で終わる複数行コメントで、これらのコメントの間には改行などを自由に入れることができます。 C++ 言語のコメントは // で始まり改行文字で終了します。 つまり、1 行コメントです。
D 言語では、これらのコメントに加えて入れ子可能な複数行コメントを用いることができます。 入れ子可能な複数行コメントは /+ で始まり +/ で終わります。 これらのコメントは、トークンを分解する能力があることにも注目する必要があります。
import std.c.stdio; int main() { /* C 言語のコメント */ //C++ のコメント /////////////////これもOKです////////////////// /+ このコメントは D 言語特有のコメント /+入れ子にすることができます+/ この部分もコメントです +/ printf("Kitty on your lap\n"); return/*コメントは空白と判断されます*/0; }
やはり、注目するべきは新しいコメント /+ +/ でしょう。 従来の複数行コメント /* */ は入れ子にすることができませんでした。 例えば /* /* */ */ というコメントを記述した場合、最初の */ でコメントを抜け出してしまうため、後の */ が無効なトークンとしてエラーになりました。 しかし /+ +/ 形式のコメントであれば、上のプログラムのように入れ子にすることができるのです。
このように、空白やコメントなどでトークンに分解され、コンパイラは意味を分析します。 トークンはいくつかの種類が存在し、その種類ごとに役割が異なります。
import や int、または return など、D 言語そのものが兼ね備えている最も基本的な命令用のトークンを予約語と呼びます。 予約語は、言語仕様によって明確に定められていて、仕様に基づいた意味以外を持つことはありません。 main や printf 等の関数名や、std などのパッケージ及びモジュール名は、プログラマが自由に命名することができます。 これを識別子と呼びます。 識別子は常に一意に認識できなければならず、同名の識別子は基本的に共存できません。
また、"Kitty on your lap" や 0 などの固定的な情報をリテラルと呼びます。 リテラルについては次の章で詳しく解説します。
以上のトークンのどれにも属さないトークンは、+ や =、& 記号など、演算やトークンを区切る役割を持ちます。 ソースコードに書くあらゆる文字は、必ずいずれかのトークンに属し、コンパイラが適切に分解可能な言語仕様に基づいて書かなくてはなりません。 プログラマは、自分が書いているソースコードの一字一句の意味を正しく理解している必要があります。 なぜならば、コンピュータ言語は人間が使う自然言語とは異なり、曖昧さがないためです。