rendered paste bodyimport 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