Sök…


Introduktion

Attoparsec är ett parsing combinator-bibliotek som "syftar särskilt till att hantera nätverksprotokoll och komplicerade text / binära filformat" effektivt.

Attoparsec erbjuder inte bara hastighet och effektivitet, utan backtracking och inkrementell ingång.

Dess API speglar nära det för ett annat parser-kombinatorbibliotek, Parsec.

Det finns undermoduler för kompatibilitet med ByteString , Text och Char8 . Användning av språkförlängningen OverloadedStrings rekommenderas.

parametrar

Typ Detalj
Parser ia Kärntypen för att representera en parser. i är ByteString , t.ex. ByteString .
IResult ir Resultatet av en parse med Fail i [String] String , Partial (i -> IResult ir) och Done ir som konstruktörer.

kombinatorer

Parsingingång uppnås bäst genom större parserfunktioner som består av mindre, enda ändamål.

Låt oss säga att vi ville analysera följande text som representerar arbetstid:

Måndag: 0800 1600.

Vi kunde dela upp dessa i två "tokens": dagnamnet - "måndag" - och en tidsdel "0800" till "1600".

För att analysera ett dagnamn kan vi skriva följande:

data Day = Day String

day :: Parser Day
day = do
  name <- takeWhile1 (/= ':')
  skipMany1 (char ':')
  skipSpace
  return $ Day name

För att analysera tidsdelen kan vi skriva:

data TimePortion = TimePortion String String

time = do
    start <- takeWhile1 isDigit
    skipSpace
    end <- takeWhile1 isDigit
    return $ TimePortion start end

Nu har vi två parsers för våra enskilda delar av texten, vi kan kombinera dessa i en "större" parser för att läsa en hel dags arbetstid:

data WorkPeriod = WorkPeriod Day TimePortion

work = do
    d <- day
    t <- time
    return $ WorkPeriod d t
    

och kör sedan parser:

parseOnly work "Monday: 0800 1600"

Bitmapp - analysera binära data

Attoparsec gör parsing av binära data triviala. Antagande av dessa definitioner:

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)

Vi kan enkelt para rubriken från en bitmappsfil. Här har vi fyra parserfunktioner som representerar rubrikavsnittet från en bitmappsfil:

För det första kan DIB-avsnittet läsas genom att ta de två första byte

dibP :: Parser DIB
dibP = read . unpack <$> take 2

På samma sätt kan storleken på bitmappen, de reserverade avsnitten och pixelförskjutningen lätt läsas också:

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

som sedan kan kombineras till en större parser-funktion för hela huvudet:

bitmapHeader :: Parser Header
bitmapHeader = do
    dib <- dibP
    sz <- sizeP
    reservedP
    reservedP
    offset <- addressP
    return $ Header dib sz "" "" offset


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow