{-# LANGUAGE BangPatterns, CPP, FlexibleInstances, TypeSynonymInstances #-}
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
module Data.Attoparsec.Text
(
Parser
, Result
, T.IResult(..)
, I.compareResults
, parse
, feed
, I.parseOnly
, parseWith
, parseTest
, maybeResult
, eitherResult
, I.char
, I.anyChar
, I.notChar
, I.satisfy
, I.satisfyWith
, I.skip
, I.peekChar
, I.peekChar'
, digit
, letter
, space
, I.inClass
, I.notInClass
, I.string
, I.stringCI
, I.asciiCI
, skipSpace
, I.skipWhile
, I.scan
, I.runScanner
, I.take
, I.takeWhile
, I.takeWhile1
, I.takeTill
, (.*>)
, (<*.)
, I.takeText
, I.takeLazyText
, I.endOfLine
, isEndOfLine
, isHorizontalSpace
, decimal
, hexadecimal
, signed
, double
, Number(..)
, number
, rational
, scientific
, try
, (<?>)
, choice
, count
, option
, many'
, many1
, many1'
, manyTill
, manyTill'
, sepBy
, sepBy'
, sepBy1
, sepBy1'
, skipMany
, skipMany1
, eitherP
, I.match
, I.endOfInput
, I.atEnd
) where
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative (pure, (*>), (<*), (<$>))
import Data.Word (Word)
#endif
import Control.Applicative ((<|>))
import Data.Attoparsec.Combinator
import Data.Attoparsec.Number (Number(..))
import Data.Scientific (Scientific)
import qualified Data.Scientific as Sci
import Data.Attoparsec.Text.Internal (Parser, Result, parse, takeWhile1)
import Data.Bits (Bits, (.|.), shiftL)
import Data.Char (isAlpha, isDigit, isSpace, ord)
import Data.Int (Int8, Int16, Int32, Int64)
import Data.List (intercalate)
import Data.Text (Text)
import Data.Word (Word8, Word16, Word32, Word64)
import qualified Data.Attoparsec.Internal as I
import qualified Data.Attoparsec.Internal.Types as T
import qualified Data.Attoparsec.Text.Internal as I
import qualified Data.Text as T
parseTest :: (Show a) => I.Parser a -> Text -> IO ()
parseTest :: Parser a -> Text -> IO ()
parseTest p :: Parser a
p s :: Text
s = Result a -> IO ()
forall a. Show a => a -> IO ()
print (Parser a -> Text -> Result a
forall a. Parser a -> Text -> Result a
parse Parser a
p Text
s)
parseWith :: Monad m =>
(m Text)
-> I.Parser a
-> Text
-> m (Result a)
parseWith :: m Text -> Parser a -> Text -> m (Result a)
parseWith refill :: m Text
refill p :: Parser a
p s :: Text
s = Result a -> m (Result a)
forall r. IResult Text r -> m (IResult Text r)
step (Result a -> m (Result a)) -> Result a -> m (Result a)
forall a b. (a -> b) -> a -> b
$ Parser a -> Text -> Result a
forall a. Parser a -> Text -> Result a
parse Parser a
p Text
s
where step :: IResult Text r -> m (IResult Text r)
step (T.Partial k :: Text -> IResult Text r
k) = (IResult Text r -> m (IResult Text r)
step (IResult Text r -> m (IResult Text r))
-> (Text -> IResult Text r) -> Text -> m (IResult Text r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> IResult Text r
k) (Text -> m (IResult Text r)) -> m Text -> m (IResult Text r)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m Text
refill
step r :: IResult Text r
r = IResult Text r -> m (IResult Text r)
forall (m :: * -> *) a. Monad m => a -> m a
return IResult Text r
r
{-# INLINE parseWith #-}
maybeResult :: Result r -> Maybe r
maybeResult :: Result r -> Maybe r
maybeResult (T.Done _ r :: r
r) = r -> Maybe r
forall a. a -> Maybe a
Just r
r
maybeResult _ = Maybe r
forall a. Maybe a
Nothing
eitherResult :: Result r -> Either String r
eitherResult :: Result r -> Either String r
eitherResult (T.Done _ r :: r
r) = r -> Either String r
forall a b. b -> Either a b
Right r
r
eitherResult (T.Fail _ [] msg :: String
msg) = String -> Either String r
forall a b. a -> Either a b
Left String
msg
eitherResult (T.Fail _ ctxs :: [String]
ctxs msg :: String
msg) = String -> Either String r
forall a b. a -> Either a b
Left (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate " > " [String]
ctxs String -> String -> String
forall a. [a] -> [a] -> [a]
++ ": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
msg)
eitherResult _ = String -> Either String r
forall a b. a -> Either a b
Left "Result: incomplete input"
isEndOfLine :: Char -> Bool
isEndOfLine :: Char -> Bool
isEndOfLine c :: Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\n' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\r'
{-# INLINE isEndOfLine #-}
isHorizontalSpace :: Char -> Bool
isHorizontalSpace :: Char -> Bool
isHorizontalSpace c :: Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== ' ' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\t'
{-# INLINE isHorizontalSpace #-}
hexadecimal :: (Integral a, Bits a) => Parser a
hexadecimal :: Parser a
hexadecimal = (a -> Char -> a) -> a -> Text -> a
forall a. (a -> Char -> a) -> a -> Text -> a
T.foldl' a -> Char -> a
forall a. (Bits a, Num a) => a -> Char -> a
step 0 (Text -> a) -> Parser Text Text -> Parser a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` (Char -> Bool) -> Parser Text Text
takeWhile1 Char -> Bool
isHexDigit
where
isHexDigit :: Char -> Bool
isHexDigit c :: Char
c = (Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= '0' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= '9') Bool -> Bool -> Bool
||
(Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= 'a' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= 'f') Bool -> Bool -> Bool
||
(Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= 'A' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= 'F')
step :: a -> Char -> a
step a :: a
a c :: Char
c | Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 48 Bool -> Bool -> Bool
&& Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 57 = (a
a a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` 4) a -> a -> a
forall a. Bits a => a -> a -> a
.|. Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- 48)
| Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 97 = (a
a a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` 4) a -> a -> a
forall a. Bits a => a -> a -> a
.|. Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- 87)
| Bool
otherwise = (a
a a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` 4) a -> a -> a
forall a. Bits a => a -> a -> a
.|. Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- 55)
where w :: Int
w = Char -> Int
ord Char
c
{-# SPECIALISE hexadecimal :: Parser Int #-}
{-# SPECIALISE hexadecimal :: Parser Int8 #-}
{-# SPECIALISE hexadecimal :: Parser Int16 #-}
{-# SPECIALISE hexadecimal :: Parser Int32 #-}
{-# SPECIALISE hexadecimal :: Parser Int64 #-}
{-# SPECIALISE hexadecimal :: Parser Integer #-}
{-# SPECIALISE hexadecimal :: Parser Word #-}
{-# SPECIALISE hexadecimal :: Parser Word8 #-}
{-# SPECIALISE hexadecimal :: Parser Word16 #-}
{-# SPECIALISE hexadecimal :: Parser Word32 #-}
{-# SPECIALISE hexadecimal :: Parser Word64 #-}
decimal :: Integral a => Parser a
decimal :: Parser a
decimal = (a -> Char -> a) -> a -> Text -> a
forall a. (a -> Char -> a) -> a -> Text -> a
T.foldl' a -> Char -> a
forall a. Num a => a -> Char -> a
step 0 (Text -> a) -> Parser Text Text -> Parser a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` (Char -> Bool) -> Parser Text Text
takeWhile1 Char -> Bool
isDecimal
where step :: a -> Char -> a
step a :: a
a c :: Char
c = a
a a -> a -> a
forall a. Num a => a -> a -> a
* 10 a -> a -> a
forall a. Num a => a -> a -> a
+ Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- 48)
{-# SPECIALISE decimal :: Parser Int #-}
{-# SPECIALISE decimal :: Parser Int8 #-}
{-# SPECIALISE decimal :: Parser Int16 #-}
{-# SPECIALISE decimal :: Parser Int32 #-}
{-# SPECIALISE decimal :: Parser Int64 #-}
{-# SPECIALISE decimal :: Parser Integer #-}
{-# SPECIALISE decimal :: Parser Word #-}
{-# SPECIALISE decimal :: Parser Word8 #-}
{-# SPECIALISE decimal :: Parser Word16 #-}
{-# SPECIALISE decimal :: Parser Word32 #-}
{-# SPECIALISE decimal :: Parser Word64 #-}
isDecimal :: Char -> Bool
isDecimal :: Char -> Bool
isDecimal c :: Char
c = Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= '0' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= '9'
{-# INLINE isDecimal #-}
signed :: Num a => Parser a -> Parser a
{-# SPECIALISE signed :: Parser Int -> Parser Int #-}
{-# SPECIALISE signed :: Parser Int8 -> Parser Int8 #-}
{-# SPECIALISE signed :: Parser Int16 -> Parser Int16 #-}
{-# SPECIALISE signed :: Parser Int32 -> Parser Int32 #-}
{-# SPECIALISE signed :: Parser Int64 -> Parser Int64 #-}
{-# SPECIALISE signed :: Parser Integer -> Parser Integer #-}
signed :: Parser a -> Parser a
signed p :: Parser a
p = (a -> a
forall a. Num a => a -> a
negate (a -> a) -> Parser a -> Parser a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Parser Char
I.char '-' Parser Char -> Parser a -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser a
p))
Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Char -> Parser Char
I.char '+' Parser Char -> Parser a -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser a
p)
Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser a
p
rational :: Fractional a => Parser a
{-# SPECIALIZE rational :: Parser Double #-}
{-# SPECIALIZE rational :: Parser Float #-}
{-# SPECIALIZE rational :: Parser Rational #-}
{-# SPECIALIZE rational :: Parser Scientific #-}
rational :: Parser a
rational = (Scientific -> a) -> Parser a
forall a. (Scientific -> a) -> Parser a
scientifically Scientific -> a
forall a b. (Real a, Fractional b) => a -> b
realToFrac
double :: Parser Double
double :: Parser Double
double = (Scientific -> Double) -> Parser Double
forall a. (Scientific -> a) -> Parser a
scientifically Scientific -> Double
forall a. RealFloat a => Scientific -> a
Sci.toRealFloat
number :: Parser Number
number :: Parser Number
number = (Scientific -> Number) -> Parser Number
forall a. (Scientific -> a) -> Parser a
scientifically ((Scientific -> Number) -> Parser Number)
-> (Scientific -> Number) -> Parser Number
forall a b. (a -> b) -> a -> b
$ \s :: Scientific
s ->
let e :: Int
e = Scientific -> Int
Sci.base10Exponent Scientific
s
c :: Integer
c = Scientific -> Integer
Sci.coefficient Scientific
s
in if Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 0
then Integer -> Number
I (Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* 10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
e)
else Double -> Number
D (Scientific -> Double
forall a. RealFloat a => Scientific -> a
Sci.toRealFloat Scientific
s)
{-# DEPRECATED number "Use 'scientific' instead." #-}
scientific :: Parser Scientific
scientific :: Parser Scientific
scientific = (Scientific -> Scientific) -> Parser Scientific
forall a. (Scientific -> a) -> Parser a
scientifically Scientific -> Scientific
forall a. a -> a
id
data SP = SP !Integer {-# UNPACK #-}!Int
{-# INLINE scientifically #-}
scientifically :: (Scientific -> a) -> Parser a
scientifically :: (Scientific -> a) -> Parser a
scientifically h :: Scientific -> a
h = do
!Bool
positive <- ((Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '+') (Char -> Bool) -> Parser Char -> Parser Text Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Bool) -> Parser Char
I.satisfy (\c :: Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '-' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '+')) Parser Text Bool -> Parser Text Bool -> Parser Text Bool
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
Bool -> Parser Text Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
Integer
n <- Parser Integer
forall a. Integral a => Parser a
decimal
let f :: Text -> SP
f fracDigits :: Text
fracDigits = Integer -> Int -> SP
SP ((Integer -> Char -> Integer) -> Integer -> Text -> Integer
forall a. (a -> Char -> a) -> a -> Text -> a
T.foldl' Integer -> Char -> Integer
forall a. Num a => a -> Char -> a
step Integer
n Text
fracDigits)
(Int -> Int
forall a. Num a => a -> a
negate (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Text -> Int
T.length Text
fracDigits)
step :: a -> Char -> a
step a :: a
a c :: Char
c = a
a a -> a -> a
forall a. Num a => a -> a -> a
* 10 a -> a -> a
forall a. Num a => a -> a -> a
+ Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- 48)
SP c :: Integer
c e :: Int
e <- ((Char -> Bool) -> Parser Char
I.satisfy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
=='.') Parser Char -> Parser Text SP -> Parser Text SP
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Text -> SP
f (Text -> SP) -> Parser Text Text -> Parser Text SP
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Bool) -> Parser Text Text
I.takeWhile Char -> Bool
isDigit)) Parser Text SP -> Parser Text SP -> Parser Text SP
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
SP -> Parser Text SP
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Int -> SP
SP Integer
n 0)
let !signedCoeff :: Integer
signedCoeff | Bool
positive = Integer
c
| Bool
otherwise = -Integer
c
((Char -> Bool) -> Parser Char
I.satisfy (\w :: Char
w -> Char
w Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== 'e' Bool -> Bool -> Bool
|| Char
w Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== 'E') Parser Char -> Parser a -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
(Int -> a) -> Parser Text Int -> Parser a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Scientific -> a
h (Scientific -> a) -> (Int -> Scientific) -> Int -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Int -> Scientific
Sci.scientific Integer
signedCoeff (Int -> Scientific) -> (Int -> Int) -> Int -> Scientific
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+)) (Parser Text Int -> Parser Text Int
forall a. Num a => Parser a -> Parser a
signed Parser Text Int
forall a. Integral a => Parser a
decimal)) Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Scientific -> a
h (Scientific -> a) -> Scientific -> a
forall a b. (a -> b) -> a -> b
$ Integer -> Int -> Scientific
Sci.scientific Integer
signedCoeff Int
e)
digit :: Parser Char
digit :: Parser Char
digit = (Char -> Bool) -> Parser Char
I.satisfy Char -> Bool
isDigit Parser Char -> String -> Parser Char
forall i a. Parser i a -> String -> Parser i a
<?> "digit"
{-# INLINE digit #-}
letter :: Parser Char
letter :: Parser Char
letter = (Char -> Bool) -> Parser Char
I.satisfy Char -> Bool
isAlpha Parser Char -> String -> Parser Char
forall i a. Parser i a -> String -> Parser i a
<?> "letter"
{-# INLINE letter #-}
space :: Parser Char
space :: Parser Char
space = (Char -> Bool) -> Parser Char
I.satisfy Char -> Bool
isSpace Parser Char -> String -> Parser Char
forall i a. Parser i a -> String -> Parser i a
<?> "space"
{-# INLINE space #-}
skipSpace :: Parser ()
skipSpace :: Parser ()
skipSpace = (Char -> Bool) -> Parser ()
I.skipWhile Char -> Bool
isSpace
{-# INLINE skipSpace #-}
(.*>) :: Text -> Parser a -> Parser a
s :: Text
s .*> :: Text -> Parser a -> Parser a
.*> f :: Parser a
f = Text -> Parser Text Text
I.string Text
s Parser Text Text -> Parser a -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser a
f
{-# DEPRECATED (.*>) "This is no longer necessary, and will be removed. Use '*>' instead." #-}
(<*.) :: Parser a -> Text -> Parser a
f :: Parser a
f <*. :: Parser a -> Text -> Parser a
<*. s :: Text
s = Parser a
f Parser a -> Parser Text Text -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Text -> Parser Text Text
I.string Text
s
{-# DEPRECATED (<*.) "This is no longer necessary, and will be removed. Use '<*' instead." #-}