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