git.iko.soy/typeable/attoparsec
on master help sign in
Change the API around a little.
34d6acaBryan O'Sullivan
src/Text/ParserCombinators/ByteStringParser.hs+42−12
@@ -38,6 +38,7 @@ module Text.ParserCombinators.ByteStringParser
38 , skipMany1
38 , skipMany1
39 , count
39 , count
40 , lookAhead
40 , lookAhead
41+ , peek
41 , sepBy
42 , sepBy
42 , sepBy1
43 , sepBy1
43
44
@@ -48,16 +49,22 @@ module Text.ParserCombinators.ByteStringParser
48 , anyChar
49 , anyChar
49 , space
50 , space
50 , char
51 , char
52+ , notChar
51 , string
53 , string
52 , stringCI
54 , stringCI
53 , byteString
55 , byteString
54 , byteStringCI
56 , byteStringCI
55
57
58+ -- * Parser converters.
59+ , maybeP
60+ , eitherP
61+
56 -- * Miscellaneous functions.
62 -- * Miscellaneous functions.
57 , getInput
63 , getInput
58 , getConsumed
64 , getConsumed
59 , takeWhile
65 , takeWhile
60 , takeWhile1
66 , takeWhile1
67+ , takeTill
61 , takeAll
68 , takeAll
62 , skipWhile
69 , skipWhile
63 , skipSpace
70 , skipSpace
@@ -67,7 +74,7 @@ module Text.ParserCombinators.ByteStringParser
67 , notInClass
74 , notInClass
68 ) where
75 ) where
69
76
70−import Control.Applicative (Applicative(..))
77+import Control.Applicative (Applicative(..), (<$>), (<*))
71import Control.Monad (MonadPlus(..), ap, liftM2)
78import Control.Monad (MonadPlus(..), ap, liftM2)
72import qualified Data.ByteString.Lazy.Char8 as C
79import qualified Data.ByteString.Lazy.Char8 as C
73import Data.Char (isDigit, isLetter, isSpace, toLower)
80import Data.Char (isDigit, isLetter, isSpace, toLower)
@@ -75,7 +82,7 @@ import Data.Int (Int64)
75import qualified Data.Set as S
82import qualified Data.Set as S
76import Prelude hiding (takeWhile)
83import Prelude hiding (takeWhile)
77
84
78−type ParseError = (C.ByteString, String)
85+type ParseError = String
79
86
80-- * Parser Monad
87-- * Parser Monad
81
88
@@ -176,6 +183,11 @@ char :: Char -> Parser Char
176char c = satisfy (== c) <?> [c]
183char c = satisfy (== c) <?> [c]
177{-# INLINE char #-}
184{-# INLINE char #-}
178
185
186+-- | Satisfy a specific character.
187+notChar :: Char -> Parser Char
188+notChar c = satisfy (/= c) <?> "not " ++ [c]
189+{-# INLINE notChar #-}
190+
179charClass :: String -> S.Set Char
191charClass :: String -> S.Set Char
180charClass s = S.fromList (go s)
192charClass s = S.fromList (go s)
181 where go (a:'-':b:xs) = [a..b] ++ go xs
193 where go (a:'-':b:xs) = [a..b] ++ go xs
@@ -252,6 +264,10 @@ takeWhile f = Parser $ \(S bs n) ->
252 in Right (h, S bs' (n + C.length h))
264 in Right (h, S bs' (n + C.length h))
253{-# INLINE takeWhile #-}
265{-# INLINE takeWhile #-}
254
266
267+takeTill :: (Char -> Bool) -> Parser C.ByteString
268+takeTill p = takeWhile (not . p) <* satisfy p
269+{-# INLINE takeTill #-}
270+
255takeWhile1 :: (Char -> Bool) -> Parser C.ByteString
271takeWhile1 :: (Char -> Bool) -> Parser C.ByteString
256takeWhile1 f = Parser $ \(S bs n) ->
272takeWhile1 f = Parser $ \(S bs n) ->
257 let (h, bs') = C.span f bs
273 let (h, bs') = C.span f bs
@@ -313,29 +329,43 @@ match p = do bs <- getInput
313 end <- getConsumed
329 end <- getConsumed
314 return (C.take (end - start) bs)
330 return (C.take (end - start) bs)
315
331
332+maybeP :: Parser a -> Parser (Maybe a)
333+maybeP p = (Just <$> p) <|> pure Nothing
334+{-# INLINE maybeP #-}
335+
336+eitherP :: Parser a -> Parser b -> Parser (Either a b)
337+eitherP a b = (Left <$> a) <|> (Right <$> b)
338+{-# INLINE eitherP #-}
339+
340+peek :: Parser a -> Parser (Maybe a)
341+peek p = Parser $ \s ->
342+ case unParser p s of
343+ Right (m, _) -> Right (Just m, s)
344+ _ -> Right (Nothing, s)
345+
316−lookAhead :: Parser a -> Parser (Maybe a)
346+lookAhead :: Parser a -> Parser a
317lookAhead p = Parser $ \s ->
347lookAhead p = Parser $ \s ->
318− case unParser p s of
348+ case unParser p s of
319− Right (m, _) -> Right (Just m, s)
349+ Right (m, _) -> Right (m, s)
320− _ -> Right (Nothing, s)
350+ Left (e, bs) -> Left (e, bs)
321
351
322parseAt :: Parser a -> C.ByteString -> Int64
352parseAt :: Parser a -> C.ByteString -> Int64
323− -> Either ParseError (a, C.ByteString)
353+ -> (C.ByteString, Either ParseError a)
324parseAt p bs n =
354parseAt p bs n =
325 case unParser p (S bs n) of
355 case unParser p (S bs n) of
326− Left (bs', msg) -> Left (bs', showError msg)
356+ Left (bs', msg) -> (bs', Left $ showError msg)
327− Right (a, S bs' _) -> Right (a, bs')
357+ Right (a, S bs' _) -> (bs', Right a)
328 where
358 where
329 showError [msg] = "Parser error, expected:\n" ++ msg ++ "\n"
359 showError [msg] = "Parser error, expected:\n" ++ msg ++ "\n"
330 showError msgs = "Parser error, expected one of:\n" ++ unlines msgs
360 showError msgs = "Parser error, expected one of:\n" ++ unlines msgs
331
361
332-- | Run a parser.
362-- | Run a parser.
333parse :: Parser a -> C.ByteString
363parse :: Parser a -> C.ByteString
334− -> Either ParseError (a, C.ByteString)
364+ -> (C.ByteString, Either ParseError a)
335parse p bs = parseAt p bs 0
365parse p bs = parseAt p bs 0
336
366
337parseTest :: (Show a) => Parser a -> C.ByteString -> IO ()
367parseTest :: (Show a) => Parser a -> C.ByteString -> IO ()
338parseTest p s =
368parseTest p s =
339 case parse p s of
369 case parse p s of
340− Left (st, msg) -> putStrLn $ msg ++ "\nGot:\n" ++ show st
370+ (st, Left msg) -> putStrLn $ msg ++ "\nGot:\n" ++ show st
341− Right (r,_) -> print r
371+ (_, Right r) -> print r