git.iko.soy/typeable/attoparsec
on master help sign in
Fix asciiCI performance
1e77033Kusanagi Kouichi
Data/Attoparsec/Text/Internal.hs+9−8
@@ -75,7 +75,7 @@ import Data.Attoparsec.Internal
75import Data.Attoparsec.Internal.Types hiding (Parser, Failure, Success)
75import Data.Attoparsec.Internal.Types hiding (Parser, Failure, Success)
76import qualified Data.Attoparsec.Text.Buffer as Buf
76import qualified Data.Attoparsec.Text.Buffer as Buf
77import Data.Attoparsec.Text.Buffer (Buffer, buffer)
77import Data.Attoparsec.Text.Buffer (Buffer, buffer)
78−import Data.Char (chr, ord)
78+import Data.Char (isAsciiUpper, isAsciiLower, toUpper, toLower)
79import Data.List (intercalate)
79import Data.List (intercalate)
80import Data.String (IsString(..))
80import Data.String (IsString(..))
81import Data.Text.Internal (Text(..))
81import Data.Text.Internal (Text(..))
@@ -225,15 +225,16 @@ stringCI s = go 0
225
225
226-- | Satisfy a literal string, ignoring case for characters in the ASCII range.
226-- | Satisfy a literal string, ignoring case for characters in the ASCII range.
227asciiCI :: Text -> Parser Text
227asciiCI :: Text -> Parser Text
228−asciiCI s = string_ (stringSuspended asciiToLower) asciiToLower s
228+asciiCI s = fmap fst $ match $ T.foldr ((*>) . asciiCharCI) (pure ()) s
229− where
230− asciiToLower = T.map f
231− where
232− offset = ord 'a' - ord 'A'
233− f c | 'A' <= c && c <= 'Z' = chr (ord c + offset)
234− | otherwise = c
235{-# INLINE asciiCI #-}
229{-# INLINE asciiCI #-}
236
230
231+asciiCharCI :: Char -> Parser Char
232+asciiCharCI c
233+ | isAsciiUpper c = char c <|> char (toLower c)
234+ | isAsciiLower c = char c <|> char (toUpper c)
235+ | otherwise = char c
236+{-# INLINE asciiCharCI #-}
237+
237-- | Skip past input for as long as the predicate returns 'True'.
238-- | Skip past input for as long as the predicate returns 'True'.
238skipWhile :: (Char -> Bool) -> Parser ()
239skipWhile :: (Char -> Bool) -> Parser ()
239skipWhile p = go
240skipWhile p = go