YAML 1.2 メモ (8) フロー・シーケンス

YAML のフロー・シーケンスは JSON の配列オブジェクトの上位互換になっています。角括弧で両端を囲み、フロー・ノードを入れ子にできます。フロー・シーケンスの中にブロック・ノードを書くとエラーになります。

エントリ間にはカンマを1個置いて区切ります。空のエントリは許されていないので、区切りのカンマの数も必ず1個だけで2個以上のカンマをエントリ間に書くとエラーになります。JSON とは異なり、最後のエントリと右角括弧の間にカンマを書くこともできます。もちろん、末尾のカンマは省いてもかまいません。

フロー・シーケンスのエントリにできるものは、フロー・ノードと、もう一つ、フロー・ペアがあります。後者はキーと値の組がたった一つしかないマッピングで、連想配列のようなものを記述するときに便利だと書いてあるものの、いまひとつありがたみがわかないものです。

以上のような、末尾に省略可能な規則がある右再帰の生成規則の書き方がおもしろくて、該当するフロー・シーケンスの生成規則は仕様に次のように定義してあります。この手の生成規則を LL(k) 文法にすると、空規則を多用しなければなくなり、くどくなる一方なのが常で、やっぱり YAML 1.2 もくどかった。

http://yaml.org/spec/1.2/spec.html#c-flow-sequence%28n,c%29

[137] c-flow-sequence(n,c) ::= 
    "[" s-separate(n,c)? ns-s-flow-seq-entries(n,in-flow(c))? "]"
[138] ns-s-flow-seq-entries(n,c) ::=
    ns-flow-seq-entry(n,c) s-separate(n,c)?
    ( "," s-separate(n,c)? ns-s-flow-seq-entries(n,c)? )?
[139] ns-flow-seq-entry(n,c) ::= ns-flow-pair(n,c) | ns-flow-node(n,c)

コメントはセパレータの一部なので、エントリ間に書き込むことができることがわかります。

また、セパレータの改行はインデントを含むので、フロー・シーケンスでもインデント・レベルは守らなければならない縛りがあります。ただし、フロー・シーケンス自体はインデントを深くすることはなく、入れ子構造によってインデントを深くする必要はありません。上に転載した生成規則のパラメータ n がインデント・レベルであり、フロー・ノードの規則の中では n はずっと n のままで変わらず受け継いでいきます。あくまで、フロー・シーケンスが、ブロック・シーケンス・エントリである場合、ブロック・マッピング・エントリである場合には、それぞれのブロック・エントリのインデント・レベルにしたがわないといけないということです。

--- []   # 空のフロー・シーケンス。
--- [  ] # 空のとき、括弧間にセパレータはあってもかまわない。 
--- [
    # セパレータにはコメントも含まれているし白い行も含まれているので
    
    
    
]
# このような空のシーケンスも許されます。
--- [a]  # エントリが1つ。
--- [a,] # これも可。
--- [a,b] # エントリが2つ。
--- [a,b,] # これも可
# --- [,] # これはエラー
# --- [,a] # これもエラー
# --- [a,,] # これもエラー
# --- [a,,b] # これもエラー
# --- [a,b,,] # これもエラー
--- [a,? k: v,b] # [ "a", {? "k" : "v" }, "b" ] と同じ
--- [a,k: v,b]   # 上と同じ
--- [a,? k0: v0, ? k1: v1,b] # [ "a", {? "k0" : "v0"}, {? "k1" : "v1"}, "b" ]  と同じ
--- [a,k0: v0, k1: v1,b]     # 上と同じ
--- [a,? k0, ? k1, b] # [ "a", {? "k0" : !!null}, {? "k1" : !!null}, "b" ]  と同じ
--- [a,: v0, : v1, b] # [ "a", {? !!null : "v0"}, {? !!null : "v1"}, "b" ]  と同じ
---
  インデント・レベルが 2 のブロック・マッピング :
   # そのエントリのインデント・レベルは 3
   [ # フロー・ノードの中では、ブロック・エントリのインデント・レベルを守っていれば
     # 好きなようにインデントできます。しなくてもかまいません。
   a,
   b,
   c,
   ]
  同じくブロック・マッピング : [
     a,
     [
       b0,
       [b10],
     ],
     c,
   ]
  フロー・シーケンスのエントリは複数行のスカラーも可です : [
     この行に続いて
     さらに続いて
     この行で終わるプレイン,
     
     プレインはコンマで終わります,

     "プレインでコンマをエスケープする方法はないので,
      コンマをスカラーに含めたいときはダブル・クォーテッドか
      シングル・クォーテッドにします。"
   ]
  フロー・ペアの暗黙キーは一行完結でなければなりません : [
     k0 :
       v0,
     # k1-0
     # and k1-1 : # エラー
     #  v1 
   ]
  フロー・ペアの明示キーは複数行に伸びてもかまいません : [
     ? k0-0
       k0-1
       k0-2
     : v0-0
       v0-1
       v0-2,
   ]