Attoparsecのメモ
上のサイトを見ながら、Bencodeのパースをするコードを書いていたら、そもそもParsecやAttoparsecというパースライブラリについて全然わからなかったので、メモがてら記録をしておきます。
ParsecよりもAttoparsecの方が早いと聞いたのと、上のサイトはAttoparsecを使ってるのもあって、こっちを触ってみます。
http://hackage.haskell.org/package/attoparsec-0.13.1.0/docs/Data-Attoparsec-ByteString-Char8.html
パース実行するときに使う関数がparseです。
parse :: Parser a -> ByteString -> Result a
パーサーとパース文字列を入れると結果が返ってくる。わかりやすいです。
日付のパーサーだったらこんな感じで書けそうですね。
{-# LANGUAGE OverloadedStrings #-} import Data.Attoparsec.ByteString import qualified Data.Attoparsec.ByteString.Char8 as B import Data.ByteString parseDate :: Parser [Integer] parseDate = do y <- B.decimal B.char '/' m <- B.decimal B.char '/' d <- B.decimal return [y, m, d]
ghciを起動して読み込んでみます。
*Data.Attoparsec.ByteString B> parse parseDate "2016/10/25" Partial _
あれ?
Partial (i -> IResult i r)
Supply this continuation with more input so that the parser can resume. To indicate that no more input is available, pass an empty string to the continuation.
どうやらパーサーが途中で止まっているかららしい。
”2016/10/25”という文字列だと、最後が数字なので、「次の数字はまだかー?」ってパーサーが待っているってことなんでしょうか。
*Data.Attoparsec.ByteString B> parse parseDate "2016/10/25x" Done "x" [2016,10,25]
入力文字列の最後に数字以外の文字を入れたらパーサーが止まったらしく、終了しました。
1回だけパースを実行したいときには、parseOnlyという関数があるみたいです。
*Data.Attoparsec.ByteString B> parseOnly parseDate "2016/10/25" Right [2016,10,25]
Bencodeのパースをするコードはもうちょっと複雑そうですね。
それはまた今度で。