Haskell Language
Attoparsec
サーチ…
前書き
Attoparsecは、 "特にネットワークプロトコルや複雑なテキスト/バイナリファイルフォーマットを効率的に扱うことを目的とした"コンパインネーターライブラリの解析です。
Attoparsecはスピードと効率だけでなく、バックトラッキングとインクリメンタル入力を提供します。
そのAPIは、別のパーサーコンビネータライブラリParsecのAPIと密接に似ています。
ByteString
、 Text
、 Char8
との互換性のためのサブモジュールがあります。 OverloadedStrings
言語拡張を使用することをお勧めします。
パラメーター
タイプ | 詳細 |
---|---|
Parser ia | パーサを表すためのコア型。 i は文字列型です(例: ByteString 。 |
IResult ir | 構文解析の結果、 Fail i [String] String 、 Partial (i -> IResult ir) およびDone ir がコンストラクタとしてPartial (i -> IResult ir) れます。 |
コンビネーション
パース入力は、より小さい単一目的のものからなるより大きなパーサ関数によって最もよく達成されます。
勤務時間を表す次のテキストを解析したいとしましょう:
月曜日:0800 1600
曜日名「月曜日」と時刻部分「0800」〜「1600」の2つの「トークン」に分割することができます。
曜日名を解析するには、次のように記述します。
data Day = Day String day :: Parser Day day = do name <- takeWhile1 (/= ':') skipMany1 (char ':') skipSpace return $ Day name
時間部分を解析するために、次のように書くことができます。
data TimePortion = TimePortion String String time = do start <- takeWhile1 isDigit skipSpace end <- takeWhile1 isDigit return $ TimePortion start end
テキストの個々の部分に対して2つのパーサーがあります。これらを「より大きい」パーサーで組み合わせて、1日の勤務時間を読み取ることができます。
data WorkPeriod = WorkPeriod Day TimePortion work = do d <- day t <- time return $ WorkPeriod d t
パーサーを実行します。
parseOnly work "Monday: 0800 1600"
ビットマップ - バイナリデータの解析
Attoparsecは、バイナリデータの解析を簡単にします。これらの定義を仮定します。
import Data.Attoparsec.ByteString (Parser, eitherResult, parse, take) import Data.Binary.Get (getWord32le, runGet) import Data.ByteString (ByteString, readFile) import Data.ByteString.Char8 (unpack) import Data.ByteString.Lazy (fromStrict) import Prelude hiding (readFile, take) -- The DIB section from a bitmap header data DIB = BM | BA | CI | CP | IC | PT deriving (Show, Read) type Reserved = ByteString -- The entire bitmap header data Header = Header DIB Int Reserved Reserved Int deriving (Show)
ビットマップファイルからヘッダーを簡単に解析できます。ここでは、ビットマップファイルのヘッダーセクションを表す4つのパーサ関数があります。
第1に、DIBセクションは、最初の2バイト
dibP :: Parser DIB
dibP = read . unpack <$> take 2
同様に、ビットマップのサイズ、予約されたセクション、およびピクセルオフセットも容易に読み取ることができます。
sizeP :: Parser Int sizeP = fromIntegral . runGet getWord32le . fromStrict <$> take 4 reservedP :: Parser Reserved reservedP = take 2 addressP :: Parser Int addressP = fromIntegral . runGet getWord32le . fromStrict <$> take 4
これをヘッダ全体のより大きなパーサー関数に組み込むことができます:
bitmapHeader :: Parser Header bitmapHeader = do dib <- dibP sz <- sizeP reservedP reservedP offset <- addressP return $ Header dib sz "" "" offset