プログラミング言語SML#解説 4.0.0版
19

19.1 演算子式の展開

演算子宣言は,構文構造の決定に関わる特殊宣言であり,以下の構文で定義される.

infix  (n)? vidList
infixr (n)? vidList

これら宣言は,vidに対して演算子属性を与える. infix宣言は,識別子が左結合する演算子として使用するこ とを宣言し,infixr宣言は,識別子が右結合する演算子として使用す ることを宣言する. オプションとして結合力を0から9までの数字nで指定する ことができる. 数字が大きいほうが結合力が強い. 結合力nを省略すると,0を指定したとみなされる. 宣言,

nonfix vidList

は,vidListの演算子属性を削除する.

これら演算子宣言は,vidの宣言が書ける所に書くことがで き,vidの宣言が生成する識別子の定義と同様の静的スコープに従う が,構文解析処理への指示であり,識別子の定義とは独立になされる.

演算子属性が与えられた識別子idが式またはパターンに現れ ると,演算子の優先度に従い以下の構文変換が行われる.

変換前 変換後
 exp1 vid exp2 op vid (exp1,exp2)
pat1 vid pat2 op vid (pat1,pat2)

ここで,exp1exp2は,演算子属性の結合力の強さに応じ て決定される. 式またはパターンに現れた構文

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

以上の階層的な構文の定義とインフィックス宣言によって,構文間の結合の強さが定義される. 例えば,レコードアップデート構文 (exp1 # {lab=exp2}) の結合力は,最も結合力の強い(infix 9と宣言された)演算子よりも強く, if exp thenexp else exp 等の他の構文の結合力は,最も結合力の弱い(infix 0と宣言された)演算子の結合力より も弱い.