Scala programs are written using the Unicode Basic Multilingual Plane (BMP) character set; Unicode supplementary characters are not presently supported. This chapter defines the two modes of Scala's lexical syntax, the Scala mode and the XML mode. If not otherwise mentioned, the following descriptions of Scala tokens refer to Scala mode, and literal characters 'c' refer to the ASCII fragment \u0000-\u007F.
Scala プログラムはユニコード基本多言語面 (BMP) 文字セットを使って書かれます; ユニコード補助文字は現在サポートされていません。 この章では Scala の字句構文の 2 つのモード、Scala モードと XML モードを定義します。以下では断りがなければ、 Scala トークンの記述は Scala モードを意味し、リテラル文字 'c' は ASCIIフラグメント \u0000-\u007F を意味します。
In Scala mode, Unicode escapes are replaced by the corresponding Unicode character with the given hexadecimal code.
Scala モードでは、 ユニコードエスケープ は与えられた 16進コードに対応するユニコード文字で置き換えられます。
UnicodeEscape ::= \{\\}u{u} hexDigit hexDigit hexDigit hexDigit hexDigit ::= '0' | … | '9' | 'A' | … | 'F' | 'a' | … | 'f' |
To construct tokens, characters are distinguished according to the following classes (Unicode general category given in parentheses):
トークンの組み立てにあたり、文字は次の区分に従って区別されます (括弧内はユニコード一般カテゴリを表します)。
構文:
op ::= opchar {opchar} varid ::= lower idrest plainid ::= upper idrest | varid | op id ::= plainid | '\`' stringLit '\`' idrest ::= {letter | digit} ['_' op]
There are three ways to form an identifier. First, an identifier can start with a letter which can be followed by an arbitrary sequence of letters and digits. This may be followed by underscore '_' characters and another string composed of either letters and digits or of operator characters. Second, an identifier can start with an operator character followed by an arbitrary sequence of operator characters. The preceding two forms are called plain identifiers. Finally, an identifier may also be formed by an arbitrary string between back-quotes (host systems may impose some restrictions on which strings are legal for identifiers). The identifier then is composed of all characters excluding the backquotes themselves.
識別子には 3 つの形があります。 1 つめは、文字で始まり、文字または 10進数字の任意の並びが後に続く識別子です。 これには、下線 '_'を後に続けることができ、文字あるいは 10進数字から構成される他の文字列、 または演算子文字から構成される文字列を続けることができます。 2 つめは、演算子文字で始まり、演算子文字の任意の並びが続く識別子です。 これら前の 2 つの形は プレーン な識別子 (訳注:訳は、一般識別子)と呼ばれます。 最後の形は、任意の文字列をバッククォートで囲んだものです (ホストシステムは、 文字列が識別子として正しいということに制限を課すかもしれません)。 識別子はバッククォート自身を除くすべての文字で構成されることになります。
通常は、最長一致規則が適用されます。例えば、文字列
big_bob++=`def`
は、3 つの識別子 big_bob、++=、def に分解されます。 パターンマッチングの規則では、さらに、小文字から始まる 変数識別子(variable identifiers) と、 そうでない 定数識別子(constant identifiers) を区別します。
'$' 文字はコンパイラが生成する識別子用に予約されています。 ユーザープログラムは '$' 文字を含む識別子を定義すべきではありません。
The following names are reserved words instead of being members of the syntactic class id of lexical identifiers.
次の名前は予約語であり、字句上の識別子の構文上の識別種には属していません。
abstract case catch class def do else extends false final finally for forSome if implicit import lazy match new null object override package private protected return sealed super this throw trait try true type val var while with yield _ : = => <- <: <% >: # @
ASCII の '=>'と '<-' に等価な、ユニコード演算子 \u21D2 '⇒' と \u2190 '←' も予約されています。
Example 1.1.1
次は識別子の例です:
x Object maxIndex p2p empty_? + `yield` αρετη _y dot_product_* __sysstem _MAX_LEN_
Example 1.1.2
文字列をバッククォートで囲むことは、Scala の予約語
である Java 識別子にアクセスする必要があるときの 1 つの解決策です。例えば、
文 Thread.yield() は、yield が Scala の予約語ですから、文法違反です。
しかし、次の回避策があります:
Thread.`yield`()
構文:
semi ::= ';' | nl {nl}
Scala is a line-oriented language where statements may be terminated by semicolons or newlines. A newline in a Scala source text is treated as the special token "nl" if the three following criteria are satisfied:
Scala は、文をセミコロンあるいは改行によって終えてもよい行指向(line-oriented) 言語です。 Scala ソーステキスト中の改行は、 もし次の 3 つの条件が満たされるなら、特別なトークン "nl" として扱われます:
文を終結させることができるトークンは、リテラル、識別子と次の区切り文字と 予約語です。
this null true false return type <xml-start> _ ) ] }
The tokens that can begin a statement are all Scala tokens except the following delimiters and reserved words:
文を始めることができるトークンは、次のデリミタと予約語 以外の 、 すべての Scala トークンです。
catch else extends finally forSome match with yield , . ; : = => <- <: <% >: # [ ) ] }
A case token can begin a statement only if followed by a class or object token.
case トークンは、class あるいは object トークンが後に続くときのみ、文を始める ことができます。
Newlines are enabled in:
改行は次の場所で可能です。
Newlines are disabled in:
改行できない場所は次です
Note that the brace characters of {...} escapes in XML and string literals are not tokens, and therefore do not enclose a region where newlines are enabled.
XML における {...}エスケープの波括弧文字と、文字列リテラルはトークンではない ことに注意してください。ですから、それらは改行可能な領域を囲みません。
Normally, only a single nl token is inserted between two consecutive non-newline tokens which are on different lines, even if there are multiple lines between the two tokens. However, if two tokens are separated by at least one complete blank line (i.e. a line which contains no printable characters), then two nl tokens are inserted.
通常、ただ 1 つの nl トークンが、 異なる行にある継続する 2 つの非改行トークンの間に、 たとえその 2 つのトークン間に多数の行があるとしても、挿入されます。 しかし、もし 2 つのトークンが、少なくとも 1 つの完全な空白行(すなわち、 印字可能な文字を含んでいない行)で分割されているなら、 2 つの nl トークンが挿入されます。
The Scala grammar (given in full in Appendix A) contains productions where optional nl tokens, but not semicolons, are accepted. This has the effect that a newline in one of these positions does not terminate an expression or statement. These positions can be summarized as follows:
Scala 文法(詳細は Chapter A)には、セミコロンではなく、 オプションの nl トークンが受け入れられる場所の規則があります。 それには、そういった場所の 1 つで改行しても式あるいは文は終結しない、 という効果があります。 それらの場所は次のように要約できます:
Multiple newline tokens are accepted in the following places (note that a semicolon in place of the newline would be illegal in every one of these cases):
複数の改行トークンは次の場所で受け入れられます (改行の代わりにセミコロンにすると、 すべての場合において不正となることに注意してください)。
A single new line token is accepted
次の場合、ただ 1 つの改行が受け入れられます。
Example 1.2.1
次のコードは、それぞれ 2 行からなる 4 つの正しい形の
文です。2 行の間の改行トークンは、文の区切りとして扱われません。
if (x > 0) x = x - 1 while (x > 0) x = x / 2 for (x <- 1 to 10) println(x) type IntList = List[Int]
Example 1.2.2
次のコードは無名クラスを定めます。
new Iterator[Int] { private var x = 0 def hasNext = true def next = { x += 1; x } }
改行を入れると、同じコードはローカルなブロックが後に続く、 オブジェクト生成として解釈されます。
new Iterator[Int] { private var x = 0 def hasNext = true def next = { x += 1; x } }
Example 1.2.3
次のコードはただ 1 つの式を定めます。
x < 0 || x > 10
改行を入れると、同じコードは 2 つの式として解釈されます。
x < 0 || x > 10
Example 1.2.4
次のコードはただ 1 つのカリー化された関数を定めます。
def func(xa: Int) (y: Int) = x + y
改行を入れると、同じコードは抽象関数定義と文法違反の文として解釈されます。
def func(x: Int) (y: Int) = x + y
Example 1.2.5
The following code designates an attributed definition:
次のコードは属性を持った定義を定めます。
@serializable protected class Data { ... }
改行を入れると、 同じコードは 1 つの属性と 1 つの別の文(文法違反の文)として解釈されます。
@serializable protected class Data { ... }
There are literals for integer numbers, floating point numbers, characters, booleans, symbols, strings. The syntax of these literals is in each case as in Java.
整数、浮動小数点数、文字、ブール値、シンボル、文字列用のリテラルがあります。 これらのリテラル構文は、それぞれ Java と同じです。
構文:
Literal ::= ['-'] integerLiteral | ['-'] floatingPointLiteral | booleanLiteral | characterLiteral | stringLiteral | symbolLiteral | 'null'
構文:
integerLiteral ::= (decimalNumeral | hexNumeral | octalNumeral) ['L' | 'l'] decimalNumeral ::= '0' | nonZeroDigit {digit} hexNumeral ::= '0' 'x' hexDigit {hexDigit} octalNumeral ::= '0' octalDigit {octalDigit} digit ::= '0' | nonZeroDigit nonZeroDigit ::= '1' | … | '9' octalDigit ::= '0' | … | '7'
Integer literals are usually of type Int, or of type Long when followed by a L or l suffix. Values of type Int are all integer numbers between -231 and 231 - 1, inclusive. Values of type Long are all integer numbers between -263 and 263 -1, inclusive. A compile-time error occurs if an integer literal denotes a number outside these ranges.
整数リテラルは通常 Int 型であり、L あるいは l 接尾辞が後に続くなら Long 型です。Int 型の値は、-2 31 以上 2 31 - 1 以下のすべての整数です。 Long 型の値は、-2 63 以上 2 63 - 1 以下のすべての整数です。 もし整数リテラルがこれらの範囲外の数を表すなら、コンパイルエラーが発生します。
However, if the expected type pt (§6.1) of a literal in an expression is either Byte , Short, or Char and the integer number fits in the numeric range defined by the type, then the number is converted to type pt and the literal's type is pt. The numeric ranges is given by these are:
しかし、もし式中のリテラルの要請型(expected type) pt
(§6.1)が Byte、Short、
あるいは Char のいずれかであり、
その整数値が型によって定義された数値の範囲内なら、その数は型 pt に変換されます。
それらの型の数値範囲は次です:
Byte -2
7
以上 2
7
- 1 以下
Short -2
15
以上 2
15
- 1 以下
Char 0 以上 2
16
- 1 以下
Example 1.3.1
次は整数リテラルの例です:
0 21 0xFFFFFFFF 0777L
構文:
floatingPointLiteral ::= digit {digit} '.' {digit} [exponentPart] [floatType] | '.' digit {digit} [exponentPart] [floatType] | digit {digit} exponentPart [floatType] | digit {digit} [exponentPart] floatType exponentPart ::= ('E' | 'e') ['+' | '-'] digit {digit} floatType ::= 'F' | 'f' | 'D' | 'd'
Floating point literals are of type Float when followed by a floating point type suffix F or f, and are of type Double otherwise. The type Float consists of all IEEE 754 32-bit single-precision binary floating point values, whereas the type Double consists of all IEEE 754 64-bit double-precision binary floating point values. If a floating point literal in a program is followed by a token starting with a letter, there must be at least one intervening whitespace character between the two tokens .
浮動小数点リテラルは、接尾辞 F あるいは f が後に続くなら Float 型であり、 そうでなければ Double 型です。 Float 型はすべての IEEE 754 32ビット単精度バイナリ浮動小数点値からなるのに対して、 Double 型はすべての IEEE 754 64ビット倍精度バイナリ浮動小数点値からなります。
もしプログラム中の浮動小数点リテラルの後に文字で始まるトークンが続くなら、 2 つのトークン間に少なくとも 1 つの空白文字がなければなりません。
Example 1.3.2
次は浮動小数点リテラルの例です。
0.0 1e30f 3.14159f 1.0e-100 .1
Example 1.3.3
The phrase '1.toString' parses as three different tokens: '1', '.', and 'toString'. On the other hand, if a space is inserted after the period, the phrase '1. toString' parses as the floating point literal '1.' followed by the identifier 'toString'.
語句 '1.toString' は 3 つの異なるトークン '1'、'.'、'toString' に分解されます。 他方、もしピリオドの後に空白を入れると、'1 .toString' は、 浮動小数点リテラル '1.' の後に識別子 'toString'が続いていると解析されます。
構文:
booleanLiteral ::= 'true' | 'false'
ブーリアンリテラル true と false は、Boolean型のメンバーです。
構文:
characterLiteral ::= '\'' printableChar '\'' | '\'' charEscapeSeq '\''
A character literal is a single character enclosed in quotes. The character is either a printable unicode character or is described by an escape sequence (§1.3.6).
文字リテラルは引用符で囲まれた単一文字です。 文字は、印字可能なユニコード文字であるか、 エスケープシーケンス(§1.3.6) で記述されるかのいずれかです。
Example 1.3.4
次は文字リテラルの例です。
'a' '\u0041' '\n' '\t'
Note that '\u000A' is not a valid character literal because Unicode conversion is done before literal parsing and the Unicode character \u000A (line feed) is not a printable character. One can use instead the escape sequence '\n' or the octal escape '\12' (§1.3.6).
'\u000A' は有効な文字リテラル ではない ことに注意してください。 なぜなら、リテラル解析の前にユニコード変換され、ユニコード文字 \u000A (ラインフィード) は印字可能な文字ではないからです。 その代わりに、エスケープシーケンス '\n' あるいは 8進法のエスケープ '\12' (§1.3.6)を使えます。
構文:
stringLiteral ::= '\"' {stringElement} '\"' stringElement ::= printableCharNoDoubleQuote | charEscapeSeq
A string literal is a sequence of characters in double quotes. The characters are either printable unicode character or are described by escape sequences (§1.3.6). If the string literal contains a double quote character, it must be escaped, i.e. \". The value of a string literal is an instance of class String.
文字列リテラルはダブルクォートの中の文字の並びです。 文字は、印字可能なユニコード文字であるか、エスケープシーケンス (§1.3.6) で記述されるかのいずれかです。 もし文字列リテラルがダブルクォート文字を含むなら、 エスケープして \" としなくてはなりません。 文字列リテラルの値は、 クラス String のインスタンスです。
Example 1.3.5
次は文字列リテラルの例です
"Hello,\nWorld!" "This string contains a \" character."
複数行文字列リテラル (Multi-Line String Literals)
構文:
stringLiteral ::= '"""' multiLineChars '"""' multiLineChars ::= {['"'] ['"'] charNoDoubleQuote} {'"'}
A multi-line string literal is a sequence of characters enclosed in triple quotes """ ...""". The sequence of characters is arbitrary, except that it may contain three or more consecutive quote characters only at the very end. Characters must not necessarily be printable; newlines or other control characters are also permitted . Unicode escapes work as everywhere else, but none of the escape sequences in (§1.3.6) is interpreted.
複数行文字列リテラルは 3 つの引用符 """ ...""" で囲まれた文字の並びです。 文字の並びは、その最後にだけ 3 つ以上の連続した引用符を含むことができる以外、 任意です。 文字は必ずしも印字可能である必要はありません。 改行あるいは他の制御文字も同様に許されます。 ユニコードエスケープは他の場所と同様に機能しますが、 しかし(§1.3.6) 中のエスケープシーケンスはどれも解釈されません。
Example 1.3.6
次は複数行文字列リテラルの例です。
"""the present string spans three lines."""
これは次の文字列になります。
the present string spans three lines.
The Scala library contains a utility method stripMargin which can be used to strip leading whitespace from multi-line strings.
Scala ライブラリには実用的なメソッド stripMargin があり、複数行文字列から先頭の 空白文字を取り去るのに使えます。 式
"""the present string |spans three |lines.""".stripMargin
は、次のように評価されます。
the present string spans three lines.
Method stripMargin is defined in class scala.collection.immutable.StringLike. Because there is a predefined implicit conversion (§6.26) from String to StringLike, the method is applicable to all strings.
メソッド stripMargin はクラス scala.collection.immutable.StringLike の中で定義されています。 String から StringLike への事前定義された暗黙変換 (§6.26)があるので、 このメソッドはすべての文字列に適用可能です。
The following escape sequences are recognized in character and string literals.
次のエスケープシーケンスは、文字あるいは文字列リテラル中で認識されます。
\b \u0008: バックスペース BS \t \u0009: 水平タブ HT \n \u000a: ラインフィード LF \f \u000c: フォームフィード FF \r \u000d: キャリッジリターン CR \" \u0022: ダブルクォート " \' \u0027: シングルクォート ' \\ \u005c: バックスラッシュ \
A character with Unicode between 0 and 255 may also be represented by an octal escape, i.e. a backslash '\' followed by a sequence of up to three octal characters. It is a compile time error if a backslash character in a character or string literal does not start a valid escape sequence.
ユニコードで 0 から 255 の文字は、8進法のエスケープ、すなわちバックスラッシュ '\' と、それに続く最大 3 つの 8進文字の並びで表せます。
文字あるいは文字列リテラル中のバックスラッシュ文字が、 有効なエスケープシーケンスを開始しないなら、コンパイルエラーが発生します。
構文:
symbolLiteral ::= ''' plainid
A symbol literal 'x is a shorthand for the expression scala.Symbol("x"). Symbol is a case class (§5.3.2), which is defined as follows.
シンボルリテラル 'x は、式 scala.Symbol("x") の略記表現です。 Symbol はケースクラス(§5.3.2)であり、 次のように定義されています。
package scala final case class Symbol private (name: String) { override def toString: String = "'" + name }
The apply method of Symbol's companion object caches weak references to Symbols, thus ensuring that identical symbol literals are equivalent with respect to reference equality.
Symbol のコンパニオンオブジェクトの apply メソッドは、 Symbols への弱い参照をキャッシュしており、 同じ識別子のシンボルリテラルが参照等価性の観点で等しいことを保証しています。
Tokens may be separated by whitespace characters and/or comments. Comments come in two forms:
A single-line comment is a sequence of characters which starts with // and extends to the end of the line.
A multi-line comment is a sequence of characters between /* and */. Multi-line comments may be nested, but are required to be properly nested. Therefore, a comment like /* /* */ will be rejected as having an unterminated comment.
トークンは空白文字あるいはコメントで分割できます。 コメントには 2 つの形があります:
一行コメントは // で始まる文字の並びであり、行末に及びます。
複数行コメントは /* と */ の間の文字の並びです。 複数行コメントはネストできます。しかし適切にネストされるよう要求されます。 ですから、/* /* */ のようなコメントは終わらないコメントとして却下されます。
In order to allow literal inclusion of XML fragments, lexical analysis switches from Scala mode to XML mode when encountering an opening angle bracket '<' in the following circumstance: The '<' must be preceded either by whitespace, an opening parenthesis or an opening brace and immediately followed by a character starting an XML name.
XML 小部分のリテラル記述を可能とするために、字句解析は、次の環境中で 始め山括弧 '<' に出会うと Scala モードから XML モードへと変わります: '<' の前には空白文字、左丸括弧あるいは左波括弧がなけれならず、 そしてすぐ後に XML 名を始める文字が続かなくてはなりません。
構文:
( whitespace | '(' | '{' ) '<' (XNameStart | '!' | '?') XNameStart ::= '_' | BaseChar | Ideographic (W3C XMLと同様、但し ':' なし
The scanner switches from XML mode to Scala mode if either
Note that no Scala tokens are constructed in XML mode, and that comments are interpreted as text.
次のいずれかの場合、スキャナは XML モードから Scala モードへと変わります。
Scala トークンは XML モードでは構築されず、 コメントはテキストとして解釈されることに注意してください。
Example 1.5.1
The following value definition uses an XML literal with two embedded Scala expressions
次の値定義は、2つの埋め込まれた Scala 式をもつ XML リテラルを使っています。
val b = <book> <title>The Scala Language Specification</title> <version>{scalaBook.version}</version> <authors>{scalaBook.authors.mkList("", ", ", "")}</authors> </book>