Szukaj…


Wprowadzenie

Attoparsec to parsująca biblioteka kombinatora, która „ma na celu szczególnie efektywne radzenie sobie z protokołami sieciowymi i skomplikowanymi formatami plików tekstowych / binarnych”.

Attoparsec oferuje nie tylko szybkość i wydajność, ale także cofanie się i wprowadzanie przyrostowe.

Jego interfejs API ściśle odzwierciedla bibliotekę innej biblioteki kombinacji parserów, Parsec.

Istnieją podmoduły kompatybilności z ByteString , Text i Char8 . Zalecane jest użycie rozszerzenia języka OverloadedStrings .

Parametry

Rodzaj Szczegół
Parser ia Podstawowy typ reprezentujący analizator składni. i jest typem ciągu, np. ByteString .
IResult ir Wynik analizy składniowej z Fail i [String] String , Partial (i -> IResult ir) i Done ir jako konstruktorami.

Kombinatory

Parsowanie danych wejściowych można najlepiej osiągnąć dzięki większym funkcjom parsera, które składają się z mniejszych, pojedynczych funkcji.

Załóżmy, że chcemy przeanalizować następujący tekst reprezentujący godziny pracy:

Poniedziałek: 0800 1600.

Możemy podzielić je na dwa „tokeny”: nazwę dnia - „poniedziałek” - i przedział czasu od „0800” do „1600”.

Aby przeanalizować nazwę dnia, możemy napisać:

data Day = Day String

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

Aby przeanalizować część czasu, możemy napisać:

data TimePortion = TimePortion String String

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

Teraz mamy dwa parsery dla poszczególnych części tekstu, możemy połączyć je w „większy” parser, aby odczytać godziny pracy całego dnia:

data WorkPeriod = WorkPeriod Day TimePortion

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

a następnie uruchom parser:

parseOnly work "Monday: 0800 1600"

Mapa bitowa - analizowanie danych binarnych

Attoparsec sprawia, że parsowanie danych binarnych jest banalne. Zakładając następujące definicje:

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)

Możemy łatwo parsować nagłówek z pliku mapy bitowej. Tutaj mamy 4 funkcje analizatora składni, które reprezentują sekcję nagłówka z pliku bitmapy:

Po pierwsze, sekcję DIB można odczytać, biorąc pierwsze 2 bajty

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

Podobnie łatwo można odczytać rozmiar mapy bitowej, zarezerwowane sekcje i przesunięcie pikseli:

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

który można następnie połączyć w większą funkcję parsera dla całego nagłówka:

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow