2.3 トークン
コードの「単語」
C 言語のテキストをより細かく分解し、コンパイラがどのように C 言語を処理しているかを知れば、プログラミングに対してより構造的な理解が深まるでしょう。実は C 言語を細かく分解していくと、コンパイラが認識する最小単位のテキスト、トークンとなります。トークンとは、これ以上分解することのできない C 言語の最小単位のテキストで、英文における単語のようなものです。トークンには、次のような分類があります
- キーワード
- 識別子
- 定数
- リテラル文字列
- 演算子
- 区切り子
キーワードとは C 言語が仕様レベルで予約済みの名前のことで、前回のプログラムで紹介した return などはキーワードに属します。
識別子とはコンパイラがデータの位置などを識別するためにソースコード上で命名された名前です。例えば、関数名は識別子です。
定数とはソース上で指定された固定的な値で、例えば 10 というような数値は定数です。
リテラル文字列は前回説明したように二重引用符 " で囲まれた文字列のことです。
演算子とは後ほど説明する計算のために用いる記号で + や - 記号は演算子に属します。
区切り子とは [ ] ( ) { } * , : = ; ... # のいずれかの記号です。main() メソッドの宣言における丸括弧 ( ) や波括弧 { }、printf() 関数や return 文の末尾にあるセミコロン ; などが区切り子に相当します。
例えば、もう一度「2.2 はじめてのC言語.コード2」を見てください。
#include <stdio.h> int main() { printf("Kitty on your lap\n"); return 0; }
このプログラムは、次のようなトークンの列で構成されています。ただし、この場では先頭の #include から始まる行は考えないものとします。
トークン | トークンの種類 |
---|---|
int | キーワード |
main | 識別子 |
( | 区切り子 |
) | 区切り子 |
{ | 区切り子 |
printf | 識別子 |
( | 演算子 |
"Kitty on your lap\n" | リテラル文字列 |
) | 演算子 |
; | 区切り子 |
return | キーワード |
0 | 定数 |
; | 区切り子 |
} | 区切り子 |
コンパイラは、このように文をトークンレベルに分解して、一つひとつの命令を認識していきます。日本語のような人間が使用する自然言語に比べ、プログラミング言語には無駄な記号がひとつもないということがわかるでしょう。プログラム中のあらゆる文字や記号には、明確な意味が定義されているのです。そこに曖昧なものはありません。
トークンの間に演算子や区切り子を使ったトークンがあれば、構文に基づいてトークンは分解されますが、キーワードや識別子、定数などが連続して続く場合、それぞれのトークンは空白文字で区切らなければなりません。空白文字とは、次のいずれかの文字のことを表します。
- スペース
- 水平及び垂直タブ
- 改行
- 改ページ
- コメント
コメントとは、ソースの説明を行うための注釈のことです。このテキストは実際のプログラムには何の関係もないため、コンパイル時に空白として扱われます。コメントについては「2.5 コメント」で詳しく解説します。
C 言語は、トークンの間に自由に空白文字を挿入することが可能です。そのため、次のようなプログラムも問題なくコンパイルすることができます。
#include <stdio.h> int main() {printf ("Kitty on your lap\n" ); return 0; }
一見このプログラムはぐちゃぐちゃですが、トークンレベルで分解してみると問題はありません。ただし、int と main の間の空白や return と 0 の空白は省略することはできません。空白がない場合はトークンが分解されないため、intmain という識別子だと認識されてしまいます。