    module Text.ParserCombinators.Poly.ByteStringChar
      ( -- * The Parser datatype
        Parser(P)
      , Result(..)
      , runParser
        -- ** Basic parsers
      , next
      , eof
      , satisfy
      , onFail
        -- ** Derived parsers (but implemented more efficiently)
      , manySatisfy
      , many1Satisfy
        -- ** Re-parsing
      , reparse
        -- * Re-export all more general combinators
      , module Text.ParserCombinators.Poly.Base
      ) where

    import Text.ParserCombinators.Poly.Base
    import Text.ParserCombinators.Poly.Result
    import qualified Data.ByteString.Lazy.Char8 as BS
    import Data.ByteString.Lazy.Char8 (ByteString)
    import Control.Applicative
    import qualified Control.Monad.Fail as Fail

    -- | This @Parser@ datatype is a specialised parsing monad with error
    --   reporting.  Whereas the standard version can be used for arbitrary
    --   token types, this version is specialised to ByteString input only.
    newtype Parser a = P (ByteString -> Result ByteString a)

    -- | Apply a parser to an input token sequence.
    runParser :: Parser a -> ByteString -> (Either String a, ByteString)
    runParser :: forall a. Parser a -> ByteString -> (Either String a, ByteString)
    runParser (P ByteString -> Result ByteString a
    p) = Result ByteString a -> (Either String a, ByteString)
    forall z a. Result z a -> (Either String a, z)
    resultToEither (Result ByteString a -> (Either String a, ByteString))
    -> (ByteString -> Result ByteString a)
    -> ByteString
    -> (Either String a, ByteString)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Result ByteString a
    p

    instance Functor Parser where
        fmap :: forall a b. (a -> b) -> Parser a -> Parser b
    fmap a -> b
    f (P ByteString -> Result ByteString a
    p) = (ByteString -> Result ByteString b) -> Parser b
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P ((a -> b) -> Result ByteString a -> Result ByteString b
    forall a b. (a -> b) -> Result ByteString a -> Result ByteString b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f (Result ByteString a -> Result ByteString b)
    -> (ByteString -> Result ByteString a)
    -> ByteString
    -> Result ByteString b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Result ByteString a
    p)

    instance Monad Parser where
        return :: forall a. a -> Parser a
    return       = a -> Parser a
    forall a. a -> Parser a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure
        (P ByteString -> Result ByteString a
    f) >>= :: forall a b. Parser a -> (a -> Parser b) -> Parser b
    >>= a -> Parser b
    g  = (ByteString -> Result ByteString b) -> Parser b
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (Result ByteString a -> Result ByteString b
    continue (Result ByteString a -> Result ByteString b)
    -> (ByteString -> Result ByteString a)
    -> ByteString
    -> Result ByteString b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Result ByteString a
    f)
          where
            continue :: Result ByteString a -> Result ByteString b
    continue (Success ByteString
    ts a
    x)             = let (P ByteString -> Result ByteString b
    g') = a -> Parser b
    g a
    x in ByteString -> Result ByteString b
    g' ByteString
    ts
            continue (Committed Result ByteString a
    r)              = Result ByteString b -> Result ByteString b
    forall z a. Result z a -> Result z a
    Committed (Result ByteString a -> Result ByteString b
    continue Result ByteString a
    r)
            continue (Failure ByteString
    ts String
    e)             = ByteString -> String -> Result ByteString b
    forall z a. z -> String -> Result z a
    Failure ByteString
    ts String
    e

    #if !MIN_VERSION_base(4,13,0)
        fail         = Fail.fail
    #endif

    instance Fail.MonadFail Parser where
        fail :: forall a. String -> Parser a
    fail String
    e       = (ByteString -> Result ByteString a) -> Parser a
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (\ByteString
    ts-> ByteString -> String -> Result ByteString a
    forall z a. z -> String -> Result z a
    Failure ByteString
    ts String
    e)

    instance Commitment Parser where
        commit :: forall a. Parser a -> Parser a
    commit (P ByteString -> Result ByteString a
    p)         = (ByteString -> Result ByteString a) -> Parser a
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (Result ByteString a -> Result ByteString a
    forall z a. Result z a -> Result z a
    Committed (Result ByteString a -> Result ByteString a)
    -> (ByteString -> Result ByteString a)
    -> ByteString
    -> Result ByteString a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Result ByteString a -> Result ByteString a
    forall z a. Result z a -> Result z a
    squash (Result ByteString a -> Result ByteString a)
    -> (ByteString -> Result ByteString a)
    -> ByteString
    -> Result ByteString a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Result ByteString a
    p)
          where
            squash :: Result z a -> Result z a
    squash (Committed Result z a
    r) = Result z a -> Result z a
    squash Result z a
    r
            squash Result z a
    r             = Result z a
    r
        (P ByteString -> Result ByteString a
    p) adjustErr :: forall a. Parser a -> (String -> String) -> Parser a
    `adjustErr` String -> String
    f  = (ByteString -> Result ByteString a) -> Parser a
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (Result ByteString a -> Result ByteString a
    forall z a. Result z a -> Result z a
    adjust (Result ByteString a -> Result ByteString a)
    -> (ByteString -> Result ByteString a)
    -> ByteString
    -> Result ByteString a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Result ByteString a
    p)
          where
            adjust :: Result z a -> Result z a
    adjust (Failure z
    z String
    e) = z -> String -> Result z a
    forall z a. z -> String -> Result z a
    Failure z
    z (String -> String
    f String
    e)
            adjust (Committed Result z a
    r) = Result z a -> Result z a
    forall z a. Result z a -> Result z a
    Committed (Result z a -> Result z a
    adjust Result z a
    r)
            adjust  Result z a
    good         = Result z a
    good

        oneOf' :: forall a. [(String, Parser a)] -> Parser a
    oneOf' = [(String, String)] -> [(String, Parser a)] -> Parser a
    forall {a}. [(String, String)] -> [(String, Parser a)] -> Parser a
    accum []
          where accum :: [(String, String)] -> [(String, Parser a)] -> Parser a
    accum [(String, String)]
    errs [] =
                    String -> Parser a
    forall a. String -> Parser a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String
    "failed to parse any of the possible choices:\n"
                                String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++Int -> String -> String
    indent Int
    2 (((String, String) -> String) -> [(String, String)] -> String
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (String, String) -> String
    showErr ([(String, String)] -> [(String, String)]
    forall a. [a] -> [a]
    reverse [(String, String)]
    errs)))
                accum [(String, String)]
    errs ((String
    e,P ByteString -> Result ByteString a
    p):[(String, Parser a)]
    ps) =
                    (ByteString -> Result ByteString a) -> Parser a
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (\ByteString
    ts-> case ByteString -> Result ByteString a
    p ByteString
    ts of
                               Failure ByteString
    _ String
    err ->
                                           let (P ByteString -> Result ByteString a
    p') = [(String, String)] -> [(String, Parser a)] -> Parser a
    accum ((String
    e,String
    err)(String, String) -> [(String, String)] -> [(String, String)]
    forall a. a -> [a] -> [a]
    :[(String, String)]
    errs) [(String, Parser a)]
    ps
                                           in ByteString -> Result ByteString a
    p' ByteString
    ts
                               r :: Result ByteString a
    r@(Success ByteString
    _ a
    _)    -> Result ByteString a
    r
                               r :: Result ByteString a
    r@(Committed Result ByteString a
    _)    -> Result ByteString a
    r )
                showErr :: (String, String) -> String
    showErr (String
    name,String
    err) = String
    nameString -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    ":\n"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++Int -> String -> String
    indent Int
    2 String
    err

    instance Applicative Parser where
        pure :: forall a. a -> Parser a
    pure a
    x    = (ByteString -> Result ByteString a) -> Parser a
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (\ByteString
    ts-> ByteString -> a -> Result ByteString a
    forall z a. z -> a -> Result z a
    Success ByteString
    ts a
    x)
        Parser (a -> b)
    pf <*> :: forall a b. Parser (a -> b) -> Parser a -> Parser b
    <*> Parser a
    px = do { f <- Parser (a -> b)
    pf; x <- px; return (f x) }
    #if defined(GLASGOW_HASKELL) && GLASGOW_HASKELL > 610
        p  <*  q  = p `discard` q
    #endif

    instance Alternative Parser where
        empty :: forall a. Parser a
    empty     = String -> Parser a
    forall a. String -> Parser a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "no parse"
        Parser a
    p <|> :: forall a. Parser a -> Parser a -> Parser a
    <|> Parser a
    q   = Parser a
    p Parser a -> Parser a -> Parser a
    forall a. Parser a -> Parser a -> Parser a
    `onFail` Parser a
    q

    instance PolyParse Parser

    ------------------------------------------------------------------------

    -- | Simply return the next token in the input tokenstream.
    next :: Parser Char
    next :: Parser Char
    next = (ByteString -> Result ByteString Char) -> Parser Char
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (\ByteString
    bs-> case ByteString -> Maybe (Char, ByteString)
    BS.uncons ByteString
    bs of
                    Maybe (Char, ByteString)
    Nothing     -> ByteString -> String -> Result ByteString Char
    forall z a. z -> String -> Result z a
    Failure ByteString
    bs String
    "Ran out of input (EOF)"
                    Just (Char
    h, ByteString
    t) -> ByteString -> Char -> Result ByteString Char
    forall z a. z -> a -> Result z a
    Success ByteString
    t Char
    h )

    -- | Succeed if the end of file/input has been reached, fail otherwise.
    eof :: Parser ()
    eof :: Parser ()
    eof = (ByteString -> Result ByteString ()) -> Parser ()
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (\ByteString
    bs -> if ByteString -> Bool
    BS.null ByteString
    bs
                    then ByteString -> () -> Result ByteString ()
    forall z a. z -> a -> Result z a
    Success ByteString
    bs ()
                    else ByteString -> String -> Result ByteString ()
    forall z a. z -> String -> Result z a
    Failure ByteString
    bs String
    "Expected end of input (EOF)" )

    -- | Return the next token if it satisfies the given predicate.
    satisfy :: (Char -> Bool) -> Parser Char
    satisfy :: (Char -> Bool) -> Parser Char
    satisfy Char -> Bool
    f = do { x <- Parser Char
    next
                   ; if f x then return x else fail "Parse.satisfy: failed"
                   }

    -- | @p `onFail` q@ means parse p, unless p fails, in which case
    --   parse q instead.
    --   Can be chained together to give multiple attempts to parse something.
    --   (Note that q could itself be a failing parser, e.g. to change the error
    --   message from that defined in p to something different.)
    --   However, a severe failure in p cannot be ignored.
    onFail :: Parser a -> Parser a -> Parser a
    (P ByteString -> Result ByteString a
    p) onFail :: forall a. Parser a -> Parser a -> Parser a
    `onFail` (P ByteString -> Result ByteString a
    q) = (ByteString -> Result ByteString a) -> Parser a
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (\ByteString
    ts-> ByteString -> Result ByteString a -> Result ByteString a
    continue ByteString
    ts (Result ByteString a -> Result ByteString a)
    -> Result ByteString a -> Result ByteString a
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Result ByteString a
    p ByteString
    ts)
      where continue :: ByteString -> Result ByteString a -> Result ByteString a
    continue ByteString
    ts (Failure ByteString
    _ String
    _) = ByteString -> Result ByteString a
    q ByteString
    ts
        --  continue _  (Committed r) = r   -- no, remain Committed
            continue ByteString
    _  Result ByteString a
    r             = Result ByteString a
    r

    ------------------------------------------------------------------------

    -- | @manySatisfy p@ is a more efficient fused version of @many (satisfy p)@
    manySatisfy :: (Char->Bool) -> Parser ByteString
    manySatisfy :: (Char -> Bool) -> Parser ByteString
    manySatisfy Char -> Bool
    f = (ByteString -> Result ByteString ByteString) -> Parser ByteString
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (\ByteString
    bs-> let (ByteString
    pre,ByteString
    suf) = (Char -> Bool) -> ByteString -> (ByteString, ByteString)
    BS.span Char -> Bool
    f ByteString
    bs in ByteString -> ByteString -> Result ByteString ByteString
    forall z a. z -> a -> Result z a
    Success ByteString
    suf ByteString
    pre)

    -- | @many1Satisfy p@ is a more efficient fused version of @many1 (satisfy p)@
    many1Satisfy :: (Char->Bool) -> Parser ByteString
    many1Satisfy :: (Char -> Bool) -> Parser ByteString
    many1Satisfy Char -> Bool
    f = do x <- (Char -> Bool) -> Parser ByteString
    manySatisfy Char -> Bool
    f
                        if BS.null x then fail "Parse.many1Satisfy: failed"
                                     else return x

    ------------------------------------------------------------------------

    -- | Push some tokens back onto the front of the input stream and reparse.
    --   This is useful e.g. for recursively expanding macros.  When the
    --   user-parser recognises a macro use, it can lookup the macro
    --   expansion from the parse state, lex it, and then stuff the
    --   lexed expansion back down into the parser.
    reparse    :: ByteString -> Parser ()
    reparse :: ByteString -> Parser ()
    reparse ByteString
    ts  = (ByteString -> Result ByteString ()) -> Parser ()
    forall a. (ByteString -> Result ByteString a) -> Parser a
    P (\ByteString
    inp-> ByteString -> () -> Result ByteString ()
    forall z a. z -> a -> Result z a
    Success (ByteString
    ts ByteString -> ByteString -> ByteString
    `BS.append` ByteString
    inp) ())

    ------------------------------------------------------------------------