-- |
-- Module      :  Text.Megaparsec.Error
-- Copyright   :  © 2015–present Megaparsec contributors
-- License     :  FreeBSD
--
-- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
-- Stability   :  experimental
-- Portability :  portable
--
-- Parse errors. The current version of Megaparsec supports well-typed
-- errors instead of 'String'-based ones. This gives a lot of flexibility in
-- describing what exactly went wrong as well as a way to return arbitrary
-- data in case of failure.
--
-- You probably do not want to import this module directly because
-- "Text.Megaparsec" re-exports it anyway.

{-# LANGUAGE BangPatterns         #-}
{-# LANGUAGE DeriveDataTypeable   #-}
{-# LANGUAGE DeriveFunctor        #-}
{-# LANGUAGE DeriveGeneric        #-}
{-# LANGUAGE FlexibleContexts     #-}
{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE LambdaCase           #-}
{-# LANGUAGE RecordWildCards      #-}
{-# LANGUAGE ScopedTypeVariables  #-}
{-# LANGUAGE StandaloneDeriving   #-}
{-# LANGUAGE UndecidableInstances #-}

module Text.Megaparsec.Error
  ( -- * Parse error type
    ErrorItem (..)
  , ErrorFancy (..)
  , ParseError (..)
  , mapParseError
  , errorOffset
  , setErrorOffset
  , ParseErrorBundle (..)
  , attachSourcePos
    -- * Pretty-printing
  , ShowErrorComponent (..)
  , errorBundlePretty
  , parseErrorPretty
  , parseErrorTextPretty )
where

import Control.DeepSeq
import Control.Exception
import Control.Monad.State.Strict
import Data.Data (Data)
import Data.List (intercalate)
import Data.List.NonEmpty (NonEmpty (..))
import Data.Maybe (isNothing)
import Data.Proxy
import Data.Set (Set)
import Data.Typeable (Typeable)
import Data.Void
import GHC.Generics
import Text.Megaparsec.Pos
import Text.Megaparsec.State
import Text.Megaparsec.Stream
import qualified Data.List.NonEmpty as NE
import qualified Data.Set           as E

----------------------------------------------------------------------------
-- Parse error type

-- | Data type that is used to represent “unexpected\/expected” items in
-- 'ParseError'. The data type is parametrized over the token type @t@.
--
-- @since 5.0.0

data ErrorItem t
  = Tokens (NonEmpty t)      -- ^ Non-empty stream of tokens
  | Label (NonEmpty Char)    -- ^ Label (cannot be empty)
  | EndOfInput               -- ^ End of input
  deriving (Int -> ErrorItem t -> ShowS
[ErrorItem t] -> ShowS
ErrorItem t -> String
(Int -> ErrorItem t -> ShowS)
-> (ErrorItem t -> String)
-> ([ErrorItem t] -> ShowS)
-> Show (ErrorItem t)
forall t. Show t => Int -> ErrorItem t -> ShowS
forall t. Show t => [ErrorItem t] -> ShowS
forall t. Show t => ErrorItem t -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ErrorItem t] -> ShowS
$cshowList :: forall t. Show t => [ErrorItem t] -> ShowS
show :: ErrorItem t -> String
$cshow :: forall t. Show t => ErrorItem t -> String
showsPrec :: Int -> ErrorItem t -> ShowS
$cshowsPrec :: forall t. Show t => Int -> ErrorItem t -> ShowS
Show, ReadPrec [ErrorItem t]
ReadPrec (ErrorItem t)
Int -> ReadS (ErrorItem t)
ReadS [ErrorItem t]
(Int -> ReadS (ErrorItem t))
-> ReadS [ErrorItem t]
-> ReadPrec (ErrorItem t)
-> ReadPrec [ErrorItem t]
-> Read (ErrorItem t)
forall t. Read t => ReadPrec [ErrorItem t]
forall t. Read t => ReadPrec (ErrorItem t)
forall t. Read t => Int -> ReadS (ErrorItem t)
forall t. Read t => ReadS [ErrorItem t]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ErrorItem t]
$creadListPrec :: forall t. Read t => ReadPrec [ErrorItem t]
readPrec :: ReadPrec (ErrorItem t)
$creadPrec :: forall t. Read t => ReadPrec (ErrorItem t)
readList :: ReadS [ErrorItem t]
$creadList :: forall t. Read t => ReadS [ErrorItem t]
readsPrec :: Int -> ReadS (ErrorItem t)
$creadsPrec :: forall t. Read t => Int -> ReadS (ErrorItem t)
Read, ErrorItem t -> ErrorItem t -> Bool
(ErrorItem t -> ErrorItem t -> Bool)
-> (ErrorItem t -> ErrorItem t -> Bool) -> Eq (ErrorItem t)
forall t. Eq t => ErrorItem t -> ErrorItem t -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ErrorItem t -> ErrorItem t -> Bool
$c/= :: forall t. Eq t => ErrorItem t -> ErrorItem t -> Bool
== :: ErrorItem t -> ErrorItem t -> Bool
$c== :: forall t. Eq t => ErrorItem t -> ErrorItem t -> Bool
Eq, Eq (ErrorItem t)
Eq (ErrorItem t) =>
(ErrorItem t -> ErrorItem t -> Ordering)
-> (ErrorItem t -> ErrorItem t -> Bool)
-> (ErrorItem t -> ErrorItem t -> Bool)
-> (ErrorItem t -> ErrorItem t -> Bool)
-> (ErrorItem t -> ErrorItem t -> Bool)
-> (ErrorItem t -> ErrorItem t -> ErrorItem t)
-> (ErrorItem t -> ErrorItem t -> ErrorItem t)
-> Ord (ErrorItem t)
ErrorItem t -> ErrorItem t -> Bool
ErrorItem t -> ErrorItem t -> Ordering
ErrorItem t -> ErrorItem t -> ErrorItem t
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall t. Ord t => Eq (ErrorItem t)
forall t. Ord t => ErrorItem t -> ErrorItem t -> Bool
forall t. Ord t => ErrorItem t -> ErrorItem t -> Ordering
forall t. Ord t => ErrorItem t -> ErrorItem t -> ErrorItem t
min :: ErrorItem t -> ErrorItem t -> ErrorItem t
$cmin :: forall t. Ord t => ErrorItem t -> ErrorItem t -> ErrorItem t
max :: ErrorItem t -> ErrorItem t -> ErrorItem t
$cmax :: forall t. Ord t => ErrorItem t -> ErrorItem t -> ErrorItem t
>= :: ErrorItem t -> ErrorItem t -> Bool
$c>= :: forall t. Ord t => ErrorItem t -> ErrorItem t -> Bool
> :: ErrorItem t -> ErrorItem t -> Bool
$c> :: forall t. Ord t => ErrorItem t -> ErrorItem t -> Bool
<= :: ErrorItem t -> ErrorItem t -> Bool
$c<= :: forall t. Ord t => ErrorItem t -> ErrorItem t -> Bool
< :: ErrorItem t -> ErrorItem t -> Bool
$c< :: forall t. Ord t => ErrorItem t -> ErrorItem t -> Bool
compare :: ErrorItem t -> ErrorItem t -> Ordering
$ccompare :: forall t. Ord t => ErrorItem t -> ErrorItem t -> Ordering
$cp1Ord :: forall t. Ord t => Eq (ErrorItem t)
Ord, Typeable (ErrorItem t)
Constr
DataType
Typeable (ErrorItem t) =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> ErrorItem t -> c (ErrorItem t))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (ErrorItem t))
-> (ErrorItem t -> Constr)
-> (ErrorItem t -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (ErrorItem t)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (ErrorItem t)))
-> ((forall b. Data b => b -> b) -> ErrorItem t -> ErrorItem t)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r)
-> (forall u. (forall d. Data d => d -> u) -> ErrorItem t -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ErrorItem t -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t))
-> Data (ErrorItem t)
ErrorItem t -> Constr
ErrorItem t -> DataType
(forall d. Data d => c (t d)) -> Maybe (c (ErrorItem t))
(forall b. Data b => b -> b) -> ErrorItem t -> ErrorItem t
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorItem t -> c (ErrorItem t)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorItem t)
forall t. Data t => Typeable (ErrorItem t)
forall t. Data t => ErrorItem t -> Constr
forall t. Data t => ErrorItem t -> DataType
forall t.
Data t =>
(forall b. Data b => b -> b) -> ErrorItem t -> ErrorItem t
forall t u.
Data t =>
Int -> (forall d. Data d => d -> u) -> ErrorItem t -> u
forall t u.
Data t =>
(forall d. Data d => d -> u) -> ErrorItem t -> [u]
forall t r r'.
Data t =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r
forall t r r'.
Data t =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r
forall t (m :: * -> *).
(Data t, Monad m) =>
(forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
forall t (m :: * -> *).
(Data t, MonadPlus m) =>
(forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
forall t (c :: * -> *).
Data t =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorItem t)
forall t (c :: * -> *).
Data t =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorItem t -> c (ErrorItem t)
forall t (t :: * -> *) (c :: * -> *).
(Data t, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (ErrorItem t))
forall t (t :: * -> * -> *) (c :: * -> *).
(Data t, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (ErrorItem t))
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ErrorItem t -> u
forall u. (forall d. Data d => d -> u) -> ErrorItem t -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorItem t)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorItem t -> c (ErrorItem t)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (ErrorItem t))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (ErrorItem t))
$cEndOfInput :: Constr
$cLabel :: Constr
$cTokens :: Constr
$tErrorItem :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
$cgmapMo :: forall t (m :: * -> *).
(Data t, MonadPlus m) =>
(forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
gmapMp :: (forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
$cgmapMp :: forall t (m :: * -> *).
(Data t, MonadPlus m) =>
(forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
gmapM :: (forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
$cgmapM :: forall t (m :: * -> *).
(Data t, Monad m) =>
(forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t)
gmapQi :: Int -> (forall d. Data d => d -> u) -> ErrorItem t -> u
$cgmapQi :: forall t u.
Data t =>
Int -> (forall d. Data d => d -> u) -> ErrorItem t -> u
gmapQ :: (forall d. Data d => d -> u) -> ErrorItem t -> [u]
$cgmapQ :: forall t u.
Data t =>
(forall d. Data d => d -> u) -> ErrorItem t -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r
$cgmapQr :: forall t r r'.
Data t =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r
$cgmapQl :: forall t r r'.
Data t =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r
gmapT :: (forall b. Data b => b -> b) -> ErrorItem t -> ErrorItem t
$cgmapT :: forall t.
Data t =>
(forall b. Data b => b -> b) -> ErrorItem t -> ErrorItem t
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (ErrorItem t))
$cdataCast2 :: forall t (t :: * -> * -> *) (c :: * -> *).
(Data t, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (ErrorItem t))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (ErrorItem t))
$cdataCast1 :: forall t (t :: * -> *) (c :: * -> *).
(Data t, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (ErrorItem t))
dataTypeOf :: ErrorItem t -> DataType
$cdataTypeOf :: forall t. Data t => ErrorItem t -> DataType
toConstr :: ErrorItem t -> Constr
$ctoConstr :: forall t. Data t => ErrorItem t -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorItem t)
$cgunfold :: forall t (c :: * -> *).
Data t =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorItem t)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorItem t -> c (ErrorItem t)
$cgfoldl :: forall t (c :: * -> *).
Data t =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorItem t -> c (ErrorItem t)
$cp1Data :: forall t. Data t => Typeable (ErrorItem t)
Data, Typeable, (forall x. ErrorItem t -> Rep (ErrorItem t) x)
-> (forall x. Rep (ErrorItem t) x -> ErrorItem t)
-> Generic (ErrorItem t)
forall x. Rep (ErrorItem t) x -> ErrorItem t
forall x. ErrorItem t -> Rep (ErrorItem t) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall t x. Rep (ErrorItem t) x -> ErrorItem t
forall t x. ErrorItem t -> Rep (ErrorItem t) x
$cto :: forall t x. Rep (ErrorItem t) x -> ErrorItem t
$cfrom :: forall t x. ErrorItem t -> Rep (ErrorItem t) x
Generic, a -> ErrorItem b -> ErrorItem a
(a -> b) -> ErrorItem a -> ErrorItem b
(forall a b. (a -> b) -> ErrorItem a -> ErrorItem b)
-> (forall a b. a -> ErrorItem b -> ErrorItem a)
-> Functor ErrorItem
forall a b. a -> ErrorItem b -> ErrorItem a
forall a b. (a -> b) -> ErrorItem a -> ErrorItem b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> ErrorItem b -> ErrorItem a
$c<$ :: forall a b. a -> ErrorItem b -> ErrorItem a
fmap :: (a -> b) -> ErrorItem a -> ErrorItem b
$cfmap :: forall a b. (a -> b) -> ErrorItem a -> ErrorItem b
Functor)

