parserの~
メソッドは、2つの元のパーサーを連続して適用して2つの結果を返す2つのパーサーを組み合わせています。それは大丈夫だろうあなたが二つ以上のパーサを組み合わせることがない場合は
def ~[U](q: =>Parser[U]): Parser[(T,U)].
、(Parser[T]
に)単にである可能性があります。あなたがp1.~(p2).~(p3)
を意味戻り値の型T1
、T2
、T3
、その後p1 ~ p2 ~ p3
、とそれらの3、p1
、p2
、p3
を、チェーン場合は、タイプParser[((T1, T2), T3)]
です。あなたの例のように5つを組み合わせると、それはParser[((((T1, T2), T3), T4), T5)]
になります。結果にパターンマッチングを行うと、すべてのパランシェも同じようになります。
case ((((_, id), _), formals), _) => ...
これは非常に不快です。
次に、巧妙な構文トリックが来ます。 caseクラスに2つのパラメータがある場合、パターン内の接頭辞の位置ではなく、中置で現れることがあります。つまり、 case class X(a: A, b: B)
がある場合、case X(a, b)
とパターンマッチすることができますが、case a X b
もパターンマッチすることができます。 (それはパターンx::xs
で行われ、空ではないリストに一致します。::
はケースクラスです)。 ケースa ~ b ~ c
を書くとき、それはcase ~(~(a,b), c)
を意味しますが、より快適であり、case ((a,b), c)
よりも楽しいです。これは正しいことが難しいです。
したがって、Parserの~
メソッドは、Parser[(T,U)]
の代わりにParser[~[T,U]]
を返します。したがって、複数の〜の結果に簡単にパターンを一致させることができます。それ以外にも、~[T,U]
と(T,U)
は、あなたが得ることができる同形的なものとほぼ同じものです。
結果のコードが自然に読み込まれるため、パーサーと結果の型の結合方法に同じ名前が選択されます。結果処理の各部分が文法規則の項目にどのように関連しているかがすぐにわかります。その優先順位は(それがしっかりと結合する)パーサ上の他の事業者とうまく演じているので
parser1 ~ parser2 ~ parser3 ^^ {case part1 ~ part2 ~ part3 => ...}
ティルダが選択されています。
最後に、補助演算子~>
と<~
があります。これは、オペランドの1つの結果、通常は有効なデータを持たないルールの定数部分を破棄します。したがって、どちらかというとむしろ書きます。
"class" ~> ID <~ ")" ~ formals <~ ")"
結果にはIDと正式な値しか得られません。
ありがとうございます。私はスカラーの "暗黙の変換"機能に慣れていませんでした。 そのトピックに関する素敵な記事がここにあります:http://scalada.blogspot.com/2008/03/implicit-conversions-magical-and.html – Jano