All pastes #356520 Raw Edit

Bencoding parser

public text v1 · immutable
·published 2007-02-15 03:16 UTC
rendered paste body
import Text.ParserCombinators.Parsec
import Control.Monad

data Bencoding =
    BString String | BInteger Integer | BList [Bencoding]
  | BDict [(String,Bencoding)] deriving Show

bencoding = choice
    [liftM BString byteString, liftM BInteger integer,
     liftM BList list, liftM BDict dict]
byteString = do
    n <- numeral
    guard (n >= 0)
    char ':'
    count n anyToken
integer = between (char 'i') (char 'e') numeral
list = between (char 'l') (char 'e') (many bencoding)
dict = between (char 'd') (char 'e') $ many $ liftM2 (,) byteString bencoding
numeral :: Num a => Parser a
numeral = do
    sign <- option "" (string "-")
    digits <- many1 digit
    guard (digits == "0" || head digits /= '0')
    return $ fromInteger $ read $ sign ++ digits