@@ -9,7 +9,7 @@ import Control.MonadPlus (class MonadPlus, class MonadZero, class Alternative)
9
9
import Control.Monad.Rec.Class (class MonadRec , tailRecM , Step (..))
10
10
import Control.Plus (class Plus , class Alt )
11
11
import Control.Lazy (class Lazy )
12
- import Data.Bifunctor (bimap , lmap )
12
+ import Data.Bifunctor (lmap )
13
13
import Data.Either (Either (..))
14
14
15
15
-- | A position in an input string.
@@ -26,26 +26,28 @@ type Pos = Int
26
26
type PosString = { str :: String , pos :: Pos }
27
27
28
28
-- | The type of parsing errors.
29
- newtype ParseError = ParseError String
30
-
31
- instance showParseError :: Show ParseError where
32
- show (ParseError msg) = msg
33
-
34
- derive instance eqParseError :: Eq ParseError
35
-
36
- derive instance ordParseError :: Ord ParseError
37
-
38
- -- | A parser is represented as a function which takes a pair of
39
- -- | continuations for failure and success.
40
- newtype Parser a = Parser (PosString -> Either { pos :: Pos , error :: ParseError } { result :: a , suffix :: PosString } )
41
-
42
- -- | Run a parser by providing success and failure continuations.
43
- unParser :: forall a . Parser a -> PosString -> Either { pos :: Pos , error :: ParseError } { result :: a , suffix :: PosString }
29
+ type ParseError = { error :: String , pos :: Pos }
30
+
31
+ -- | A parser is represented as a function that, when successful, returns
32
+ -- | a result and the position where the parse finished or, when it fails,
33
+ -- | a ParserError with more information on where and why it failed.
34
+ -- | See also `printParserError`.
35
+ newtype Parser a = Parser (PosString -> Either ParseError { result :: a , suffix :: PosString } )
36
+
37
+ -- | Run a parser, allowing the caller to define where to start within the
38
+ -- | input `String` and what to do with the unchanged output of the Parser.
39
+ -- | See `runparser` for more typical usages.
40
+ unParser :: forall a . Parser a -> PosString -> Either ParseError { result :: a , suffix :: PosString }
44
41
unParser (Parser p) = p
45
42
46
- -- | Run a parser for an input string, returning either an error or a result.
43
+ -- | Run a parser for an input string. See also `printParserError`
44
+ -- | and `unParser` for more flexible usages.
47
45
runParser :: forall a . Parser a -> String -> Either ParseError a
48
- runParser (Parser p) s = bimap _.error _.result (p { str: s, pos: 0 })
46
+ runParser (Parser p) s = map _.result (p { str: s, pos: 0 })
47
+
48
+ -- | Prints a ParseError's the error message and the position of the error.
49
+ printParserError :: ParseError -> String
50
+ printParserError rec = rec.error <> " ; pos = " <> show rec.pos
49
51
50
52
instance functorParser :: Functor Parser where
51
53
map f (Parser p) = Parser (map (\{ result, suffix } -> { result: f result, suffix }) <<< p)
@@ -93,7 +95,7 @@ instance lazyParser :: Lazy (Parser a) where
93
95
94
96
-- | Fail with the specified message.
95
97
fail :: forall a . String -> Parser a
96
- fail msg = Parser \{ pos } -> Left { pos, error: ParseError msg }
98
+ fail error = Parser \{ pos } -> Left { pos, error }
97
99
98
100
-- | In case of error, the default behavior is to backtrack if no input was consumed.
99
101
-- |
0 commit comments