module Data.ByteString.Parser.Char8
( Parser(..)
, Result(..)
, parseOnly
, char
, notChar
, anyChar
, satisfy
, space
, isSpace
, skipSpace
, peekChar
, string
, stringCI
, Data.ByteString.Parser.Char8.take
, scan
, runScanner
, inRange
, notInRange
, Data.ByteString.Parser.Char8.takeWhile
, takeWhile1
, takeTill
, takeTill1
, signed
, decimal
, hexadecimal
, octal
, fractional
, provided
, choice
, Data.ByteString.Parser.count
, optional
, eitherP
, option
, many
, many1
, manyTill
, sepBy
, sepBy1
, wrap
, match
, label
, extent
, takeByteString
, endOfInput
, atEnd
, Control.Applicative.empty
, pure
, guard
, when
, unless
, void
)
where
import Prelude hiding (null, length, splitAt, take)
import Control.Applicative
import Control.Monad
import Data.Maybe
import Data.Word
import GHC.Base (unsafeChr)
import Data.ByteString as BS
import Data.ByteString.Unsafe as BS
import Snack.Combinators
import Data.ByteString.Parser ( Parser(..), Result(..), parseOnly
, string, count, match, label, extent
, takeByteString, endOfInput, atEnd
)
import Data.ByteString.Lex.Fractional qualified as LF
import Data.ByteString.Lex.Integral qualified as LI
{-# INLINE CONLIKE char #-}
char :: Char -> Parser Char
char :: Char -> Parser Char
char Char
c = String -> Parser Char -> Parser Char
forall a. String -> Parser a -> Parser a
label (Char -> String
forall a. Show a => a -> String
show Char
c) (Parser Char -> Parser Char) -> Parser Char -> Parser Char
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> Parser Char
satisfy (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==)
{-# INLINE CONLIKE notChar #-}
notChar :: Char -> Parser Char
notChar :: Char -> Parser Char
notChar Char
c = (Char -> Bool) -> Parser Char
satisfy (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=)
{-# INLINE anyChar #-}
anyChar :: Parser Char
anyChar :: Parser Char
anyChar = (ByteString -> Result Char) -> Parser Char
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
if ByteString -> Bool
null ByteString
inp
then [String] -> ByteString -> Result Char
forall a. [String] -> ByteString -> Result a
Failure [String
"any character"] ByteString
inp
else Char -> ByteString -> Result Char
forall a. a -> ByteString -> Result a
Success (Word8 -> Char
w2c (ByteString -> Word8
unsafeHead ByteString
inp)) (ByteString -> ByteString
unsafeTail ByteString
inp)
{-# INLINE CONLIKE satisfy #-}
satisfy :: (Char -> Bool) -> Parser Char
satisfy :: (Char -> Bool) -> Parser Char
satisfy Char -> Bool
isOk = (ByteString -> Result Char) -> Parser Char
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
if ByteString -> Bool
null ByteString
inp
then [String] -> ByteString -> Result Char
forall a. [String] -> ByteString -> Result a
Failure [String
"more input"] ByteString
inp
else let c :: Char
c = Word8 -> Char
w2c (ByteString -> Word8
unsafeHead ByteString
inp)
in if Char -> Bool
isOk Char
c
then Char -> ByteString -> Result Char
forall a. a -> ByteString -> Result a
Success Char
c (ByteString -> ByteString
unsafeTail ByteString
inp)
else [String] -> ByteString -> Result Char
forall a. [String] -> ByteString -> Result a
Failure [] ByteString
inp
{-# INLINE space #-}
space :: Parser Char
space :: Parser Char
space = String -> Parser Char -> Parser Char
forall a. String -> Parser a -> Parser a
label String
"space" (Parser Char -> Parser Char) -> Parser Char -> Parser Char
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> Parser Char
satisfy Char -> Bool
isSpace
{-# INLINE skipSpace #-}
skipSpace :: Parser ()
skipSpace :: Parser ()
skipSpace = Parser ByteString -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser ByteString -> Parser ()) -> Parser ByteString -> Parser ()
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> Parser ByteString
Data.ByteString.Parser.Char8.takeWhile Char -> Bool
isSpace
{-# INLINE isSpace #-}
isSpace :: Char -> Bool
isSpace :: Char -> Bool
isSpace Char
c = (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') Bool -> Bool -> Bool
|| (Char
'\t' Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'\r')
{-# INLINE peekChar #-}
peekChar :: Parser Char
peekChar :: Parser Char
peekChar = (ByteString -> Result Char) -> Parser Char
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
if ByteString -> Bool
null ByteString
inp
then [String] -> ByteString -> Result Char
forall a. [String] -> ByteString -> Result a
Failure [String
"more input"] ByteString
inp
else Char -> ByteString -> Result Char
forall a. a -> ByteString -> Result a
Success (Word8 -> Char
w2c (ByteString -> Word8
unsafeHead ByteString
inp)) ByteString
inp
{-# INLINE CONLIKE stringCI #-}
stringCI :: ByteString -> Parser ByteString
stringCI :: ByteString -> Parser ByteString
stringCI ByteString
str = (ByteString -> Result ByteString) -> Parser ByteString
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
let (ByteString
pfx, ByteString
sfx) = Int -> ByteString -> (ByteString, ByteString)
splitAt (ByteString -> Int
length ByteString
str) ByteString
inp
in case ByteString -> ByteString
toCaseFold ByteString
pfx ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString -> ByteString
toCaseFold ByteString
str of
Bool
True -> ByteString -> ByteString -> Result ByteString
forall a. a -> ByteString -> Result a
Success ByteString
pfx ByteString
sfx
Bool
False -> [String] -> ByteString -> Result ByteString
forall a. [String] -> ByteString -> Result a
Failure [ByteString -> String
forall a. Show a => a -> String
show ByteString
pfx] ByteString
inp
{-# INLINE toCaseFold #-}
toCaseFold :: ByteString -> ByteString
toCaseFold :: ByteString -> ByteString
toCaseFold = (Word8 -> Word8) -> ByteString -> ByteString
BS.map Word8 -> Word8
forall {a}. (Ord a, Num a) => a -> a
foldCase
where foldCase :: a -> a
foldCase a
w | a
65 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
w Bool -> Bool -> Bool
&& a
w a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
90 = a
w a -> a -> a
forall a. Num a => a -> a -> a
+ a
32
foldCase a
w = a
w
{-# INLINE CONLIKE take #-}
take :: Int -> Parser ByteString
take :: Int -> Parser ByteString
take Int
n = (ByteString -> Result ByteString) -> Parser ByteString
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> ByteString -> Int
length ByteString
inp
then [String] -> ByteString -> Result ByteString
forall a. [String] -> ByteString -> Result a
Failure [Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" more bytes"] ByteString
inp
else ByteString -> ByteString -> Result ByteString
forall a. a -> ByteString -> Result a
Success (Int -> ByteString -> ByteString
unsafeTake Int
n ByteString
inp) (Int -> ByteString -> ByteString
unsafeDrop Int
n ByteString
inp)
{-# INLINE CONLIKE scan #-}
scan :: s -> (s -> Char -> Maybe s) -> Parser ByteString
scan :: forall s. s -> (s -> Char -> Maybe s) -> Parser ByteString
scan s
state s -> Char -> Maybe s
scanner = (ByteString, s) -> ByteString
forall a b. (a, b) -> a
fst ((ByteString, s) -> ByteString)
-> Parser (ByteString, s) -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> (s -> Char -> Maybe s) -> Parser (ByteString, s)
forall s. s -> (s -> Char -> Maybe s) -> Parser (ByteString, s)
runScanner s
state s -> Char -> Maybe s
scanner
{-# INLINE CONLIKE runScanner #-}
runScanner :: s -> (s -> Char -> Maybe s) -> Parser (ByteString, s)
runScanner :: forall s. s -> (s -> Char -> Maybe s) -> Parser (ByteString, s)
runScanner s
state s -> Char -> Maybe s
scanner = (ByteString -> Result (ByteString, s)) -> Parser (ByteString, s)
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp -> ByteString -> s -> Int -> Result (ByteString, s)
loop ByteString
inp s
state Int
0
where
loop :: ByteString -> s -> Int -> Result (ByteString, s)
loop ByteString
inp !s
st !Int
n =
case Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= ByteString -> Int
length ByteString
inp of
Bool
True -> (ByteString, s) -> ByteString -> Result (ByteString, s)
forall a. a -> ByteString -> Result a
Success (ByteString
inp, s
st) ByteString
forall a. Monoid a => a
mempty
Bool
False ->
case ByteString -> Int -> Word8
unsafeIndex ByteString
inp Int
n of
Word8
w ->
case s -> Char -> Maybe s
scanner s
st (Word8 -> Char
w2c Word8
w) of
Maybe s
Nothing -> (ByteString, s) -> ByteString -> Result (ByteString, s)
forall a. a -> ByteString -> Result a
Success (Int -> ByteString -> ByteString
unsafeTake Int
n ByteString
inp, s
st) (Int -> ByteString -> ByteString
unsafeDrop Int
n ByteString
inp)
Just s
st' -> ByteString -> s -> Int -> Result (ByteString, s)
loop ByteString
inp s
st' (Int -> Int
forall a. Enum a => a -> a
succ Int
n)
{-# INLINE CONLIKE takeWhile #-}
takeWhile :: (Char -> Bool) -> Parser ByteString
takeWhile :: (Char -> Bool) -> Parser ByteString
takeWhile Char -> Bool
test = (Char -> Bool) -> Parser ByteString
takeTill (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
test)
{-# INLINE CONLIKE takeWhile1 #-}
takeWhile1 :: (Char -> Bool) -> Parser ByteString
takeWhile1 :: (Char -> Bool) -> Parser ByteString
takeWhile1 Char -> Bool
test = (Char -> Bool) -> Parser ByteString
Data.ByteString.Parser.Char8.takeWhile Char -> Bool
test Parser ByteString -> (ByteString -> Bool) -> Parser ByteString
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
m a -> (a -> Bool) -> m a
`provided` (Bool -> Bool
not (Bool -> Bool) -> (ByteString -> Bool) -> ByteString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Bool
null)
{-# INLINE CONLIKE takeTill #-}
takeTill :: (Char -> Bool) -> Parser ByteString
takeTill :: (Char -> Bool) -> Parser ByteString
takeTill Char -> Bool
test = (ByteString -> Result ByteString) -> Parser ByteString
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
let n :: Int
n = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (ByteString -> Int
length ByteString
inp) (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ (Word8 -> Bool) -> ByteString -> Maybe Int
findIndex (Char -> Bool
test (Char -> Bool) -> (Word8 -> Char) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Char
w2c) ByteString
inp
in ByteString -> ByteString -> Result ByteString
forall a. a -> ByteString -> Result a
Success (Int -> ByteString -> ByteString
unsafeTake Int
n ByteString
inp) (Int -> ByteString -> ByteString
unsafeDrop Int
n ByteString
inp)
{-# INLINE CONLIKE takeTill1 #-}
takeTill1 :: (Char -> Bool) -> Parser ByteString
takeTill1 :: (Char -> Bool) -> Parser ByteString
takeTill1 Char -> Bool
test = (Char -> Bool) -> Parser ByteString
Data.ByteString.Parser.Char8.takeTill Char -> Bool
test Parser ByteString -> (ByteString -> Bool) -> Parser ByteString
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
m a -> (a -> Bool) -> m a
`provided` (Bool -> Bool
not (Bool -> Bool) -> (ByteString -> Bool) -> ByteString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Bool
null)
{-# INLINE signed #-}
signed :: (Num a) => Parser a -> Parser a
signed :: forall a. Num a => Parser a -> Parser a
signed Parser a
runNumber = (Char -> Parser Char
char Char
'-' Parser Char -> Parser a -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (a -> a) -> Parser a -> Parser a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
negate Parser a
runNumber)
Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Char -> Parser Char
char Char
'+' Parser Char -> Parser a -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser a
runNumber)
Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser a
runNumber)
{-# INLINE decimal #-}
decimal :: (Integral a) => Parser a
decimal :: forall a. Integral a => Parser a
decimal = (ByteString -> Result a) -> Parser a
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
case ByteString -> Maybe (a, ByteString)
forall a. Integral a => ByteString -> Maybe (a, ByteString)
LI.readDecimal ByteString
inp of
Just (a
res, ByteString
more) -> a -> ByteString -> Result a
forall a. a -> ByteString -> Result a
Success a
res ByteString
more
Maybe (a, ByteString)
Nothing -> [String] -> ByteString -> Result a
forall a. [String] -> ByteString -> Result a
Failure [String
"decimal"] ByteString
inp
{-# INLINE hexadecimal #-}
hexadecimal :: (Integral a) => Parser a
hexadecimal :: forall a. Integral a => Parser a
hexadecimal = (ByteString -> Result a) -> Parser a
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
case ByteString -> Maybe (a, ByteString)
forall a. Integral a => ByteString -> Maybe (a, ByteString)
LI.readHexadecimal ByteString
inp of
Just (a
res, ByteString
more) -> a -> ByteString -> Result a
forall a. a -> ByteString -> Result a
Success a
res ByteString
more
Maybe (a, ByteString)
Nothing -> [String] -> ByteString -> Result a
forall a. [String] -> ByteString -> Result a
Failure [String
"hexadecimal"] ByteString
inp
{-# INLINE octal #-}
octal :: (Integral a) => Parser a
octal :: forall a. Integral a => Parser a
octal = (ByteString -> Result a) -> Parser a
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
case ByteString -> Maybe (a, ByteString)
forall a. Integral a => ByteString -> Maybe (a, ByteString)
LI.readOctal ByteString
inp of
Just (a
res, ByteString
more) -> a -> ByteString -> Result a
forall a. a -> ByteString -> Result a
Success a
res ByteString
more
Maybe (a, ByteString)
Nothing -> [String] -> ByteString -> Result a
forall a. [String] -> ByteString -> Result a
Failure [String
"octal"] ByteString
inp
{-# INLINE fractional #-}
fractional :: (Fractional a) => Parser a
fractional :: forall a. Fractional a => Parser a
fractional = (ByteString -> Result a) -> Parser a
forall a. (ByteString -> Result a) -> Parser a
Parser \ByteString
inp ->
case ByteString -> Maybe (a, ByteString)
forall a. Fractional a => ByteString -> Maybe (a, ByteString)
LF.readDecimal ByteString
inp of
Just (a
res, ByteString
more) -> a -> ByteString -> Result a
forall a. a -> ByteString -> Result a
Success a
res ByteString
more
Maybe (a, ByteString)
Nothing -> [String] -> ByteString -> Result a
forall a. [String] -> ByteString -> Result a
Failure [String
"fractional"] ByteString
inp
{-# INLINE w2c #-}
w2c :: Word8 -> Char
w2c :: Word8 -> Char
w2c = Int -> Char
unsafeChr (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral