19.1 演算子式の展開
演算子宣言は,構文構造の決定に関わる特殊宣言であり,以下の構文で定義される.
infix n vidList
infixr n vidList
これら宣言は,vidに対して演算子属性を与える. infix宣言は,識別子が左結合する演算子として使用するこ とを宣言し,infixr宣言は,識別子が右結合する演算子として使用す ることを宣言する. オプションとして結合力を0から9までの数字nで指定する ことができる. 数字が大きいほうが結合力が強い. 結合力を省略すると,を指定したとみなされる. 宣言,
nonfix vidList
は,vidListの演算子属性を削除する.
これら演算子宣言は,vidの宣言が書ける所に書くことがで き,vidの宣言が生成する識別子の定義と同様の静的スコープに従う が,構文解析処理への指示であり,識別子の定義とは独立になされる.
演算子属性が与えられた識別子idが式またはパターンに現れ ると,演算子の優先度に従い以下の構文変換が行われる.
変換前 | 変換後 |
---|---|
exp vid exp | op vid (exp,exp) |
pat vid pat | op vid (pat,pat) |
ここで,expとexpは,演算子属性の結合力の強さに応じ て決定される. 式またはパターンに現れた構文
op vid
は,vidと同一であるが,vidの演算子属性は無視される.
従って,fooが演算子属性をもつ識別子の場合,以下の2つの式は 等価である.
1 foo 2
op foo (1,2)
演算子宣言はインタフェイスファイルでも行うことができる. SML#言語では,すべてのコンパイル単位および対話型モードで, 以下の演算子宣言を含むインタフェイスファイルが暗黙に_requireされ ている.
infix 7 * / div mod
infix 6 + -^
infixr 5 :: @
infix 4 = <> > >= < <=
infix 3 := o
infix 0 before
以上の階層的な構文の定義とインフィックス宣言によって,構文間の結合の強さが定義される. 例えば,レコードアップデート構文 (exp # {lab=exp}) の結合力は,最も結合力の強い(infix 9と宣言された)演算子よりも強く, if exp thenexp else exp 等の他の構文の結合力は,最も結合力の弱い(infix 0と宣言された)演算子の結合力より も弱い.