トークン

この章では、スクリプトプログラムのソースコードの基本的構成要素について 定義する。

Unicode エスケープ

ソースコード内に現れる次のような規則的な文字の並びは Unicode エスケープとして解釈され、一つの Unicode コードポイントに変換される。Unicode エスケープには識別子 Unicode エスケープと文字列 Unicode エスケープの二種類がある。

IdentifierUnicodeEscape
\[ HexadecimalDigit+ ]
StringUnicodeEscape
\u HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit
\U HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit

Unicode エスケープに含まれる HexadecimalDigit の並びは十六進整数を表し、 Unicode エスケープはその数値と等しい Unicode コードポイントに変換される。 例えば、\u0020 という文字列 Unicode エスケープは空白文字 (U+0020) を表す Unicode コードポイントに変換される。

Unicode エスケープの表す整数が Unicode コードスペース (0 以上 10FFFF(16) 以下) の範囲外のときは、文法エラーとする。

Unicode エスケープは多重に解釈しない。例えば、文字列リテラル "\u005Cu0040" の中の \u005C は Unicode エスケープとして解釈されるので、これは文字列リテラル "\u0040" と等しいが、更にこれを "@" と解釈することはない。

ソースコードの終端

非終端記号 EOC は、ソースコードの終端を表す。

EOC
!{任意の Unicode コードポイント}

区切り

区切りは、トークン以外の構文構成要素であり、トークンを分離する。

区切りは、任意の個数 (0 個を含む) の空白文字、改行文字、またはコメントから成る。

D
(WhiteSpace / LineSeparator / Comment)*

キーワード区切りは、キーワードとその直後のトークンを分離する。

キーワード区切りはキーワードの直後に識別子文字が続かないことを強制する。

KD
!IdentifierChar D

空白文字

空白文字は以下の Unicode 文字として定義する:

WhiteSpace
{Unicode のカテゴリ Zs (space separator) に属する文字}
{水平タブ (U+0009)}
{垂直タブ (U+000B)}
{フォームフィード (U+000C)}

これらの文字は、コメントやトークンの一部を構成する場合があるが、 この場合それらは単なるコメントやトークンの構成要素と見なし、 空白文字とは見なさない。

改行文字

改行文字は以下の Unicode 文字列として定義する:

LineSeparator
{ラインフィード (U+000A)}
{キャリッジリターン (U+000D)} {ラインフィード (U+000A)}?
{ネクストライン (U+0085)}
{行区切り (U+2028)}
{段落区切り (U+2029)}

定義の通り、キャリッジリターンの直後にラインフィードが続くときは、 その二つを合わせて一つの改行文字とする。

これらの文字は、コメントやトークンの内部に出現する場合がある。 この場合、それらはコメントやトークンの一部となる。 ただし、パーサがソースコードの行数を数えるときは、これらの文字がコメントや トークンの一部であるかどうかにかかわらずこれらを改行文字として数えるべきであり、 また上記の文字以外の文字を改行文字として数えるべきでない。

コメント

コメントは以下のように定義する:

Comment
// ((!LineSeparator) {任意の Unicode コードポイント})*
/* ((!*/) {任意の Unicode コードポイント})* */

コメントには行末までのコメントと任意範囲のコメントがある。

行末までのコメントは、二つのスラッシュ // で始まり、 その後現れる最初の改行文字の直前で終わる。 改行文字がその後に一つも現れない場合は、 ソースコードの末尾までを行末までのコメントとする。

任意範囲のコメントは、連続するスラッシュとアスタリスク /* で始まり、その後現れる最初の連続するアスタリスクとスラッシュ */ で終わる。 連続するアスタリスクとスラッシュが一つも現れない場合は、文法エラーとする。 任意範囲のコメントの中には改行文字を含む任意の文字を含めることが出来る。 例えば、/*/ は任意範囲のコメントとはみなさないが、/*//* */ は一つの任意範囲のコメントである。

コメントの内部に現れる文字は、コメントの終わりを示す文字以外は文法的な 意味を持たない。特に、コメントの中に別のコメントを入れることはできない。

トークン

トークンは、プログラムにとって具体的な意味を持つソースコードの 構成単位である。

識別子

識別子先頭文字で始まるトークンは識別子である。 識別子は識別子先頭文字で始まり、それに続く 0 文字以上の識別子文字によって構成される。

Identifier
IdentifierFirstChar IdentifierChar* D
IdentifierFirstChar
{Unicode カテゴリ letter (L) の各サブカテゴリの文字}
{Unicode カテゴリ letter number (Nl) の各サブカテゴリの文字}
{アンダースコア _ (U+005F)}
{ドル $ (U+0024)}
{上記の文字に対応する IdentifierUnicodeEscape}
IdentifierChar
IdentifierFirstChar
{Unicode カテゴリ mark (M) の各サブカテゴリの文字}
{Unicode カテゴリ number (N) の各サブカテゴリの文字}
{Unicode カテゴリ connector punctuation (Pc) の文字}
{Unicode カテゴリ other format (Cf) の文字}
{上記の文字に対応する IdentifierUnicodeEscape}

複数の識別子は、それを構成する Unicode 文字のコードが完全に一致する場合のみ等しいとみなす。

識別子では識別子 Unicode エスケープが解釈される。例えば、ソースコードにおいて abca\[0062]c は等しい識別子トークンとみなす。識別子 Unicode エスケープが表している文字が識別子として本来使えない文字ならば、 文法エラーとする。

キーワード

キーワードは、記号 @ とそれに続く一つ以上の識別子文字によって構成されるトークンである。

キーワードの直後に空白文字などを一切間に置かずに 識別子文字を置くことはできない。

文字列リテラル

文字列リテラルは、スクリプトプログラムで扱われる文字列を表す。

