View on Github

akrantiain仕様書 — .snojファイルとモジュールの仕様

トップに戻る

1. .snojファイルの構文規則

1-0. 構造

.snojファイルはモジュールの集まりである。
モジュールには「明示モジュール」と「暗黙モジュール」の2種類があり、明示モジュールは各.snojファイルに0個以上、暗黙モジュールは各.snojファイルに1個のみ存在する。
.snojファイルが渡された時、その中に存在する暗黙モジュールに指定された変換を、akrantiainは実行する。

明示モジュールには「名前」と「中身」があり、以下のような構文を取る。
% モジュール名 { 中身 }
一方、暗黙モジュールには名前がなく、中身のみを持つ。暗黙モジュールの中身は.snojファイル内に直に記述される。

明示・暗黙に関わらず、一つのモジュール定義の途中に別のモジュール定義を挟むことはできない。
ゆえに、例えば
@FALL_THROUGH;
% a { "a" -> /A/; }
%% a;
というコードは動作せず、構文エラーとなる。なぜなら、暗黙モジュールの定義
@FALL_THROUGH;
%% a;
の途中に別のモジュール定義
% a { "a" -> /A/; }
が挟まっているからである。

1-1. モジュール名

モジュール名には、2種類の形がある。
識別子
識別子 => 識別子
(識別子は、アルファベットの後に、(アルファベット・数字・_)が0個以上続いたものである。)
前者を「単独型」、後者を「推移型」と呼ぶ。あくまで見た目上の差であり、本質的には単独型と推移型に差はない。

同一名のモジュールが複数定義されている場合、モジュールエラー#1113を吐く。

1-2. モジュールの中身

モジュールの中身には、2種類の形がある。片方は、2章で説明する「文列」であり、もう片方は「モジュールの合成」である。
なお、この2種の差は本質的なものである。

1-3. modChain素

modChain素には、以下の4種類がある。
  1. 単一の識別子
  2. 2個以上の識別子を=>で区切ったもの
  3. 1.を()で囲んだもの
  4. 2.を()で囲んだもの
1.と3.は等価であり、2.と4.は等価である。
1.及び3.は、同名の単独型モジュールを表す。
2.及び4.は、以下のような方法で1個以上の推移型モジュールを合成したものを表す。
「例えば、A => B => C => Dは、3つのモジュールA => B B => CC => Dを合成したものである。」

1-4. モジュールの合成

1つ以上のモジュールを合成して、別のモジュールの定義とすることができる。これには主に二つの用途がある。
  1. 複数のモジュールを合成したものに名前をつける
  2. 1つ以上のモジュールを合成したものを暗黙モジュールの定義とすることで、明示モジュールを実際に利用する
モジュールを合成するには、以下の構文を用いる。
%% modChain素 >> modChain素 >> modChain素;
つまり、1個以上のmodChain素を>>で区切って、先頭に%%、末尾に;を置いたものである。
1つのモジュール合成を、行をまたいで定義することはできない。
逆に、末尾のセミコロンは、行の最後および行コメントの直前では省略できる。

modChain素自体がモジュールの連鎖を表すことができ、それを連鎖させたものでモジュールの合成を表すが、この2種類の連鎖に意味的な差はなく、例えば、
% baz { %% foo >> (A => B => C) >> bar; }
という定義があった時、bazという名のモジュールは、入力された文字列をfooA => BB => Cbarという4つのモジュールに順に通過させることと等価な挙動をするモジュールとして定義される。
なお、定義中に登場するモジュール名を持つモジュールが存在しない場合、モジュールエラー#1111を吐く。
また、モジュールが循環参照している場合、モジュールエラー#1112を吐く。