{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE Safe #-}
module Text.Parsec.Error
( Message ( SysUnExpect, UnExpect, Expect, Message )
, messageString
, ParseError, errorPos, errorMessages, errorIsUnknown
, showErrorMessages
, newErrorMessage, newErrorUnknown
, addErrorMessage, setErrorPos, setErrorMessage
, mergeError
) where
import Data.List ( nub, sort )
import Data.Typeable ( Typeable )
import Text.Parsec.Pos
data Message = SysUnExpect !String
| UnExpect !String
| Expect !String
| Message !String
deriving ( Typeable )
instance Enum Message where
fromEnum :: Message -> Int
fromEnum (SysUnExpect String
_) = Int
0
fromEnum (UnExpect String
_) = Int
1
fromEnum (Expect String
_) = Int
2
fromEnum (Message String
_) = Int
3
toEnum :: Int -> Message
toEnum Int
_ = forall a. HasCallStack => String -> a
error String
"toEnum is undefined for Message"
instance Eq Message where
Message
m1 == :: Message -> Message -> Bool
== Message
m2 = forall a. Enum a => a -> Int
fromEnum Message
m1 forall a. Eq a => a -> a -> Bool
== forall a. Enum a => a -> Int
fromEnum Message
m2
instance Ord Message where
compare :: Message -> Message -> Ordering
compare Message
msg1 Message
msg2 = forall a. Ord a => a -> a -> Ordering
compare (forall a. Enum a => a -> Int
fromEnum Message
msg1) (forall a. Enum a => a -> Int
fromEnum Message
msg2)
messageString :: Message -> String
messageString :: Message -> String
messageString (SysUnExpect String
s) = String
s
messageString (UnExpect String
s) = String
s
messageString (Expect String
s) = String
s
messageString (Message String
s) = String
s
data ParseError = ParseError !SourcePos [Message]
deriving ( Typeable )
errorPos :: ParseError -> SourcePos
errorPos :: ParseError -> SourcePos
errorPos (ParseError SourcePos
pos [Message]
_msgs)
= SourcePos
pos
errorMessages :: ParseError -> [Message]
errorMessages :: ParseError -> [Message]
errorMessages (ParseError SourcePos
_pos [Message]
msgs)
= forall a. Ord a => [a] -> [a]
sort [Message]
msgs
errorIsUnknown :: ParseError -> Bool
errorIsUnknown :: ParseError -> Bool
errorIsUnknown (ParseError SourcePos
_pos [Message]
msgs)
= forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Message]
msgs
newErrorUnknown :: SourcePos -> ParseError
newErrorUnknown :: SourcePos -> ParseError
newErrorUnknown SourcePos
pos
= SourcePos -> [Message] -> ParseError
ParseError SourcePos
pos []
newErrorMessage :: Message -> SourcePos -> ParseError
newErrorMessage :: Message -> SourcePos -> ParseError
newErrorMessage Message
msg SourcePos
pos
= SourcePos -> [Message] -> ParseError
ParseError SourcePos
pos [Message
msg]
addErrorMessage :: Message -> ParseError -> ParseError
addErrorMessage :: Message -> ParseError -> ParseError
addErrorMessage Message
msg (ParseError SourcePos
pos [Message]
msgs)
= SourcePos -> [Message] -> ParseError
ParseError SourcePos
pos (Message
msgforall a. a -> [a] -> [a]
:[Message]
msgs)
setErrorPos :: SourcePos -> ParseError -> ParseError
setErrorPos :: SourcePos -> ParseError -> ParseError
setErrorPos SourcePos
pos (ParseError SourcePos
_ [Message]
msgs)
= SourcePos -> [Message] -> ParseError
ParseError SourcePos
pos [Message]
msgs
setErrorMessage :: Message -> ParseError -> ParseError
setErrorMessage :: Message -> ParseError -> ParseError
setErrorMessage Message
msg (ParseError SourcePos
pos [Message]
msgs)
= SourcePos -> [Message] -> ParseError
ParseError SourcePos
pos (Message
msg forall a. a -> [a] -> [a]
: forall a. (a -> Bool) -> [a] -> [a]
filter (Message
msg forall a. Eq a => a -> a -> Bool
/=) [Message]
msgs)
mergeError :: ParseError -> ParseError -> ParseError
mergeError :: ParseError -> ParseError -> ParseError
mergeError e1 :: ParseError
e1@(ParseError SourcePos
pos1 [Message]
msgs1) e2 :: ParseError
e2@(ParseError SourcePos
pos2 [Message]
msgs2)
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Message]
msgs2 Bool -> Bool -> Bool
&& Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Message]
msgs1) = ParseError
e1
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Message]
msgs1 Bool -> Bool -> Bool
&& Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Message]
msgs2) = ParseError
e2
| Bool
otherwise
= case SourcePos
pos1 forall a. Ord a => a -> a -> Ordering
`compare` SourcePos
pos2 of
Ordering
EQ -> SourcePos -> [Message] -> ParseError
ParseError SourcePos
pos1 ([Message]
msgs1 forall a. [a] -> [a] -> [a]
++ [Message]
msgs2)
Ordering
GT -> ParseError
e1
Ordering
LT -> ParseError
e2
instance Show ParseError where
show :: ParseError -> String
show ParseError
err
= forall a. Show a => a -> String
show (ParseError -> SourcePos
errorPos ParseError
err) forall a. [a] -> [a] -> [a]
++ String
":" forall a. [a] -> [a] -> [a]
++
String
-> String -> String -> String -> String -> [Message] -> String
showErrorMessages String
"or" String
"unknown parse error"
String
"expecting" String
"unexpected" String
"end of input"
(ParseError -> [Message]
errorMessages ParseError
err)
instance Eq ParseError where
ParseError
l == :: ParseError -> ParseError -> Bool
== ParseError
r
= ParseError -> SourcePos
errorPos ParseError
l forall a. Eq a => a -> a -> Bool
== ParseError -> SourcePos
errorPos ParseError
r Bool -> Bool -> Bool
&& ParseError -> [String]
messageStrs ParseError
l forall a. Eq a => a -> a -> Bool
== ParseError -> [String]
messageStrs ParseError
r
where
messageStrs :: ParseError -> [String]
messageStrs = forall a b. (a -> b) -> [a] -> [b]
map Message -> String
messageString forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseError -> [Message]
errorMessages
showErrorMessages ::
String -> String -> String -> String -> String -> [Message] -> String
showErrorMessages :: String
-> String -> String -> String -> String -> [Message] -> String
showErrorMessages String
msgOr String
msgUnknown String
msgExpecting String
msgUnExpected String
msgEndOfInput [Message]
msgs
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Message]
msgs = String
msgUnknown
| Bool
otherwise = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (String
"\n"forall a. [a] -> [a] -> [a]
++) forall a b. (a -> b) -> a -> b
$ [String] -> [String]
clean forall a b. (a -> b) -> a -> b
$
[String
showSysUnExpect,String
showUnExpect,String
showExpect,String
showMessages]
where
([Message]
sysUnExpect,[Message]
msgs1) = forall a. (a -> Bool) -> [a] -> ([a], [a])
span ((String -> Message
SysUnExpect String
"") forall a. Eq a => a -> a -> Bool
==) [Message]
msgs
([Message]
unExpect,[Message]
msgs2) = forall a. (a -> Bool) -> [a] -> ([a], [a])
span ((String -> Message
UnExpect String
"") forall a. Eq a => a -> a -> Bool
==) [Message]
msgs1
([Message]
expect,[Message]
messages) = forall a. (a -> Bool) -> [a] -> ([a], [a])
span ((String -> Message
Expect String
"") forall a. Eq a => a -> a -> Bool
==) [Message]
msgs2
showExpect :: String
showExpect = String -> [Message] -> String
showMany String
msgExpecting [Message]
expect
showUnExpect :: String
showUnExpect = String -> [Message] -> String
showMany String
msgUnExpected [Message]
unExpect
showSysUnExpect :: String
showSysUnExpect | Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Message]
unExpect) Bool -> Bool -> Bool
||
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Message]
sysUnExpect = String
""
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
firstMsg = String
msgUnExpected forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ String
msgEndOfInput
| Bool
otherwise = String
msgUnExpected forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ String
firstMsg
where
firstMsg :: String
firstMsg = Message -> String
messageString (forall a. [a] -> a
head [Message]
sysUnExpect)
showMessages :: String
showMessages = String -> [Message] -> String
showMany String
"" [Message]
messages
showMany :: String -> [Message] -> String
showMany String
pre [Message]
msgs3 = case [String] -> [String]
clean (forall a b. (a -> b) -> [a] -> [b]
map Message -> String
messageString [Message]
msgs3) of
[] -> String
""
[String]
ms | forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
pre -> [String] -> String
commasOr [String]
ms
| Bool
otherwise -> String
pre forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ [String] -> String
commasOr [String]
ms
commasOr :: [String] -> String
commasOr [] = String
""
commasOr [String
m] = String
m
commasOr [String]
ms = [String] -> String
commaSep (forall a. [a] -> [a]
init [String]
ms) forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ String
msgOr forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. [a] -> a
last [String]
ms
commaSep :: [String] -> String
commaSep = String -> [String] -> String
separate String
", " forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
clean
separate :: String -> [String] -> String
separate String
_ [] = String
""
separate String
_ [String
m] = String
m
separate String
sep (String
m:[String]
ms) = String
m forall a. [a] -> [a] -> [a]
++ String
sep forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
separate String
sep [String]
ms
clean :: [String] -> [String]
clean = forall a. Eq a => [a] -> [a]
nub forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null)