    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE Safe #-}

    -- |
    -- Module      :  Text.Megaparsec.Common
    -- Copyright   :  © 2018–present Megaparsec contributors
    -- License     :  FreeBSD
    --
    -- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- Common token combinators. This module is not public, the functions from
    -- it are re-exported in "Text.Megaparsec.Byte" and "Text.Megaparsec.Char".
    --
    -- @since 7.0.0
    module Text.Megaparsec.Lexer
      ( -- * White space
        space,
        lexeme,
        symbol,
        symbol',
      )
    where

    import qualified Data.CaseInsensitive as CI
    import Text.Megaparsec
    import Text.Megaparsec.Common

    ----------------------------------------------------------------------------
    -- White space

    -- | @'space' sc lineComment blockComment@ produces a parser that can parse
    -- white space in general. It's expected that you create such a parser once
    -- and pass it to other functions in this module as needed (when you see
    -- @spaceConsumer@ in documentation, usually it means that something like
    -- 'space' is expected there).
    --
    -- @sc@ is used to parse blocks of space characters. You can use
    -- 'Text.Megaparsec.Char.space1' from "Text.Megaparsec.Char" for this
    -- purpose as well as your own parser (if you don't want to automatically
    -- consume newlines, for example). Make sure that the parser does not
    -- succeed on the empty input though. In an earlier version of the library
    -- 'Text.Megaparsec.Char.spaceChar' was recommended, but now parsers based
    -- on 'takeWhile1P' are preferred because of their speed.
    --
    -- @lineComment@ is used to parse line comments. You can use
    -- @skipLineComment@ if you don't need anything special.
    --
    -- @blockComment@ is used to parse block (multi-line) comments. You can use
    -- @skipBlockComment@ or @skipBlockCommentNested@ if you don't need anything
    -- special.
    --
    -- If you don't want to allow a kind of comment, simply pass 'empty' which
    -- will fail instantly when parsing of that sort of comment is attempted and
    -- 'space' will just move on or finish depending on whether there is more
    -- white space for it to consume.
    space ::
      (MonadParsec e s m) =>
      -- | A parser for space characters which does not accept empty
      -- input (e.g. 'Text.Megaparsec.Char.space1')
      m () ->
      -- | A parser for a line comment (e.g. 'skipLineComment')
      m () ->
      -- | A parser for a block comment (e.g. 'skipBlockComment')
      m () ->
      m ()
    space :: forall e s (m :: * -> *).
    MonadParsec e s m =>
    m () -> m () -> m () -> m ()
    space m ()
    sp m ()
    line m ()
    block =
      m () -> m ()
    forall (m :: * -> *) a. MonadPlus m => m a -> m ()
    skipMany (m () -> m ()) -> m () -> m ()
    forall a b. (a -> b) -> a -> b
    $
        [m ()] -> m ()
    forall (f :: * -> *) (m :: * -> *) a.
    (Foldable f, Alternative m) =>
    f (m a) -> m a
    choice
          [m () -> m ()
    forall a. m a -> m a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    hidden m ()
    sp, m () -> m ()
    forall a. m a -> m a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    hidden m ()
    line, m () -> m ()
    forall a. m a -> m a
    forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
    hidden m ()
    block]
    {-# INLINEABLE space #-}

    -- | This is a wrapper for lexemes. The typical usage is to supply the first
    -- argument (parser that consumes white space, probably defined via 'space')
    -- and use the resulting function to wrap parsers for every lexeme.
    --
    -- > lexeme  = L.lexeme spaceConsumer
    -- > integer = lexeme L.decimal
    lexeme ::
      (MonadParsec e s m) =>
      -- | How to consume white space after lexeme
      m () ->
      -- | How to parse actual lexeme
      m a ->
      m a
    lexeme :: forall e s (m :: * -> *) a. MonadParsec e s m => m () -> m a -> m a
    lexeme m ()
    spc m a
    p = m a
    p m a -> m () -> m a
    forall a b. m a -> m b -> m a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* m ()
    spc
    {-# INLINEABLE lexeme #-}

    -- | This is a helper to parse symbols, i.e. verbatim strings. You pass the
    -- first argument (parser that consumes white space, probably defined via
    -- 'space') and then you can use the resulting function to parse strings:
    --
    -- > symbol    = L.symbol spaceConsumer
    -- >
    -- > parens    = between (symbol "(") (symbol ")")
    -- > braces    = between (symbol "{") (symbol "}")
    -- > angles    = between (symbol "<") (symbol ">")
    -- > brackets  = between (symbol "[") (symbol "]")
    -- > semicolon = symbol ";"
    -- > comma     = symbol ","
    -- > colon     = symbol ":"
    -- > dot       = symbol "."
    symbol ::
      (MonadParsec e s m) =>
      -- | How to consume white space after lexeme
      m () ->
      -- | Symbol to parse
      Tokens s ->
      m (Tokens s)
    symbol :: forall e s (m :: * -> *).
    MonadParsec e s m =>
    m () -> Tokens s -> m (Tokens s)
    symbol m ()
    spc = m () -> m (Tokens s) -> m (Tokens s)
    forall e s (m :: * -> *) a. MonadParsec e s m => m () -> m a -> m a
    lexeme m ()
    spc (m (Tokens s) -> m (Tokens s))
    -> (Tokens s -> m (Tokens s)) -> Tokens s -> m (Tokens s)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Tokens s -> m (Tokens s)
    forall e s (m :: * -> *).
    MonadParsec e s m =>
    Tokens s -> m (Tokens s)
    string
    {-# INLINEABLE symbol #-}

    -- | A case-insensitive version of 'symbol'. This may be helpful if you're
    -- working with case-insensitive languages.
    symbol' ::
      (MonadParsec e s m, CI.FoldCase (Tokens s)) =>
      -- | How to consume white space after lexeme
      m () ->
      -- | Symbol to parse (case-insensitive)
      Tokens s ->
      m (Tokens s)
    symbol' :: forall e s (m :: * -> *).
    (MonadParsec e s m, FoldCase (Tokens s)) =>
    m () -> Tokens s -> m (Tokens s)
    symbol' m ()
    spc = m () -> m (Tokens s) -> m (Tokens s)
    forall e s (m :: * -> *) a. MonadParsec e s m => m () -> m a -> m a
    lexeme m ()
    spc (m (Tokens s) -> m (Tokens s))
    -> (Tokens s -> m (Tokens s)) -> Tokens s -> m (Tokens s)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Tokens s -> m (Tokens s)
    forall e s (m :: * -> *).
    (MonadParsec e s m, FoldCase (Tokens s)) =>
    Tokens s -> m (Tokens s)
    string'
    {-# INLINEABLE symbol' #-}