instance NFData t => NFData (ErrorItem t)

-- | Additional error data, extendable by user. When no custom data is
-- necessary, the type is typically indexed by 'Void' to “cancel” the
-- 'ErrorCustom' constructor.
--
-- @since 6.0.0

data ErrorFancy e
  = ErrorFail String
    -- ^ 'fail' has been used in parser monad
  | ErrorIndentation Ordering Pos Pos
    -- ^ Incorrect indentation error: desired ordering between reference
    -- level and actual level, reference indentation level, actual
    -- indentation level
  | ErrorCustom e
    -- ^ Custom error data
  deriving (Int -> ErrorFancy e -> ShowS
[ErrorFancy e] -> ShowS
ErrorFancy e -> String
(Int -> ErrorFancy e -> ShowS)
-> (ErrorFancy e -> String)
-> ([ErrorFancy e] -> ShowS)
-> Show (ErrorFancy e)
forall e. Show e => Int -> ErrorFancy e -> ShowS
forall e. Show e => [ErrorFancy e] -> ShowS
forall e. Show e => ErrorFancy e -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ErrorFancy e] -> ShowS
$cshowList :: forall e. Show e => [ErrorFancy e] -> ShowS
show :: ErrorFancy e -> String
$cshow :: forall e. Show e => ErrorFancy e -> String
showsPrec :: Int -> ErrorFancy e -> ShowS
$cshowsPrec :: forall e. Show e => Int -> ErrorFancy e -> ShowS
Show, ReadPrec [ErrorFancy e]
ReadPrec (ErrorFancy e)
Int -> ReadS (ErrorFancy e)
ReadS [ErrorFancy e]
(Int -> ReadS (ErrorFancy e))
-> ReadS [ErrorFancy e]
-> ReadPrec (ErrorFancy e)
-> ReadPrec [ErrorFancy e]
-> Read (ErrorFancy e)
forall e. Read e => ReadPrec [ErrorFancy e]
forall e. Read e => ReadPrec (ErrorFancy e)
forall e. Read e => Int -> ReadS (ErrorFancy e)
forall e. Read e => ReadS [ErrorFancy e]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ErrorFancy e]
$creadListPrec :: forall e. Read e => ReadPrec [ErrorFancy e]
readPrec :: ReadPrec (ErrorFancy e)
$creadPrec :: forall e. Read e => ReadPrec (ErrorFancy e)
readList :: ReadS [ErrorFancy e]
$creadList :: forall e. Read e => ReadS [ErrorFancy e]
readsPrec :: Int -> ReadS (ErrorFancy e)
$creadsPrec :: forall e. Read e => Int -> ReadS (ErrorFancy e)
Read, ErrorFancy e -> ErrorFancy e -> Bool
(ErrorFancy e -> ErrorFancy e -> Bool)
-> (ErrorFancy e -> ErrorFancy e -> Bool) -> Eq (ErrorFancy e)
forall e. Eq e => ErrorFancy e -> ErrorFancy e -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ErrorFancy e -> ErrorFancy e -> Bool
$c/= :: forall e. Eq e => ErrorFancy e -> ErrorFancy e -> Bool
== :: ErrorFancy e -> ErrorFancy e -> Bool
$c== :: forall e. Eq e => ErrorFancy e -> ErrorFancy e -> Bool
Eq, Eq (ErrorFancy e)
Eq (ErrorFancy e) =>
(ErrorFancy e -> ErrorFancy e -> Ordering)
-> (ErrorFancy e -> ErrorFancy e -> Bool)
-> (ErrorFancy e -> ErrorFancy e -> Bool)
-> (ErrorFancy e -> ErrorFancy e -> Bool)
-> (ErrorFancy e -> ErrorFancy e -> Bool)
-> (ErrorFancy e -> ErrorFancy e -> ErrorFancy e)
-> (ErrorFancy e -> ErrorFancy e -> ErrorFancy e)
-> Ord (ErrorFancy e)
ErrorFancy e -> ErrorFancy e -> Bool
ErrorFancy e -> ErrorFancy e -> Ordering
ErrorFancy e -> ErrorFancy e -> ErrorFancy e
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall e. Ord e => Eq (ErrorFancy e)
forall e. Ord e => ErrorFancy e -> ErrorFancy e -> Bool
forall e. Ord e => ErrorFancy e -> ErrorFancy e -> Ordering
forall e. Ord e => ErrorFancy e -> ErrorFancy e -> ErrorFancy e
min :: ErrorFancy e -> ErrorFancy e -> ErrorFancy e
$cmin :: forall e. Ord e => ErrorFancy e -> ErrorFancy e -> ErrorFancy e
max :: ErrorFancy e -> ErrorFancy e -> ErrorFancy e
$cmax :: forall e. Ord e => ErrorFancy e -> ErrorFancy e -> ErrorFancy e
>= :: ErrorFancy e -> ErrorFancy e -> Bool
$c>= :: forall e. Ord e => ErrorFancy e -> ErrorFancy e -> Bool
> :: ErrorFancy e -> ErrorFancy e -> Bool
$c> :: forall e. Ord e => ErrorFancy e -> ErrorFancy e -> Bool
<= :: ErrorFancy e -> ErrorFancy e -> Bool
$c<= :: forall e. Ord e => ErrorFancy e -> ErrorFancy e -> Bool
< :: ErrorFancy e -> ErrorFancy e -> Bool
$c< :: forall e. Ord e => ErrorFancy e -> ErrorFancy e -> Bool
compare :: ErrorFancy e -> ErrorFancy e -> Ordering
$ccompare :: forall e. Ord e => ErrorFancy e -> ErrorFancy e -> Ordering
$cp1Ord :: forall e. Ord e => Eq (ErrorFancy e)
Ord, Typeable (ErrorFancy e)
Constr
DataType
Typeable (ErrorFancy e) =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> ErrorFancy e -> c (ErrorFancy e))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (ErrorFancy e))
-> (ErrorFancy e -> Constr)
-> (ErrorFancy e -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (ErrorFancy e)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (ErrorFancy e)))
-> ((forall b. Data b => b -> b) -> ErrorFancy e -> ErrorFancy e)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r)
-> (forall u. (forall d. Data d => d -> u) -> ErrorFancy e -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ErrorFancy e -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e))
-> Data (ErrorFancy e)
ErrorFancy e -> Constr
ErrorFancy e -> DataType
(forall d. Data d => c (t d)) -> Maybe (c (ErrorFancy e))
(forall b. Data b => b -> b) -> ErrorFancy e -> ErrorFancy e
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorFancy e -> c (ErrorFancy e)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorFancy e)
forall e. Data e => Typeable (ErrorFancy e)
forall e. Data e => ErrorFancy e -> Constr
forall e. Data e => ErrorFancy e -> DataType
forall e.
Data e =>
(forall b. Data b => b -> b) -> ErrorFancy e -> ErrorFancy e
forall e u.
Data e =>
Int -> (forall d. Data d => d -> u) -> ErrorFancy e -> u
forall e u.
Data e =>
(forall d. Data d => d -> u) -> ErrorFancy e -> [u]
forall e r r'.
Data e =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r
forall e r r'.
Data e =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r
forall e (m :: * -> *).
(Data e, Monad m) =>
(forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
forall e (m :: * -> *).
(Data e, MonadPlus m) =>
(forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
forall e (c :: * -> *).
Data e =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorFancy e)
forall e (c :: * -> *).
Data e =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorFancy e -> c (ErrorFancy e)
forall e (t :: * -> *) (c :: * -> *).
(Data e, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (ErrorFancy e))
forall e (t :: * -> * -> *) (c :: * -> *).
(Data e, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (ErrorFancy e))
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ErrorFancy e -> u
forall u. (forall d. Data d => d -> u) -> ErrorFancy e -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorFancy e)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorFancy e -> c (ErrorFancy e)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (ErrorFancy e))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (ErrorFancy e))
$cErrorCustom :: Constr
$cErrorIndentation :: Constr
$cErrorFail :: Constr
$tErrorFancy :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
$cgmapMo :: forall e (m :: * -> *).
(Data e, MonadPlus m) =>
(forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
gmapMp :: (forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
$cgmapMp :: forall e (m :: * -> *).
(Data e, MonadPlus m) =>
(forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
gmapM :: (forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
$cgmapM :: forall e (m :: * -> *).
(Data e, Monad m) =>
(forall d. Data d => d -> m d) -> ErrorFancy e -> m (ErrorFancy e)
gmapQi :: Int -> (forall d. Data d => d -> u) -> ErrorFancy e -> u
$cgmapQi :: forall e u.
Data e =>
Int -> (forall d. Data d => d -> u) -> ErrorFancy e -> u
gmapQ :: (forall d. Data d => d -> u) -> ErrorFancy e -> [u]
$cgmapQ :: forall e u.
Data e =>
(forall d. Data d => d -> u) -> ErrorFancy e -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r
$cgmapQr :: forall e r r'.
Data e =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r
$cgmapQl :: forall e r r'.
Data e =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ErrorFancy e -> r
gmapT :: (forall b. Data b => b -> b) -> ErrorFancy e -> ErrorFancy e
$cgmapT :: forall e.
Data e =>
(forall b. Data b => b -> b) -> ErrorFancy e -> ErrorFancy e
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (ErrorFancy e))
$cdataCast2 :: forall e (t :: * -> * -> *) (c :: * -> *).
(Data e, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (ErrorFancy e))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (ErrorFancy e))
$cdataCast1 :: forall e (t :: * -> *) (c :: * -> *).
(Data e, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (ErrorFancy e))
dataTypeOf :: ErrorFancy e -> DataType
$cdataTypeOf :: forall e. Data e => ErrorFancy e -> DataType
toConstr :: ErrorFancy e -> Constr
$ctoConstr :: forall e. Data e => ErrorFancy e -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorFancy e)
$cgunfold :: forall e (c :: * -> *).
Data e =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (ErrorFancy e)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorFancy e -> c (ErrorFancy e)
$cgfoldl :: forall e (c :: * -> *).
Data e =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ErrorFancy e -> c (ErrorFancy e)
$cp1Data :: forall e. Data e => Typeable (ErrorFancy e)
Data, Typeable, (forall x. ErrorFancy e -> Rep (ErrorFancy e) x)
-> (forall x. Rep (ErrorFancy e) x -> ErrorFancy e)
-> Generic (ErrorFancy e)
forall x. Rep (ErrorFancy e) x -> ErrorFancy e
forall x. ErrorFancy e -> Rep (ErrorFancy e) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall e x. Rep (ErrorFancy e) x -> ErrorFancy e
forall e x. ErrorFancy e -> Rep (ErrorFancy e) x
$cto :: forall e x. Rep (ErrorFancy e) x -> ErrorFancy e
$cfrom :: forall e x. ErrorFancy e -> Rep (ErrorFancy e) x
Generic, a -> ErrorFancy b -> ErrorFancy a
(a -> b) -> ErrorFancy a -> ErrorFancy b
(forall a b. (a -> b) -> ErrorFancy a -> ErrorFancy b)
-> (forall a b. a -> ErrorFancy b -> ErrorFancy a)
-> Functor ErrorFancy
forall a b. a -> ErrorFancy b -> ErrorFancy a
forall a b. (a -> b) -> ErrorFancy a -> ErrorFancy b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> ErrorFancy b -> ErrorFancy a
$c<$ :: forall a b. a -> ErrorFancy b -> ErrorFancy a
fmap :: (a -> b) -> ErrorFancy a -> ErrorFancy b
$cfmap :: forall a b. (a -> b) -> ErrorFancy a -> ErrorFancy b
Functor)

instance NFData a => NFData (ErrorFancy a) where
  rnf :: ErrorFancy a -> ()
rnf (ErrorFail str :: String
str) = String -> ()
forall a. NFData a => a -> ()
rnf String
str
  rnf (ErrorIndentation ord :: Ordering
ord ref :: Pos
ref act :: Pos
act) = Ordering
ord Ordering -> () -> ()
forall a b. a -> b -> b
`seq` Pos -> ()
forall a. NFData a => a -> ()
rnf Pos
ref () -> () -> ()
forall a b. a -> b -> b
`seq` Pos -> ()
forall a. NFData a => a -> ()
rnf Pos
act
  rnf (ErrorCustom a :: a
a) = a -> ()
forall a. NFData a => a -> ()
rnf a
a

-- | @'ParseError' s e@ represents a parse error parametrized over the
-- stream type @s@ and the custom data @e@.
--
-- 'Semigroup' and 'Monoid' instances of the data type allow to merge parse
-- errors from different branches of parsing. When merging two
-- 'ParseError's, the longest match is preferred; if positions are the same,
-- custom data sets and collections of message items are combined. Note that
-- fancy errors take precedence over trivial errors in merging.
--
-- @since 7.0.0

data ParseError s e
  = TrivialError Int (Maybe (ErrorItem (Token s))) (Set (ErrorItem (Token s)))
    -- ^ Trivial errors, generated by Megaparsec's machinery. The data
    -- constructor includes the offset of error, unexpected token (if any),
    -- and expected tokens.
    --
    -- Type of the first argument was changed in the version /7.0.0/.
  | FancyError Int (Set (ErrorFancy e))
    -- ^ Fancy, custom errors.
    --
    -- Type of the first argument was changed in the version /7.0.0/.
  deriving (Typeable, (forall x. ParseError s e -> Rep (ParseError s e) x)
-> (forall x. Rep (ParseError s e) x -> ParseError s e)
-> Generic (ParseError s e)
forall x. Rep (ParseError s e) x -> ParseError s e
forall x. ParseError s e -> Rep (ParseError s e) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall s e x. Rep (ParseError s e) x -> ParseError s e
forall s e x. ParseError s e -> Rep (ParseError s e) x
$cto :: forall s e x. Rep (ParseError s e) x -> ParseError s e
$cfrom :: forall s e x. ParseError s e -> Rep (ParseError s e) x
Generic)

