@@ -19,42 +19,51 @@ import Control.Monad.Error.Trans
1919import Control.MonadPlus
2020import Control.Plus
2121
22+ import Text.Parsing.Parser.Pos
23+
2224data ParseError = ParseError
2325 { message :: String
26+ , position :: Position
2427 }
2528
2629instance errorParseError :: Error ParseError where
27- noMsg = ParseError { message: " " }
28- strMsg msg = ParseError { message: msg }
30+ noMsg = ParseError { message: " " , position: initialPos }
31+ strMsg msg = ParseError { message: msg, position: initialPos }
2932
3033instance showParseError :: Show ParseError where
31- show (ParseError msg) = " ParseError { message: " ++ msg.message ++ " }"
34+ show (ParseError msg) = " ParseError { message: " ++ msg.message ++ " , position: " ++ show msg.position ++ " }"
35+
36+ -- | `PState` contains the remaining input and current position.
37+ data PState s = PState
38+ { input :: s
39+ , position :: Position
40+ }
3241
33- newtype ParserT s m a = ParserT (s -> m { input :: s , result :: Either ParseError a , consumed :: Boolean } )
42+ newtype ParserT s m a = ParserT (PState s -> m { input :: s , result :: Either ParseError a , consumed :: Boolean , position :: Position } )
3443
35- unParserT :: forall m s a . ParserT s m a -> s -> m { input :: s , result :: Either ParseError a , consumed :: Boolean }
44+ unParserT :: forall m s a . ParserT s m a -> PState s -> m { input :: s , result :: Either ParseError a , consumed :: Boolean , position :: Position }
3645unParserT (ParserT p) = p
3746
38- runParserT :: forall m s a . (Monad m ) => s -> ParserT s m a -> m (Either ParseError a )
47+ runParserT :: forall m s a . (Monad m ) => PState s -> ParserT s m a -> m (Either ParseError a )
3948runParserT s p = do
4049 o <- unParserT p s
4150 return o.result
4251
4352type Parser s a = ParserT s Identity a
4453
4554runParser :: forall s a . s -> Parser s a -> Either ParseError a
46- runParser s = runIdentity <<< runParserT s
55+ runParser s = runIdentity <<< runParserT ( PState { input: s, position: initialPos })
4756
4857instance functorParserT :: (Functor m ) => Functor (ParserT s m ) where
4958 (<$>) f p = ParserT $ \s -> f' <$> unParserT p s
5059 where
51- f' o = { input: o.input, result: f <$> o.result, consumed: o.consumed }
60+ f' o = { input: o.input, result: f <$> o.result, consumed: o.consumed, position: o.position }
5261
5362instance applyParserT :: (Monad m ) => Apply (ParserT s m ) where
5463 (<*>) = ap
5564
5665instance applicativeParserT :: (Monad m ) => Applicative (ParserT s m ) where
57- pure a = ParserT $ \s -> pure { input: s, result: Right a, consumed: false }
66+ pure a = ParserT $ \( PState { input: s, position: pos }) -> pure { input: s, result: Right a, consumed: false , position: pos }
5867
5968instance altParserT :: (Monad m ) => Alt (ParserT s m ) where
6069 (<|>) p1 p2 = ParserT $ \s -> unParserT p1 s >>= \o ->
@@ -70,29 +79,35 @@ instance alternativeParserT :: (Monad m) => Alternative (ParserT s m)
7079instance bindParserT :: (Monad m ) => Bind (ParserT s m ) where
7180 (>>=) p f = ParserT $ \s -> unParserT p s >>= \o ->
7281 case o.result of
73- Left err -> return { input: o.input, result: Left err, consumed: o.consumed }
74- Right a -> updateConsumedFlag o.consumed <$> unParserT (f a) o.input
82+ Left err -> return { input: o.input, result: Left err, consumed: o.consumed, position: o.position }
83+ Right a -> updateConsumedFlag o.consumed <$> unParserT (f a) ( PState { input: o.input, position: o.position })
7584 where
76- updateConsumedFlag c o = { input: o.input, consumed: c || o.consumed, result: o.result }
85+ updateConsumedFlag c o = { input: o.input, consumed: c || o.consumed, result: o.result, position: o.position }
7786
7887instance monadParserT :: (Monad m ) => Monad (ParserT s m )
7988
8089instance monadPlusParserT :: (Monad m ) => MonadPlus (ParserT s m )
8190
8291instance monadTransParserT :: MonadTrans (ParserT s ) where
83- lift m = ParserT $ \s -> (\a -> { input: s, consumed: false , result: Right a }) <$> m
92+ lift m = ParserT $ \( PState { input: s, position: pos }) -> (\a -> { input: s, consumed: false , result: Right a, position: pos }) <$> m
8493
8594instance monadStateParserT :: (Monad m ) => MonadState s (ParserT s m ) where
86- state f = ParserT $ \s ->
95+ state f = ParserT $ \( PState { input: s, position: pos }) ->
8796 return $ case f s of
88- Tuple a s' -> { input: s', consumed: false , result: Right a }
97+ Tuple a s' -> { input: s', consumed: false , result: Right a, position: pos }
8998
9099instance lazy1ParserT :: Lazy1 (ParserT s m ) where
91100 defer1 f = ParserT $ \s -> unParserT (f unit) s
92101
93102consume :: forall s m . (Monad m ) => ParserT s m Unit
94- consume = ParserT $ \s -> return { consumed: true , input: s, result: Right unit }
103+ consume = ParserT $ \( PState { input: s, position: pos }) -> return { consumed: true , input: s, result: Right unit, position: pos }
95104
96105fail :: forall m s a . (Monad m ) => String -> ParserT s m a
97- fail message = ParserT $ \s -> return { input: s, consumed: false , result: Left (ParseError { message: message }) }
106+ fail message = ParserT $ \(PState { input: s, position: pos }) -> return $ parseFailed s pos message
107+
108+ -- | Creates a failed parser state for the remaining input `s` and current position
109+ -- | with an error message.
110+ -- | Most of the time, `fail` should be used instead.
111+ parseFailed :: forall s a . s -> Position -> String -> { input :: s , result :: Either ParseError a , consumed :: Boolean , position :: Position }
112+ parseFailed s pos message = { input: s, consumed: false , result: Left (ParseError { message: message, position: pos }), position: pos }
98113
0 commit comments