5.5 ここまでの構文

第 4 章と第 5 章では、プリミティブなデータと関数の、式と型を表現する Scalaの構文を扱いました。下記に、それらの文脈自由文法を拡張 Backus-Naur 記法で与えます。'|' は選択を、[...] はオプション (0あるいは1回の出現)、{...} は繰り返し (0回以上の出現)を表します。

文字 :

Scala プログラムは (Unicode) 文字の列です。次の文字セットを区別します。

    • 空白文字。たとえば ' '、タブ、改行文字

    • 文字。'a'-'z'、'A'-'Z'

    • 数字。'0'-'9'

    • 区切り文字。

      • . , ; ( ) { } [ ] \ " '

    • 演算子文字。たとえば '#' '+' ':'。正確には、上記のどれにも含まれない印刷可能な文字。

語彙素 :

ident = letter {letter | digit} | operator { operator } | ident '_' ident literal = "as in Java"

リテラルは Java と同じです。数、文字、文字列、ブール値を定義します。リテラルの例は、0、1.0e10、'x'、"he said "hi!""、true です。

識別子には2つの形式があります。文字で始まり、文字またはシンボルの列 (空を許す) が続くものか、演算子文字で始まり演算子文字の列 (空を許す) が続くものです。どちらの形式もアンダースコア '_' を含んで構いません。さらに、アンダースコア文字列の後には、どちらの形式の識別子が続いても構いません。したがって、次はすべて正しい識別子です。

x Room10a + -- foldl_: +_vector

この規則から、後に続く演算子識別子は空白文字で区切られねばならないということが判ります。たとえば入力 x+-y は3つのトークン列 x, +-, y へと字句解析されます。もし x と、 y の符号を逆にした値との和を表現したいなら、x+ -y のように、最低一つの空白を加える必要があります。

文字 $ はコンパイラ生成識別子用に予約されています。ソースプログラムで使うべきではありません。

以下は予約語です。識別子としては使用できません。

abstract case catch class def do else extends false final finally for if implicit import match new null object override package private protected requires return sealed super this throw trait try true type val var while with yield _ : = => <- <: <% >: # @

型 (Types):

Type = SimpleType | FunctionType FunctionType = SimpleType '=>' Type | '(' [Types] ')' '=>' Type SimpleType = Byte | Short | Char | Int | Long | Float | Double | Boolean | Unit | String Types = Type {',' Type}

型は

    • 数値型 Byte、Short、Char、Int、Long、Float、Double (Java と同じ)

    • Boolean 型とその値の true と false

    • Unit 型とその唯一の値 ()

    • String 型

    • 関数型、たとえば (Int, Int) => Int や String => Int => String

式 (Expressions):

Expr = InfixExpr | FunctionExpr | if '(' Expr ')' Expr else Expr InfixExpr = PrefixExpr | InfixExpr Operator InfixExpr Operator = ident PrefixExpr = ['+' | '-' | '!' | '~' ] SimpleExpr SimpleExpr = ident | literal | SimpleExpr '.' ident | Block FunctionExpr = (Bindings | Id) '=>' Expr Bindings = '(' Binding {',' Binding} ')' Binding = ident [':' Type] Block = '{' {Def ';'} Expr '}'

式は

    • 識別子、たとえば x、isGoodEnugh、*、+-

    • リテラル、たとえば 0、1.0、"abc"

    • フィールドとメソッド選択、たとえば System.out.println

    • 関数適用、たとえば sqrt(x)

    • 演算子適用、たとえば -x、y + x

    • 条件式、たとえば if (x < 0) -x else x

    • ブロック、たとえば { val x = abs(y); x * 2}

    • 無名関数、たとえば x => x + 1、(x: Int, y: Int) = x + y

定義 (Definitions):

Def = FunDef | ValDef FunDef = 'def' ident {'(' [Parameters] ')'} [':' Type] '=' Expr ValDef = 'val' ident [':' Type] '=' Expr Parameters = Parameter {',' Parameter} Parameter = ident ':' ['=>'] Type

定義は

    • 関数定義、たとえば def square(x: Int): Int = x * x

    • 値定義、たとえば val y = square(2)

(訳注 : 本節に書いてあるのは、これまでに出てきた構文です。たとえば var定義のように、書かれてないものもあります)