@@ -2,6 +2,8 @@ module Text.Parsing.StringParser where
22
33import Data.Either (Either (..))
44
5+ type Pos = Number
6+
57--
68-- Strings are represented as a string with an index from the
79-- start of the string.
@@ -12,7 +14,7 @@ import Data.Either (Either(..))
1214-- This allows us to avoid repeatedly finding substrings
1315-- every time we match a character.
1416--
15- type PosString = { str :: String , pos :: Number }
17+ type PosString = { str :: String , pos :: Pos }
1618
1719--
1820-- The type of parsing errors
@@ -26,13 +28,13 @@ instance showParseError :: Show ParseError where
2628-- A parser is represented as a function which takes a pair of
2729-- continuations for failure and success.
2830--
29- data Parser a = Parser (forall r . PosString -> (ParseError -> r ) -> (a -> PosString -> r ) -> r )
31+ data Parser a = Parser (forall r . PosString -> (Pos -> ParseError -> r ) -> (a -> PosString -> r ) -> r )
3032
31- unParser :: forall a r . Parser a -> PosString -> (ParseError -> r ) -> (a -> PosString -> r ) -> r
33+ unParser :: forall a r . Parser a -> PosString -> (Pos -> ParseError -> r ) -> (a -> PosString -> r ) -> r
3234unParser (Parser p) = p
3335
3436runParser :: forall a . Parser a -> String -> Either ParseError a
35- runParser p s = unParser p { str: s, pos: 0 } Left (\a _ -> Right a)
37+ runParser p s = unParser p { str: s, pos: 0 } (\_ err -> Left err) (\a _ -> Right a)
3638
3739--
3840-- Parser type class instances
@@ -58,10 +60,16 @@ instance bindParser :: Bind Parser where
5860instance monadParser :: Monad Parser
5961
6062instance alternativeParser :: Alternative Parser where
61- empty = Parser (\_ fc _ -> fc ( ParseError " No alternative" ))
63+ empty = fail " No alternative"
6264 (<|>) p1 p2 = Parser (\s fc sc ->
63- unParser p1 s (\_ ->
64- unParser p2 s fc sc) sc)
65+ unParser p1 s (\pos msg ->
66+ if s.pos == pos
67+ then unParser p2 s fc sc
68+ else fc pos msg)
69+ sc)
6570
6671fail :: forall a . String -> Parser a
67- fail msg = Parser (\_ fc _ -> fc (ParseError msg))
72+ fail msg = Parser (\{ pos = pos } fc _ -> fc pos (ParseError msg))
73+
74+ try :: forall a . Parser a -> Parser a
75+ try p = Parser (\(s@{ pos = pos }) fc sc -> unParser p s (\_ -> fc pos) sc)
0 commit comments