module OpenTheory.Parser
where
import qualified OpenTheory.Parser.Stream as Stream
newtype Parser a b =
Parser { unParser :: a -> Stream.Stream a -> Maybe (b, Stream.Stream a) }
partialMap :: (b -> Maybe c) -> Parser a b -> Parser a c
partialMap f p =
Parser pf
where
pf a s =
case unParser p a s of
Nothing -> Nothing
Just (b, s') ->
case f b of
Nothing -> Nothing
Just c -> Just (c, s')
map :: (b -> c) -> Parser a b -> Parser a c
map f p = partialMap (\b -> Just (f b)) p
parse :: Parser a b -> Stream.Stream a -> Maybe (b, Stream.Stream a)
parse _ Stream.Error = Nothing
parse _ Stream.Eof = Nothing
parse p (Stream.Cons a s) = unParser p a s
parseAll :: Parser a a
parseAll =
Parser pa
where
pa a s = Just (a, s)
parseNone :: Parser a b
parseNone =
Parser pn
where
pn _ _ = Nothing
parseOption :: (a -> Maybe b) -> Parser a b
parseOption f = partialMap f parseAll
parsePair :: Parser a b -> Parser a c -> Parser a (b, c)
parsePair pb pc =
Parser pbc
where
pbc a s =
case unParser pb a s of
Nothing -> Nothing
Just (b, s') ->
case parse pc s' of
Nothing -> Nothing
Just (c, s'') -> Just ((b, c), s'')
parseSome :: (a -> Bool) -> Parser a a
parseSome p = parseOption (\a -> if p a then Just a else Nothing)
parseStream :: Parser a b -> Stream.Stream a -> Stream.Stream b
parseStream _ Stream.Error = Stream.Error
parseStream _ Stream.Eof = Stream.Eof
parseStream p (Stream.Cons a s) =
case unParser p a s of
Nothing -> Stream.Error
Just (b, s') -> Stream.Cons b (parseStream p s')