git.iko.soy/typeable/attoparsec
on master help sign in
Rework stringCI
commitdcc5e1f94063d359ce08aef785325944bd9136ed authorBryan O'Sullivan <bos@serpentine.com> dateFri 27 Mar 2015, 12:49 (12 years ago) parent633e189
2 files changed+31−26
Data/Attoparsec/ByteString/Char8.hs+1−11 Data/Attoparsec/ByteString/Internal.hs+30−15
Data/Attoparsec/ByteString/Char8.hs+1−11
@@ -70,7 +70,7 @@ module Data.Attoparsec.ByteString.Char8
7070
7171 -- * Efficient string handling
7272 , I.string
73− , stringCI
73+ , I.stringCI
7474 , skipSpace
7575 , skipWhile
7676 , I.take
@@ -169,16 +169,6 @@ instance (a ~ B.ByteString) => IsString (Parser a) where
169169-- currency sign in ISO-8859-1). Haskell 'Char' values above U+00FF
170170-- are truncated, so e.g. U+1D6B7 is truncated to the byte @0xB7@.
171171
172−-- ASCII-specific but fast, oh yes.
173−toLower :: Word8 -> Word8
174−toLower w | w >= 65 && w <= 90 = w + 32
175− | otherwise = w
176−
177−-- | Satisfy a literal string, ignoring case.
178−stringCI :: B.ByteString -> Parser B.ByteString
179−stringCI = I.stringTransform (B8.map toLower)
180−{-# INLINE stringCI #-}
181−
182172-- | Consume input as long as the predicate returns 'True', and return
183173-- the consumed input.
184174--
Data/Attoparsec/ByteString/Internal.hs+30−15
@@ -1,4 +1,4 @@
1−{-# LANGUAGE BangPatterns, GADTs, OverloadedStrings, RecordWildCards #-}
1+{-# LANGUAGE BangPatterns, GADTs, OverloadedStrings, RankNTypes, RecordWildCards #-}
22-- |
33-- Module : Data.Attoparsec.ByteString.Internal
44-- Copyright : Bryan O'Sullivan 2007-2014
@@ -46,7 +46,7 @@ module Data.Attoparsec.ByteString.Internal
4646 -- * Efficient string handling
4747 , skipWhile
4848 , string
49− , stringTransform
49+ , stringCI
5050 , take
5151 , scan
5252 , runScanner
@@ -170,7 +170,25 @@ take n = takeWith n (const True)
170170-- before failing. In attoparsec, the above parser will /succeed/ on
171171-- that input, because the failed first branch will consume nothing.
172172string :: ByteString -> Parser ByteString
173−string s = T.Parser $ \t pos more lose succ ->
173+string s = string_ (stringSuspended id) id s
174+{-# INLINE string #-}
175+
176+-- ASCII-specific but fast, oh yes.
177+toLower :: Word8 -> Word8
178+toLower w | w >= 65 && w <= 90 = w + 32
179+ | otherwise = w
180+
181+-- | Satisfy a literal string, ignoring case.
182+stringCI :: ByteString -> Parser ByteString
183+stringCI s = string_ (stringSuspended lower) lower s
184+ where lower = B8.map toLower
185+{-# INLINE stringCI #-}
186+
187+string_ :: (forall r. ByteString -> ByteString -> Buffer -> Pos -> More
188+ -> Failure r -> Success ByteString r -> Result r)
189+ -> (ByteString -> ByteString)
190+ -> ByteString -> Parser ByteString
191+string_ suspended f s0 = T.Parser $ \t pos more lose succ ->
174192 let n = B.length s
175193 in if lengthAtLeast pos n t
176194 then if s == substring pos (Pos n) t
@@ -178,34 +196,31 @@ string s = T.Parser $ \t pos more lose succ ->
178196 else lose t pos more [] "string"
179197 else let t' = Buf.unsafeDrop (fromPos pos) t
180198 in if t' `B.isPrefixOf` s
181− then stringSuspended s (B.drop (B.length t') s)
182− t pos more lose succ
199+ then suspended s (B.drop (B.length t') s) t pos more lose succ
183200 else lose t pos more [] "string"
184−{-# INLINE string #-}
201+ where s = f s0
202+{-# INLINE string_ #-}
185203
186−stringSuspended :: ByteString -> ByteString -> Buffer -> Pos -> More
204+stringSuspended :: (ByteString -> ByteString)
205+ -> ByteString -> ByteString -> Buffer -> Pos -> More
187206 -> Failure r
188207 -> Success ByteString r
189208 -> Result r
190−stringSuspended s0 s t pos more lose succ =
209+stringSuspended f s0 s t pos more lose succ =
191210 runParser (demandInput_ >>= go) t pos more lose succ
192− where go s' = T.Parser $ \t' pos' more' lose' succ' ->
211+ where go s'0 = T.Parser $ \t' pos' more' lose' succ' ->
193212 let m = B.length s
213+ s' = f s'0
194214 n = B.length s'
195215 in if n >= m
196216 then if B.unsafeTake m s' == s
197217 then succ' t' (pos' + Pos (B.length s0)) more' s0
198218 else lose' t' pos' more' [] "string"
199219 else if s' == B.unsafeTake n s
200− then stringSuspended s0 (B.unsafeDrop n s)
220+ then stringSuspended f s0 (B.unsafeDrop n s)
201221 t' pos' more' lose' succ'
202222 else lose' t' pos' more' [] "string"
203223
204−stringTransform :: (ByteString -> ByteString) -> ByteString
205− -> Parser ByteString
206−stringTransform f s = takeWith (B.length s) ((==f s) . f)
207−{-# INLINE stringTransform #-}
208−
209224-- | Skip past input for as long as the predicate returns 'True'.
210225skipWhile :: (Word8 -> Bool) -> Parser ()
211226skipWhile p = go