Buscar..


Introducción

Attoparsec es una biblioteca combinadora de análisis que está "dirigida especialmente a tratar de manera eficiente los protocolos de red y los complicados formatos de archivo de texto / binario".

Attoparsec ofrece no solo velocidad y eficiencia, sino también retroceso e ingreso incremental.

Su API es muy similar a la de otra biblioteca combinadora de analizadores, Parsec.

Hay submódulos para la compatibilidad con ByteString , Text y Char8 . Se recomienda el uso de la extensión de lenguaje OverloadedStrings .

Parámetros

Tipo Detalle
Parser ia El tipo de núcleo para representar un analizador. i es el tipo de cadena, por ejemplo, ByteString .
IResult ir El resultado de un análisis, con Fail i [String] String , Partial (i -> IResult ir) y Done ir como constructores.

Combinadores

La entrada de análisis se logra mejor a través de funciones de analizador más grandes que se componen de funciones más pequeñas y de un solo propósito.

Digamos que deseamos analizar el siguiente texto que representa las horas de trabajo:

Lunes: 0800 1600.

Podríamos dividirlos en dos "tokens": el nombre del día, "Monday", y una parte de tiempo "0800" a "1600".

Para analizar el nombre de un día, podríamos escribir lo siguiente:

data Day = Day String

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

Para analizar la parte del tiempo podríamos escribir:

data TimePortion = TimePortion String String

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

Ahora que tenemos dos analizadores para nuestras partes individuales del texto, podemos combinarlos en un analizador "más grande" para leer las horas de trabajo de un día entero:

data WorkPeriod = WorkPeriod Day TimePortion

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

y luego ejecute el analizador

parseOnly work "Monday: 0800 1600"

Mapa de bits - Análisis de datos binarios

Attoparsec hace que el análisis de datos binarios sea trivial. Asumiendo estas definiciones:

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)

Podemos analizar el encabezado de un archivo de mapa de bits fácilmente. Aquí, tenemos 4 funciones de analizador que representan la sección del encabezado de un archivo de mapa de bits:

En primer lugar, la sección DIB se puede leer tomando los primeros 2 bytes

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

Del mismo modo, el tamaño del mapa de bits, las secciones reservadas y el desplazamiento de píxeles también se pueden leer fácilmente:

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

que luego se puede combinar en una función de analizador más grande para todo el encabezado:

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow