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 가 생성자로 사용됩니다. |
결합 자
파싱 입력은 더 작은 단일 용도로 구성된 더 큰 파서 기능을 통해 가장 잘 수행됩니다.
우리가 근무 시간을 나타내는 다음 텍스트를 파싱하기를 원한다고 가정 해 봅시다 :
월요일 : 0800 1600.
우리는 이것을 "토큰"으로 나눌 수 있습니다 : 요일 이름 - "월요일"- 시간 부분 "0800"- "1600".
요일 이름을 파싱하려면 다음과 같이 작성할 수 있습니다.
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
이제는 텍스트의 개별 부분에 대해 두 개의 파서가 있습니다.이를 "더 큰"파서로 결합하여 하루 종일 근무 시간을 읽을 수 있습니다.
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 가지 파서 함수가 있습니다.
첫째, 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