deriving instance ( Show (Token s)
                  , Show e
                  ) => Show (ParseError s e)

deriving instance ( Eq (Token s)
                  , Eq e
                  ) => Eq (ParseError s e)

deriving instance ( Data s
                  , Data (Token s)
                  , Ord (Token s)
                  , Data e
                  , Ord e
                  ) => Data (ParseError s e)

instance ( NFData (Token s)
         , NFData e
         ) => NFData (ParseError s e)

instance (Stream s, Ord e) => Semigroup (ParseError s e) where
  <> :: ParseError s e -> ParseError s e -> ParseError s e
(<>) = ParseError s e -> ParseError s e -> ParseError s e
forall s e.
(Stream s, Ord e) =>
ParseError s e -> ParseError s e -> ParseError s e
mergeError
  {-# INLINE (<>) #-}

instance (Stream s, Ord e) => Monoid (ParseError s e) where
  mempty :: ParseError s e
mempty  = Int
-> Maybe (ErrorItem (Token s))
-> Set (ErrorItem (Token s))
-> ParseError s e
forall s e.
Int
-> Maybe (ErrorItem (Token s))
-> Set (ErrorItem (Token s))
-> ParseError s e
TrivialError 0 Maybe (ErrorItem (Token s))
forall a. Maybe a
Nothing Set (ErrorItem (Token s))
forall a. Set a
E.empty
  mappend :: ParseError s e -> ParseError s e -> ParseError s e
mappend = ParseError s e -> ParseError s e -> ParseError s e
forall a. Semigroup a => a -> a -> a
(<>)
  {-# INLINE mappend #-}

instance ( Show s
         , Show (Token s)
         , Show e
         , ShowErrorComponent e
         , Stream s
         , Typeable s
         , Typeable e )
  => Exception (ParseError s e) where
  displayException :: ParseError s e -> String
displayException = ParseError s e -> String
forall s e.
(Stream s, ShowErrorComponent e) =>
ParseError s e -> String
parseErrorPretty

-- | Modify the custom data component in a parse error. This could be done
-- via 'fmap' if not for the 'Ord' constraint.
--
-- @since 7.0.0

mapParseError :: Ord e'
  => (e -> e')
  -> ParseError s e
  -> ParseError s e'
mapParseError :: (e -> e') -> ParseError s e -> ParseError s e'
mapParseError _ (TrivialError o :: Int
o u :: Maybe (ErrorItem (Token s))
u p :: Set (ErrorItem (Token s))
p) = Int
-> Maybe (ErrorItem (Token s))
-> Set (ErrorItem (Token s))
-> ParseError s e'
forall s e.
Int
-> Maybe (ErrorItem (Token s))
-> Set (ErrorItem (Token s))
-> ParseError s e
TrivialError Int
o Maybe (ErrorItem (Token s))
u Set (ErrorItem (Token s))
p
mapParseError f :: e -> e'
f (FancyError o :: Int
o x :: Set (ErrorFancy e)
x) = Int -> Set (ErrorFancy e') -> ParseError s e'
forall s e. Int -> Set (ErrorFancy e) -> ParseError s e
FancyError Int
o ((ErrorFancy e -> ErrorFancy e')
-> Set (ErrorFancy e) -> Set (ErrorFancy e')
forall b a. Ord b => (a -> b) -> Set a -> Set b
E.map ((e -> e') -> ErrorFancy e -> ErrorFancy e'
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap e -> e'
f) Set (ErrorFancy e)
x)

-- | Get offset of 'ParseError'.
--
-- @since 7.0.0

errorOffset :: ParseError s e -> Int
errorOffset :: ParseError s e -> Int
errorOffset (TrivialError o :: Int
o _ _) = Int
o
errorOffset (FancyError   o :: Int
o _)   = Int
o

-- | Set offset of 'ParseError'.
--
-- @since 8.0.0

setErrorOffset :: Int -> ParseError s e -> ParseError s e
setErrorOffset :: Int -> ParseError s e -> ParseError s e
setErrorOffset o :: Int
o (TrivialError _ u :: Maybe (ErrorItem (Token s))
u p :: Set (ErrorItem (Token s))
p) = Int
-> Maybe (ErrorItem (Token s))
-> Set (ErrorItem (Token s))
-> ParseError s e
forall s e.
Int
-> Maybe (ErrorItem (Token s))
-> Set (ErrorItem (Token s))
-> ParseError s e
TrivialError Int
o Maybe (ErrorItem (Token s))
u Set (ErrorItem (Token s))
p
setErrorOffset o :: Int
o (FancyError _ x :: Set (ErrorFancy e)
x) = Int -> Set (ErrorFancy e) -> ParseError s e
forall s e. Int -> Set (ErrorFancy e) -> ParseError s e
FancyError Int
o Set (ErrorFancy e)
x

-- | Merge two error data structures into one joining their collections of
-- message items and preferring the longest match. In other words, earlier
-- error message is discarded. This may seem counter-intuitive, but
-- 'mergeError' is only used to merge error messages of alternative branches
-- of parsing and in this case longest match should be preferred.

mergeError :: (Stream s, Ord e)
  => ParseError s e
  -> ParseError s e
  -> ParseError s e
mergeError :: ParseError s e -> ParseError s e -> ParseError s e
mergeError e1 :: ParseError s e
e1 e2 :: ParseError s e
e2 =
  case ParseError s e -> Int
forall s e. ParseError s e -> Int
errorOffset ParseError s e
e1 Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` ParseError s e -> Int
forall s e. ParseError s e -> Int
errorOffset ParseError s e
e2 of
    LT -> ParseError s e
e2
    EQ ->
      case (ParseError s e
e1, ParseError s e
e2) of
        (TrivialError s1 :: Int
s1 u1 :: Maybe (ErrorItem (Token s))
u1 p1 :: Set (ErrorItem (Token s))
p1, TrivialError _ u2 :: Maybe (ErrorItem (Token s))
u2 p2 :: Set (ErrorItem (Token s))
p2) ->
          Int
-> Maybe (ErrorItem (Token s))
-> Set (ErrorItem (Token s))
-> ParseError s e
forall s e.
Int
-> Maybe (ErrorItem (Token s))
-> Set (ErrorItem (Token s))
-> ParseError s e
TrivialError Int
s1 (Maybe (ErrorItem (Token s))
-> Maybe (ErrorItem (Token s)) -> Maybe (ErrorItem (Token s))
forall a. Ord a => Maybe a -> Maybe a -> Maybe a
n Maybe (ErrorItem (Token s))
u1 Maybe (ErrorItem (Token s))
u2) (Set (ErrorItem (Token s))
-> Set (ErrorItem (Token s)) -> Set (ErrorItem (Token s))
forall a. Ord a => Set a -> Set a -> Set a
E.union Set (ErrorItem (Token s))
p1 Set (ErrorItem (Token s))
p2)
        (FancyError {}, TrivialError {}) -> ParseError s e
e1
        (TrivialError {}, FancyError {}) -> ParseError s e
e2
        (FancyError s1 :: Int
s1 x1 :: Set (ErrorFancy e)
x1, FancyError _ x2 :: Set (ErrorFancy e)
x2) ->
          Int -> Set (ErrorFancy e) -> ParseError s e
forall s e. Int -> Set (ErrorFancy e) -> ParseError s e
FancyError Int
s1 (Set (ErrorFancy e) -> Set (ErrorFancy e) -> Set (ErrorFancy e)
forall a. Ord a => Set a -> Set a -> Set a
E.union Set (ErrorFancy e)
x1 Set (ErrorFancy e)
x2)
    GT -> ParseError s e
e1
  where
    -- NOTE The logic behind this merging is that since we only combine
    -- parse errors that happen at exactly the same position, all the
    -- unexpected items will be prefixes of input stream at that position or
    -- labels referring to the same thing. Our aim here is to choose the
    -- longest prefix (merging with labels and end of input is somewhat
    -- arbitrary, but is necessary because otherwise we can't make
    -- ParseError lawful Monoid and have nice parse errors at the same
    -- time).
    n :: Maybe a -> Maybe a -> Maybe a
n Nothing  Nothing = Maybe a
forall a. Maybe a
Nothing
    n (Just x :: a
x) Nothing = a -> Maybe a
forall a. a -> Maybe a
Just a
x
    n Nothing (Just y :: a
y) = a -> Maybe a
forall a. a -> Maybe a
Just a
y
    n (Just x :: a
x) (Just y :: a
y) = a -> Maybe a
forall a. a -> Maybe a
Just (a -> a -> a
forall a. Ord a => a -> a -> a
max a
x a
y)
{-# INLINE mergeError #-}

-- | A non-empty collection of 'ParseError's equipped with 'PosState' that
-- allows to pretty-print the errors efficiently and correctly.
--
-- @since 7.0.0

data ParseErrorBundle s e = ParseErrorBundle
  { ParseErrorBundle s e -> NonEmpty (ParseError s e)
bundleErrors :: NonEmpty (ParseError s e)
    -- ^ A collection of 'ParseError's that is sorted by parse error offsets
  , ParseErrorBundle s e -> PosState s
bundlePosState :: PosState s
    -- ^ State that is used for line\/column calculation
  } deriving ((forall x. ParseErrorBundle s e -> Rep (ParseErrorBundle s e) x)
-> (forall x. Rep (ParseErrorBundle s e) x -> ParseErrorBundle s e)
-> Generic (ParseErrorBundle s e)
forall x. Rep (ParseErrorBundle s e) x -> ParseErrorBundle s e
forall x. ParseErrorBundle s e -> Rep (ParseErrorBundle s e) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall s e x. Rep (ParseErrorBundle s e) x -> ParseErrorBundle s e
forall s e x. ParseErrorBundle s e -> Rep (ParseErrorBundle s e) x
$cto :: forall s e x. Rep (ParseErrorBundle s e) x -> ParseErrorBundle s e
$cfrom :: forall s e x. ParseErrorBundle s e -> Rep (ParseErrorBundle s e) x
Generic)

deriving instance ( Show s
                  , Show (Token s)
                  , Show e
                  ) => Show (ParseErrorBundle s e)

deriving instance ( Eq s
                  , Eq (Token s)
                  , Eq e
                  ) => Eq (ParseErrorBundle s e)

deriving instance ( Typeable s
                  , Typeable (Token s)
                  , Typeable e
                  ) => Typeable (ParseErrorBundle s e)

deriving instance ( Data s
                  , Data (Token s)
                  , Ord (Token s)
                  , Data e
                  , Ord e
                  ) => Data (ParseErrorBundle s e)

instance ( NFData s
         , NFData (Token s)
         , NFData e
         ) => NFData (ParseErrorBundle s e)

instance ( Show s
         , Show (Token s)
         , Show e
         , ShowErrorComponent e
         , Stream s
         , Typeable s
         , Typeable e
         ) => Exception (ParseErrorBundle s e) where
  displayException :: ParseErrorBundle s e -> String
displayException = ParseErrorBundle s e -> String
forall s e.
(Stream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty

-- | Attach 'SourcePos'es to items in a 'Traversable' container given that
-- there is a projection allowing to get an offset per item.
--
-- Items must be in ascending order with respect to their offsets.
--
-- @since 7.0.0

attachSourcePos
  :: (Traversable t, Stream s)
  => (a -> Int) -- ^ How to project offset from an item (e.g. 'errorOffset')
  -> t a               -- ^ The collection of items
  -> PosState s        -- ^ Initial 'PosState'
  -> (t (a, SourcePos), PosState s) -- ^ The collection with 'SourcePos'es
                                    -- added and the final 'PosState'
attachSourcePos :: (a -> Int) -> t a -> PosState s -> (t (a, SourcePos), PosState s)
attachSourcePos projectOffset :: a -> Int
projectOffset xs :: t a
xs = State (PosState s) (t (a, SourcePos))
-> PosState s -> (t (a, SourcePos), PosState s)
forall s a. State s a -> s -> (a, s)
runState ((a -> StateT (PosState s) Identity (a, SourcePos))
-> t a -> State (PosState s) (t (a, SourcePos))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> StateT (PosState s) Identity (a, SourcePos)
forall s (m :: * -> *).
(MonadState (PosState s) m, Stream s) =>
a -> m (a, SourcePos)
f t a
xs)
  where
    f :: a -> m (a, SourcePos)
f a :: a
a = do
      PosState s
pst <- m (PosState s)
forall s (m :: * -> *). MonadState s m => m s
get
      let pst' :: PosState s
pst' = Int -> PosState s -> PosState s
forall s. Stream s => Int -> PosState s -> PosState s
reachOffsetNoLine (a -> Int
projectOffset a
a) PosState s
pst
      PosState s -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put PosState s
pst'
      (a, SourcePos) -> m (a, SourcePos)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, PosState s -> SourcePos
forall s. PosState s -> SourcePos
pstateSourcePos PosState s
pst')
{-# INLINEABLE attachSourcePos #-}

----------------------------------------------------------------------------
-- Pretty-printing

-- | The type class defines how to print a custom component of 'ParseError'.
--
-- @since 5.0.0

class Ord a => ShowErrorComponent a where

  -- | Pretty-print a component of 'ParseError'.

  showErrorComponent :: a -> String

  -- | Length of the error component in characters, used for highlighting of
  -- parse errors in input string.
  --
  -- @since 7.0.0

  errorComponentLen :: a -> Int
  errorComponentLen _ = 1

instance ShowErrorComponent Void where
  showErrorComponent :: Void -> String
showErrorComponent = Void -> String
forall a. Void -> a
absurd

-- | Pretty-print a 'ParseErrorBundle'. All 'ParseError's in the bundle will
-- be pretty-printed in order together with the corresponding offending
-- lines by doing a single efficient pass over the input stream. The
-- rendered 'String' always ends with a newline.
--
-- @since 7.0.0

errorBundlePretty
  :: forall s e. ( Stream s
                 , ShowErrorComponent e
                 )
  => ParseErrorBundle s e -- ^ Parse error bundle to display
  -> String               -- ^ Textual rendition of the bundle
errorBundlePretty :: ParseErrorBundle s e -> String
errorBundlePretty ParseErrorBundle {..} =
  let (r :: ShowS
r, _) = ((ShowS, PosState s) -> ParseError s e -> (ShowS, PosState s))
-> (ShowS, PosState s)
-> NonEmpty (ParseError s e)
-> (ShowS, PosState s)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (ShowS, PosState s) -> ParseError s e -> (ShowS, PosState s)
f (ShowS
forall a. a -> a
id, PosState s
bundlePosState) NonEmpty (ParseError s e)
bundleErrors
  in Int -> ShowS
forall a. Int -> [a] -> [a]
drop 1 (ShowS
r "")
  where
    f :: (ShowS, PosState s)
      -> ParseError s e
      -> (ShowS, PosState s)
    f :: (ShowS, PosState s) -> ParseError s e -> (ShowS, PosState s)
f (o :: ShowS
o, !PosState s
pst) e :: ParseError s e
e = (ShowS
o ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
outChunk String -> ShowS
forall a. [a] -> [a] -> [a]
++), PosState s
pst')
      where
        (sline :: String
sline, pst' :: PosState s
pst') = Int -> PosState s -> (String, PosState s)
forall s. Stream s => Int -> PosState s -> (String, PosState s)
reachOffset (ParseError s e -> Int
forall s e. ParseError s e -> Int
errorOffset ParseError s e
e) PosState s
pst
        epos :: SourcePos
epos = PosState s -> SourcePos
forall s. PosState s -> SourcePos
pstateSourcePos PosState s
pst'
        outChunk :: String
outChunk =
          "\n" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> SourcePos -> String
sourcePosPretty SourcePos
epos String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ":\n" String -> ShowS
forall a. Semigroup a => a -> a -> a
<>
          String
padding String -> ShowS
forall a. Semigroup a => a -> a -> a
<> "|\n" String -> ShowS
forall a. Semigroup a => a -> a -> a
<>
          String
lineNumber String -> ShowS
forall a. Semigroup a => a -> a -> a
<> " | " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
sline String -> ShowS
forall a. Semigroup a => a -> a -> a
<> "\n" String -> ShowS
forall a. Semigroup a => a -> a -> a
<>
          String
padding String -> ShowS
forall a. Semigroup a => a -> a -> a
<> "| " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
rpadding String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
pointer String -> ShowS
forall a. Semigroup a => a -> a -> a
<> "\n" String -> ShowS
forall a. Semigroup a => a -> a -> a
<>
          ParseError s e -> String
forall s e.
(Stream s, ShowErrorComponent e) =>
ParseError s e -> String
parseErrorTextPretty ParseError s e
e
        lineNumber :: String
lineNumber = (Int -> String
forall a. Show a => a -> String
show (Int -> String) -> (SourcePos -> Int) -> SourcePos -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pos -> Int
unPos (Pos -> Int) -> (SourcePos -> Pos) -> SourcePos -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourcePos -> Pos
sourceLine) SourcePos
epos
        padding :: String
padding = Int -> Char -> String
forall a. Int -> a -> [a]
replicate (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
lineNumber Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) ' '
        rpadding :: String
rpadding =
          if Int
pointerLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 0
            then Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
rpshift ' '
            else ""
        rpshift :: Int
rpshift = Pos -> Int
unPos (SourcePos -> Pos
sourceColumn SourcePos
epos) Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1
        pointer :: String
pointer = Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
pointerLen '^'
        pointerLen :: Int
pointerLen =
          if Int
rpshift Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
elen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
slineLen
            then Int
slineLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
rpshift Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1
            else Int
elen
        slineLen :: Int
slineLen = String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
sline
        pxy :: Proxy s
pxy = Proxy s
forall k (t :: k). Proxy t
Proxy :: Proxy s
        elen :: Int
elen =
          case ParseError s e
e of
            TrivialError _ Nothing _ -> 1
            TrivialError _ (Just x :: ErrorItem (Token s)
x) _ -> Proxy s -> ErrorItem (Token s) -> Int
forall s. Stream s => Proxy s -> ErrorItem (Token s) -> Int
errorItemLength Proxy s
pxy ErrorItem (Token s)
x
            FancyError _ xs :: Set (ErrorFancy e)
xs ->
              (Int -> ErrorFancy e -> Int) -> Int -> Set (ErrorFancy e) -> Int
forall a b. (a -> b -> a) -> a -> Set b -> a
E.foldl' (\a :: Int
a b :: ErrorFancy e
b -> Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
a (ErrorFancy e -> Int
forall e. ShowErrorComponent e => ErrorFancy e -> Int
errorFancyLength ErrorFancy e
b)) 1 Set (ErrorFancy e)
xs

-- | Pretty-print a 'ParseError'. The rendered 'String' always ends with a
-- newline.
--
-- @since 5.0.0

parseErrorPretty
  :: (Stream s, ShowErrorComponent e)
  => ParseError s e    -- ^ Parse error to render
  -> String            -- ^ Result of rendering
parseErrorPretty :: ParseError s e -> String
parseErrorPretty e :: ParseError s e
e =
  "offset=" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show (ParseError s e -> Int
forall s e. ParseError s e -> Int
errorOffset ParseError s e
e) String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ":\n" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ParseError s e -> String
forall s e.
(Stream s, ShowErrorComponent e) =>
ParseError s e -> String
parseErrorTextPretty ParseError s e
e

-- | Pretty-print a textual part of a 'ParseError', that is, everything
-- except for its position. The rendered 'String' always ends with a
-- newline.
--
-- @since 5.1.0

parseErrorTextPretty
  :: forall s e. (Stream s, ShowErrorComponent e)
  => ParseError s e    -- ^ Parse error to render
  -> String            -- ^ Result of rendering
parseErrorTextPretty :: ParseError s e -> String
parseErrorTextPretty (TrivialError _ us :: Maybe (ErrorItem (Token s))
us ps :: Set (ErrorItem (Token s))
ps) =
  if Maybe (ErrorItem (Token s)) -> Bool
forall a. Maybe a -> Bool
isNothing Maybe (ErrorItem (Token s))
us Bool -> Bool -> Bool
&& Set (ErrorItem (Token s)) -> Bool
forall a. Set a -> Bool
E.null Set (ErrorItem (Token s))
ps
    then "unknown parse error\n"
    else String -> Set String -> String
messageItemsPretty "unexpected " (Proxy s -> ErrorItem (Token s) -> String
forall s. Stream s => Proxy s -> ErrorItem (Token s) -> String
showErrorItem Proxy s
pxy (ErrorItem (Token s) -> String)
-> Set (ErrorItem (Token s)) -> Set String
forall b a. Ord b => (a -> b) -> Set a -> Set b
`E.map` Set (ErrorItem (Token s))
-> (ErrorItem (Token s) -> Set (ErrorItem (Token s)))
-> Maybe (ErrorItem (Token s))
-> Set (ErrorItem (Token s))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Set (ErrorItem (Token s))
forall a. Set a
E.empty ErrorItem (Token s) -> Set (ErrorItem (Token s))
forall a. a -> Set a
E.singleton Maybe (ErrorItem (Token s))
us) String -> ShowS
forall a. Semigroup a => a -> a -> a
<>
         String -> Set String -> String
messageItemsPretty "expecting "  (Proxy s -> ErrorItem (Token s) -> String
forall s. Stream s => Proxy s -> ErrorItem (Token s) -> String
showErrorItem Proxy s
pxy (ErrorItem (Token s) -> String)
-> Set (ErrorItem (Token s)) -> Set String
forall b a. Ord b => (a -> b) -> Set a -> Set b
`E.map` Set (ErrorItem (Token s))
ps)
  where
    pxy :: Proxy s
pxy = Proxy s
forall k (t :: k). Proxy t
Proxy :: Proxy s
parseErrorTextPretty (FancyError _ xs :: Set (ErrorFancy e)
xs) =
  if Set (ErrorFancy e) -> Bool
forall a. Set a -> Bool
E.null Set (ErrorFancy e)
xs
    then "unknown fancy parse error\n"
    else [String] -> String
unlines (ErrorFancy e -> String
forall e. ShowErrorComponent e => ErrorFancy e -> String
showErrorFancy (ErrorFancy e -> String) -> [ErrorFancy e] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set (ErrorFancy e) -> [ErrorFancy e]
forall a. Set a -> [a]
E.toAscList Set (ErrorFancy e)
xs)

----------------------------------------------------------------------------
-- Helpers

-- | Pretty-print an 'ErrorItem'.

showErrorItem :: Stream s => Proxy s -> ErrorItem (Token s) -> String
showErrorItem :: Proxy s -> ErrorItem (Token s) -> String
showErrorItem pxy :: Proxy s
pxy = \case
    Tokens   ts :: NonEmpty (Token s)
ts -> Proxy s -> NonEmpty (Token s) -> String
forall s. Stream s => Proxy s -> NonEmpty (Token s) -> String
showTokens Proxy s
pxy NonEmpty (Token s)
ts
    Label label :: NonEmpty Char
label -> NonEmpty Char -> String
forall a. NonEmpty a -> [a]
NE.toList NonEmpty Char
label
    EndOfInput  -> "end of input"

-- | Get length of the “pointer” to display under a given 'ErrorItem'.

errorItemLength :: Stream s => Proxy s -> ErrorItem (Token s) -> Int
errorItemLength :: Proxy s -> ErrorItem (Token s) -> Int
errorItemLength pxy :: Proxy s
pxy = \case
  Tokens ts :: NonEmpty (Token s)
ts -> Proxy s -> NonEmpty (Token s) -> Int
forall s. Stream s => Proxy s -> NonEmpty (Token s) -> Int
tokensLength Proxy s
pxy NonEmpty (Token s)
ts
  _         -> 1

-- | Pretty-print an 'ErrorFancy'.

showErrorFancy :: ShowErrorComponent e => ErrorFancy e -> String
showErrorFancy :: ErrorFancy e -> String
showErrorFancy = \case
  ErrorFail msg :: String
msg -> String
msg
  ErrorIndentation ord :: Ordering
ord ref :: Pos
ref actual :: Pos
actual ->
    "incorrect indentation (got " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show (Pos -> Int
unPos Pos
actual) String -> ShowS
forall a. Semigroup a => a -> a -> a
<>
    ", should be " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
p String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show (Pos -> Int
unPos Pos
ref) String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ")"
    where
      p :: String
p = case Ordering
ord of
            LT -> "less than "
            EQ -> "equal to "
            GT -> "greater than "
  ErrorCustom a :: e
a -> e -> String
forall a. ShowErrorComponent a => a -> String
showErrorComponent e
a

-- | Get length of the “pointer” to display under a given 'ErrorFancy'.

errorFancyLength :: ShowErrorComponent e => ErrorFancy e -> Int
errorFancyLength :: ErrorFancy e -> Int
errorFancyLength = \case
  ErrorCustom a :: e
a -> e -> Int
forall a. ShowErrorComponent a => a -> Int
errorComponentLen e
a
  _             -> 1

-- | Transforms a list of error messages into their textual representation.

messageItemsPretty
  :: String            -- ^ Prefix to prepend
  -> Set String        -- ^ Collection of messages
  -> String            -- ^ Result of rendering
messageItemsPretty :: String -> Set String -> String
messageItemsPretty prefix :: String
prefix ts :: Set String
ts
  | Set String -> Bool
forall a. Set a -> Bool
E.null Set String
ts = ""
  | Bool
otherwise =
    String
prefix String -> ShowS
forall a. Semigroup a => a -> a -> a
<> (NonEmpty String -> String
orList (NonEmpty String -> String)
-> (Set String -> NonEmpty String) -> Set String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> NonEmpty String
forall a. [a] -> NonEmpty a
NE.fromList ([String] -> NonEmpty String)
-> (Set String -> [String]) -> Set String -> NonEmpty String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set String -> [String]
forall a. Set a -> [a]
E.toAscList) Set String
ts String -> ShowS
forall a. Semigroup a => a -> a -> a
<> "\n"

-- | Print a pretty list where items are separated with commas and the word
-- “or” according to the rules of English punctuation.

orList :: NonEmpty String -> String
orList :: NonEmpty String -> String
orList (x :: String
x:|[])  = String
x
orList (x :: String
x:|[y :: String
y]) = String
x String -> ShowS
forall a. Semigroup a => a -> a -> a
<> " or " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
y
orList xs :: NonEmpty String
xs       = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate ", " (NonEmpty String -> [String]
forall a. NonEmpty a -> [a]
NE.init NonEmpty String
xs) String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ", or " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> NonEmpty String -> String
forall a. NonEmpty a -> a
NE.last NonEmpty String
xs