The Go Programming Language Specificationの翻訳、3回目です。
前回までの訳はGo言語仕様[日本語訳]にまとめてあります。


字句要素

コメント

コメントには2種類の書式があります。
ひとつ目の書式は文字シーケンス//で始まり、行の終わりまでがコメントとなります。ふたつ目は文字シーケンス/*で始まり、文字シーケンス*/までがコメントとなります。コメントを入れ子にすることはできません。

トークン

トークンには識別子、キーワード、演算子と区切り文字、リテラルの4つのクラスがあります。
ホワイトスペースはスペース(U+0020)、水平タブ (U+0009)、キャリッジリターン (U+000D)、改行 (U+000A)です。ホワイトスペースは、それがなければ一つのトークンとして結合されてしまうトークンを分割するほかは無視されます。コメントはホワ イトスペースと同等に扱われます。入力をトークンに分割する際、次のトークンは長い文字列シーケンスから成る有効なトークンです。

識別子

識別子は変数や型といったプログラムの実体に対し名前をつけます。
識別子は一文字以上の字(レター)と数字から構成されます。先頭一文字は字でなくてはなりません。

identifier = letter { letter | unicode_digit } .
a
_x9
ThisVariableIsExported
αβ

いくつかの識別子は事前宣言済みです。

キーワード

下に示すキーワードは予約されているため、識別子としては使用できません。

break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var

演算子と区切り文字

下に示す文字シーケンスは、演算子、区切り文字および、その他の特別なトークンです。

+    &     +=    &=     &&    ==    !=    (    )
-    |     -=    |=     ||    <     <=    [    ]
*    ^     *=    ^=     <-    >     >=    {    }
/    <<    /=    <<=    ++    =     :=    ,    ;
%    >>    %=    >>=    --    !     ...   .    :
     &^          &^=

整数リテラル

整数リテラルは整数定数を表す数字の並びです。
10進数以外の値を表すにはプレフィックスをつけます。0は8進数で、0xまたは0Xを付けると16進数になります。16進数の場合、文字a~fA~Fを10~15の値を表すために使います。

int_lit     = decimal_lit | octal_lit | hex_lit .
decimal_lit = ( "1" ... "9" ) { decimal_digit } .
octal_lit   = "0" { octal_digit } .
hex_lit     = "0" ( "x" | "X" ) hex_digit { hex_digit } .
42
0600
0xBadFace
170141183460469231731687303715884105727

浮動小数点リテラル

浮動小数点リテラルは浮動小数点定数を表す小数で、整数部・小数点・小数部・指数部を持ちます。
整数部と小数部は10進数から成ります。指数部はeまたはEと、それに続く符号(オプション)と10進数の指数です。
整数部と分数部のどちらかは省略でき、また小数点か指数部のどちらかも省略できます。

float_lit = decimals "." [ decimals ] [ exponent ] |
            decimals exponent |
            "." decimals [ exponent ] .
decimals  = decimal_digit { decimal_digit } .
exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals .
0.
2.71828
1.e+0
6.67428e-11
1E6
.25
.12345E+5

文字リテラル

文字リテラルは整数定数、概して一文字以上の文字をシングルクォートでくくりユニコードのコードポイントを表現します。

クォート内にはシングルクォートと改行を除くどんな文字も記述できます。バックスラッシュを使用したマルチ文字シーケンスの各書式を使ってエンコードすることで、シングルクォート文字自体も表せます。

クォートを使うと簡単に一文字を表すことができます。これはGo言語のソースがUTF-8エンコードされたユニコード文字であり、UTF-8エンコードされている複数のバイト列であってもひとつの整数値を表せるからです。
たとえば、リテラル'a'はリテラルa、ユニコード U+0061、値0x61を表す1バイトの値です。一方'ä' はリテラルa-dieresis、 U+00E4、値0xe4を表しますが、UTF-8エンコードでは2バイト (0xc3 0xa4)です。

バックスラッシュによるエスケープを使って任意の値をアスキー文字として表すことができます。定数として整数値を表すには次の4通りの方法があります。\xに続いた2つの16進数文字、\uに続いた4つの16進数文字、\Uに続いた8つの16進数文字、\に続いた3つの8進数文字です。それぞれのリテラルの値は、基数に対応した数字で表される値です。

これらが表す値はすべて整数ですが、値の範囲がそれぞれ異なります。8進数のエスケープで表す値は0-255の範囲内でなければなりません。16真数のエスケープはその書式を満たす0-255が範囲です。\u\Uはユニコードのコードポイントを表すため、いくつかの値は不正な値となります。特に0x10FFFFより大きい数と上位サロゲートは不正な値です。

バックスラッシュで特定の一文字をエスケープすることで特別な値を表します。

\a   U+0007 alert or bell
\b   U+0008 backspace
\f   U+000C form feed
\n   U+000A line feed or newline
\r   U+000D carriage return
\t   U+0009 horizontal tab
\v   U+000b vertical tab
\\   U+005c backslash
\'   U+0027 single quote  (valid escape only within character literals)
\"   U+0022 double quote  (valid escape only within string literals)

これ以外のバックスラッシュで始まるシーケンスは文字リテラル内では不正となります。

char_lit         = "'" ( unicode_value | byte_value ) "'" .
unicode_value    = unicode_char | little_u_value | big_u_value | escaped_char .
byte_value       = octal_byte_value | hex_byte_value .
octal_byte_value = `\` octal_digit octal_digit octal_digit .
hex_byte_value   = `\` "x" hex_digit hex_digit .
little_u_value   = `\` "u" hex_digit hex_digit hex_digit hex_digit .
big_u_value      = `\` "U" hex_digit hex_digit hex_digit hex_digit
                           hex_digit hex_digit hex_digit hex_digit .
escaped_char     = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) .
'a'
'ä'
'本'
'\t'
'\000'
'\007'
'\377'
'\x07'
'\xff'
'\u12e4'
'\U00101234'

文字列リテラル

文字列リテラルは結合された文字シーケンスから成る文字列定数を表します。
文字列リテラルには未加工(raw)文字列リテラルと、解釈有(interpreted)文字列リテラルの2通りの記述方法があります。

未加工文字列リテラルは、バッククォート``で囲まれた文字シーケンスです。クォート内にはバッククォート以外の文字すべてを記述できます。この未加工文字列リテラルの示す値は、クォート内の解釈されない文字から成る文字列で、バックスラッシュも特別な意味を持たず、また文字列は複数行にまたがることも可能です。

解釈有文字列リテラルはダブルクォート""で囲まれた文字シーケンスです。クォートで囲まれたテキストは複数行にまたがることはできず、文字リテラルとおなじくバックスラッシュによるエスケープを解釈した結果がリテラルの値となります。(\'は使えませんが、\"は使用できます。)3つの数字から成る8進数(\000) 、2つの数字から成る16進数 (\x00)のエスケープは個々のバイトを表します。他のすべてのエスケープは(マルチバイトも含め) UTF-8エンコードされた個別の文字を表します。したがって文字列リテラル \377\xFFは、1バイトの値0xFF=255を表します。一方 ÿ\u00FF\U000000FF、\xc3\xbfは、文字U+00FFをUTF8エンコーディングした値である2バイト0xc3 0xbfを表します。

文字列シーケンスを並べたものは結合されて、ひとつの文字列となります。

StringLit              = string_lit { string_lit } .
string_lit             = raw_string_lit | interpreted_string_lit .
raw_string_lit         = "`" { unicode_char } "`" .
interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
`abc`  // same as "abc"
`\n
\n`    // same as "\\n\n\\n"
"\n"
""
"Hello, world!\n"
"日本語"
"\u65e5本\U00008a9e"
"\xff\u00FF"
"Alea iacta est."
"Alea " /* The die */ `iacta est` /* is cast */ "."  // same as "Alea iacta est."

次の例は、すべて同じ文字列を表しています。

"日本語"                                 // UTF-8 input text
`日本語`                                 // UTF-8 input text as a raw literal
"\u65e5\u672c\u8a9e"                    // The explicit Unicode code points
"\U000065e5\U0000672c\U00008a9e"        // The explicit Unicode code points
"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"  // The explicit UTF-8 bytes

ソースコード内に、アクセントとアルファベットを結合した場合のように2つのコードポイントから成る「文字リテラル」があるとエラーとなります。こ れは文字リテラルがひとつのコードポイントを表すためです。ただし「文字列リテラル」には2つのコードポイントから成る文字を記述できます。