StringLiteral
' (StringLiteralChar / ")* ' D
" (StringLiteralChar / ')* " D
@' (\ / StringChar / '' / ")* ' D
@" (\ / StringChar / "" / ')* " D
StringLiteralChar
StringChar
StringCharEscape
StringChar
{'"\ 以外の任意の Unicode コードポイント}
StringCharEscape
StringUnicodeEscape
\ {任意の Unicode コードポイント}

文字列トークンの内容は、引用符 ' または " で囲まれた Unicode 文字列である。文字列トークンの内容を囲む引用符が ' であるとき、 その文字列トークンの中身において " は特別な意味を持たず、また、 その逆も同様である。

文字列トークンの先頭に @ があれば、その文字列トークンでは記号 \ によるエスケープが無効となる。このとき、記号 \ は他の文字と同じく文字列を構成する一文字とみなす。このとき、文字列に含まれる '' は一つの文字 ' を表し、"" は一つの文字 " を表す。

先頭に @ がなければ、エスケープは有効であり、記号 \ は文字列トークンの中身において特別な意味を持つ。

StringCharEscape の解釈

エスケープが有効の文字列リテラルの中身において、StringCharEscape はそれぞれ次のような一つの Unicode コードポイントを表すものと解釈する。

StringUnicodeEscape
その文字列 Unicode エスケープが表す Unicode コードポイント
\0
Null 文字 (U+0000)
\a
ベル文字 (U+0007)
\b
バックスペース (U+0008)
\f
フォームフィード (U+000C)
\n
ラインフィード (U+000A)
\r
キャリッジリターン (U+000D)
\t
水平タブ (U+0009)
\v
垂直タブ (U+000B)
上記以外の StringCharEscape: \ {Unicode 文字}
\ に続く文字が 0 から 9 までの数字または a から z までまたは A から Z までのアルファベットならば、文法エラーとする。 それ以外のコード単位である場合は、そのコード単位そのものを表す。

注意: 文法上は、フォームフィードや水平タブをエスケープせずに そのまま文字列リテラルの中身にしてもよい。

文字列リテラルの例

次の四つの文字列リテラルは、全て a"b'c\d という 7 文字の文字列を表す。

数値リテラル

数値リテラルは、スクリプトプログラム内で数を直接表す記法である。 数値リテラルには、整数リテラル浮動小数点数リテラルの二種類がある。

以下に、数値リテラルの定義に用いるための解析ルールをいくつか定義する:

ImaginaryMark
i / I
ExactNumberMark
x / X
IllegalNumberTrailer
IdentifierChar
. DecimalDigit

ImaginaryMark は、数値リテラルが純虚数を表すことを表す。大文字の I は数字の 1 と見かけが紛らわしいので、 数値リテラルでは大文字の I の仕様は推奨しない。

ExactNumberMark は、浮動小数点数リテラルが表す数値に誤差がないことを表す。

IllegalNumberTrailer は、数値リテラルの直後に続くことができない文字列を定めるために使うルールである。

整数リテラル

整数リテラルは、スクリプトプログラム内で整数を直接表す記法である。 整数リテラルは、二進法、八進法、十進法、十六進法のいづれかで表される。

IntegerLiteral
Integer ImaginaryMark? !IllegalNumberTrailer D
Integer
BinaryInteger
OctalInteger
HexadecimalInteger
DecimalInteger
BinaryInteger
(0b / 0B) BinaryDigit+
BinaryDigit
0 / 1
OctalInteger
(0o / 0O) OctalDigit+
OctalDigit
0 / 1 / 2 / 3 / 4 / 5 / 6 / 7
DecimalInteger
DecimalDigit+
DecimalDigit
0 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9
HexadecimalInteger
(0x / 0X) HexadecimalDigit+
HexadecimalDigit
0 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / a / b / c / d / e / f / A / B / C / D / E / F

整数リテラルの Integer の部分は、非負整数を位取り記数法により表したもので ある。BinaryInteger は二進法、OctalInteger は八進法、DecimalInteger は十進法、 HexadeicmalInteger は十六進法によるリテラルである。DecimalInteger 以外の 整数リテラルの最初の二文字はリテラルの種類を区別する記号であり、数字ではない。

整数リテラルは大文字と小文字の区別をしない。例えば、0xABC0Xabc は等価である。数字の 0 と大文字の O は見かけが紛らわしいので、八進法リテラルでは大文字の O の使用は推奨しない。

プログラミング言語によっては 0 で始まり 0 から 7 までの数字のみで構成される整数リテラルは八進法によるリテラルとみなされるが、 #Script ではこのようなリテラルは十進法によるリテラルである。 混乱を避けるため、プログラマは 0 で始まる十進整数リテラルを記述すべきでない。

整数リテラルに ImaginaryMark (i または I) が含まれている場合、それは純虚数を表す。すなわち、その整数リテラルは そのリテラルの Integer の部分が表す値に虚数単位 i を掛けた値を表す。

整数リテラルに ImaginaryMark が含まれていない場合、そのリテラルはその Integer の部分が表す整数を表す。

浮動小数点数リテラル

浮動小数点数リテラルは、スクリプトプログラム内で 浮動小数点数を直接表す記法である。

FloatLiteral
FloatBody FloatPostfix !IllegalNumberTrailer D
FloatBody
(. DecimalDigit+ / DecimalDigit+ . DecimalDigit*) Exponent?
DecimalInteger Exponent
Exponent
(e / E) (+ / -)? DecimalInteger
FloatPostfix
ImaginaryMark ExactNumberMark? / ExactNumberMark? ImaginaryMark?

浮動小数点数リテラルが表す数値は、次のようにして算出する:

  1. リテラルの仮数部 (FloatBody から Exponent を除いたもの) を十進位取り記数法で表記された実数として解釈し、 その値を M とする。このとき、. は小数点として扱う。
  2. Exponent がある場合は、それに含まれる DecimalInteger を十進位取り記数法で表記された整数とみなし、その整数の値を E とする。 ただし、Exponent に - を含む場合は E は符号を反転して負数とする。Exponent がない場合は、E は 0 とする。
  3. FloatPostfix に ImaginaryMark が含まれる場合は、虚数単位 iU とする。さもなくば、整数 1 を U とする。
  4. 浮動小数点リテラルが表す数値は M × 10E × U である。また、浮動小数点リテラルが表す数値の絶対値は M × 10E である。

実行環境は、浮動小数点リテラルが表す数値の絶対値が原始実数型の表せる値の範囲に ない場合は、文法エラーとしてもよい。

浮動小数点リテラルは、数値そのものだけではなく、その精度も表す。 浮動小数点リテラルの FloatPostfix に ExactNumberMark が含まれているならば、その絶対精度は無限大である。 さもなくば、浮動小数点リテラルの精度は、上記で算出した数値を元に 次のようにして算出する:

M が 0 の場合:
  1. リテラルの仮数部の小数点 . よりも後にある数字の桁数を C とする。リテラルの仮数部に小数点が含まれていなければ、0 を C とする。
  2. このリテラルの表す数値の絶対精度は、CE である。
M が 0 でない場合:
  1. リテラルの仮数部から小数点 . を除いたものを十進位取り記数法で 表記された整数として解釈し、その値を N とする。
  2. このリテラルの表す数値の相対精度は、log10N である。

例えば、浮動小数点リテラル 00.0000E+3 の絶対精度は 4 − 3 = 1 であり、123.45678 の相対精度は log1012345678 である。

© 2006-2007 Magicant