git.iko.soy/typeable/attoparsec
on master help sign in
Update names, fix some build problems.
commit306d094ed73fda3381981f7f6768aac174db0086 authorBryan O'Sullivan <bos@serpentine.com> dateWed 24 Jan 2007, 18:16 (20 years ago) parent6b44f86
1 file changed+94−42
ByteStringParser.hs+94−42
ByteStringParser.hs+94−42
@@ -1,10 +1,10 @@
11-----------------------------------------------------------------------------
22-- |
3−-- Module : ByteStringParser
3+-- Module : Text.ParserCombinators.ByteStringParser
44-- Copyright : (c) Daan Leijen 1999-2001, Jeremy Shaw 2006, Bryan O'Sullivan 2007
55-- License : BSD-style (see the file libraries/parsec/LICENSE)
66--
7−-- Maintainer : jeremy@n-heptane.com
7+-- Maintainer : bos@serpentine.com
88-- Stability : experimental
99-- Portability : unknown
1010--
@@ -16,7 +16,7 @@ module Text.ParserCombinators.ByteStringParser where
1616import Data.Char
1717import Data.Word
1818import Control.Monad
19−import qualified Data.ByteString.Char8 as C
19+import qualified Data.ByteString.Lazy.Char8 as C
2020
2121-- * Parser
2222
@@ -26,6 +26,8 @@ type ParserError state = (state, String)
2626
2727newtype Parser state a = Parser { unParser :: (state -> Either (state,[String]) (a, state)) }
2828
29+type CharParser = Parser C.ByteString Char
30+
2931instance Functor (Parser state) where
3032 fmap f (Parser p) =
3133 Parser $ \st ->
@@ -54,12 +56,12 @@ instance MonadPlus (Parser state) where
5456 )
5557
5658-- |Always succeed
57−pSucceed :: a -> Parser state a
58−pSucceed = return
59+succeed :: a -> Parser state a
60+succeed = return
5961
6062-- |Always fail
61−pFail :: Parser state a
62−pFail = Parser (\st -> Left (st, []))
63+fail :: Parser state a
64+fail = Parser (\st -> Left (st, []))
6365
6466infix 0 <?>
6567infixr 1 <|>
@@ -83,8 +85,11 @@ getInput = Parser (\st -> Right (st,st))
8385
8486-- * Things like in @Parsec.Char@
8587
88+{-# INLINE satisfy #-}
89+
8690-- |character parser
87−satisfy :: (Char -> Bool) -> Parser C.ByteString Char
91+satisfy :: (Char -> Bool) -> CharParser
92+
8893satisfy f =
8994 Parser $ \bs ->
9095 if C.null bs
@@ -94,71 +99,116 @@ satisfy f =
9499 then Right (s,ss)
95100 else Left (bs, [])
96101
102+letter :: CharParser
103+
104+letter = satisfy isLetter
105+
106+digit :: CharParser
107+
108+digit = satisfy isDigit
109+
110+anyChar :: CharParser
111+
112+anyChar = satisfy $ const True
113+
114+space :: CharParser
115+
116+space = satisfy isSpace
117+
97118-- |satisfy a specific character
98−pChar :: Char -> Parser C.ByteString Char
99−pChar c = satisfy (== c) <?> [c]
100119
120+char :: Char -> CharParser
121+
122+char c = satisfy (== c) <?> [c]
123+
124+string :: String -> Parser C.ByteString String
125+
126+string = mapM char
127+
128+count :: Int -> Parser st a -> Parser st [a]
129+
130+count n p = sequence (replicate n p)
101131
102132-- * Things vaguely like those in @Parsec.Combinator@ (and @Parsec.Prim@)
103133
134+try :: Parser st a -> Parser st a
135+
136+try (Parser p)
137+ = Parser $ \state -> case p state of
138+ (Left (_, msgs)) -> Left (state, msgs)
139+ ok -> ok
140+
104141-- |detect 'end of file'
105−pEOF :: Parser C.ByteString ()
106−pEOF =
142+eOF :: Parser C.ByteString ()
143+eOF =
107144 Parser $ \bs -> if C.null bs then Right ((),bs) else (Left (bs, ["EOF"]))
108145
109−-- |pTakeWhile take characters while the predicate is true
110−pTakeWhile :: (Char -> Bool) -> Parser C.ByteString C.ByteString
111−pTakeWhile f =
146+-- |takeWhile take characters while the predicate is true
147+takeWhile :: (Char -> Bool) -> Parser C.ByteString C.ByteString
148+takeWhile f =
112149 Parser $ \bs -> Right (C.span f bs)
113150
114−-- |pSkipWhile skip over characters while the predicate is true
115−pSkipWhile :: (Char -> Bool) -> Parser C.ByteString ()
116−pSkipWhile p =
151+-- |skipWhile skip over characters while the predicate is true
152+skipWhile :: (Char -> Bool) -> Parser C.ByteString ()
153+skipWhile p =
117154 Parser $ \bs -> Right ((), C.dropWhile p bs)
118155
119−-- |'pMany' - take zero or more instances of the parser
120−pMany :: Parser st a -> Parser st [a]
121−pMany p
122− = scan id
123− where
124− scan f = do x <- p
125− scan (\tail -> f (x:tail))
126− <|> return (f [])
156+-- |'many' - take zero or more instances of the parser
157+many :: Parser st a -> Parser st [a]
158+many p = scan id
159+ where scan f = do x <- p
160+ scan (\xs -> f (x:xs))
161+ <|> return (f [])
127162
128−-- |'pMany1' - take one or more instances of the parser
129−pMany1 :: Parser st a -> Parser st [a]
130−pMany1 p =
163+-- |'many1' - take one or more instances of the parser
164+many1 :: Parser st a -> Parser st [a]
165+many1 p =
131166 do x <- p
132− xs <- pMany p
167+ xs <- many p
133168 return (x:xs)
134169
135−-- |'pSkipMany' - skip zero or many instances of the parser
136−pSkipMany :: Parser st a -> Parser st ()
137−pSkipMany p = scan
170+manyTill :: Parser st a -> Parser st end -> Parser st [a]
171+manyTill p end = scan
172+ where scan = do end
173+ return []
174+ <|>
175+ do x <- p
176+ xs <- scan
177+ return (x:xs)
178+
179+-- |'skipMany' - skip zero or many instances of the parser
180+skipMany :: Parser st a -> Parser st ()
181+skipMany p = scan
138182 where
139183 scan = (p >> scan) <|> return ()
140184
141−-- |'pSkipMany1' - skip one or many instances of the parser
142−pSkipMany1 :: Parser st a -> Parser st ()
143−pSkipMany1 p = p >> pSkipMany p
185+-- |'skipMany1' - skip one or many instances of the parser
186+skipMany1 :: Parser st a -> Parser st ()
187+skipMany1 p = p >> skipMany p
144188
145189-- |'notEmpty' - tests that a parser returned a non-null ByteString
146190notEmpty :: Parser C.ByteString C.ByteString -> Parser C.ByteString C.ByteString
147191notEmpty (Parser p) =
148192 Parser $ \s -> case p s of
149− o@(Right (a, s)) ->
193+ o@(Right (a, s_)) ->
150194 if C.null a
151195 then Left (a, ["notEmpty"])
152196 else o
153197 x -> x
154198
155199-- | parse some input with the given parser and return that input without copying it
156−pMatch :: Parser C.ByteString a -> Parser C.ByteString C.ByteString
157−pMatch p = do start <- getInput
158− p
159− end <- getInput
160− return (C.take (C.length start - C.length end) start)
200+match :: Parser C.ByteString a -> Parser C.ByteString C.ByteString
201+match p = do start <- getInput
202+ p
203+ end <- getInput
204+ return (C.take (C.length start - C.length end) start)
161205
206+lookAhead :: Parser C.ByteString a -> Parser C.ByteString a
207+
208+lookAhead (Parser p)
209+ = Parser $ \state -> case p state of
210+ Left (_, msgs) -> Left (state, msgs)
211+ Right (m, _) -> Right (m, state)
162212
163213-- * Running parsers
164214
@@ -172,6 +222,8 @@ parse p s =
172222 showError [msg] = "Parser error, expected:\n" ++ msg ++ "\n"
173223 showError msgs = "Parser error, expected one of:\n" ++ unlines msgs
174224
225+parseTest :: Parser st a -> st -> IO ()
226+
175227parseTest p s =
176228 case parse p s of
177229 Left (st, msg) -> putStrLn $ msg ++ "\nGot:\n" ++ show st