module Data.JustParse.Combinator (
assert,
eof,
eitherP,
greedy,
guard,
lookAhead,
notFollowedBy,
option,
optional,
test,
(<|>),
anyToken,
noneOf,
oneOf,
satisfy,
token,
chainl,
chainl1,
chainr,
chainr1,
count,
endBy,
endBy1,
exactly,
many,
many1,
mN,
sepBy,
sepBy1,
skipMany,
skipMany1,
sepEndBy,
sepEndBy1,
takeWhile,
choice,
perm,
select,
branch,
(<||>),
chainl_,
chainr_,
chainl1_,
chainr1_,
choice_,
eitherP_,
endBy_,
endBy1_,
many_,
many1_,
mN_,
option_,
optional_,
perm_,
select_,
sepBy_,
sepBy1_,
sepEndBy_,
sepEndBy1_,
skipMany_,
skipMany1_,
takeWhile_
) where
import Prelude hiding ( print, length, takeWhile )
import Data.JustParse.Internal (
Stream(..), Parser(..), Result(..), extend, finalize, isDone,
isPartial, toPartial, streamAppend )
import Data.Monoid ( mempty, Monoid, mappend )
import Data.Maybe ( fromMaybe )
import Data.List ( minimumBy, foldl1', foldl' )
import Data.Ord ( comparing )
import qualified Control.Monad as M
import qualified Control.Applicative as A
satisfy :: Stream s t => (t -> Bool) -> Parser s t
satisfy f = Parser $ \s ->
case s of
Nothing -> []
Just s' -> case uncons s' of
Nothing -> [Partial $ parse (satisfy f)]
Just (x, xs) -> [Done x (Just xs) | f x]
guard :: Stream s t => Bool -> Parser s ()
guard = M.guard
assert :: Stream s t => Bool -> Parser s ()
assert = guard
eof :: Stream s t => Parser s ()
eof = notFollowedBy anyToken
oneOf :: (Eq t, Stream s t) => [t] -> Parser s t
oneOf ts = satisfy (`elem` ts)
noneOf :: (Eq t, Stream s t) => [t] -> Parser s t
noneOf ts = satisfy (`notElem` ts)
token :: (Eq t, Stream s t) => t -> Parser s t
token t = satisfy (==t)
anyToken :: Stream s t => Parser s t
anyToken = satisfy (const True)
takeWhile :: Stream s t => (t -> Bool) -> Parser s [t]
takeWhile = many . satisfy
takeWhile_ :: Stream s t => (t -> Bool) -> Parser s [t]
takeWhile_ = many_ . satisfy
branch :: Parser s a -> Parser s a -> Parser s a
branch a b = Parser $ \s -> parse a s ++ parse b s
infixr 1 <||>
(<||>) :: Parser s a -> Parser s a -> Parser s a
(<||>) = branch
mN :: Stream s t => Int -> Int -> Parser s a -> Parser s [a]
mN _ 0 _ = Parser $ \s -> [Done [] s]
mN 0 n p = M.liftM2 (:) p (mN 0 (n1) p) A.<|> return []
mN m n p = M.liftM2 (:) p (mN (m1) (n1) p)
mN_ :: Stream s t => Int -> Int -> Parser s a -> Parser s [a]
mN_ _ 0 _ = Parser $ \s -> [Done [] s]
mN_ 0 n p = M.liftM2 (:) p (mN 0 (n1) p) <||> return []
mN_ m n p = M.liftM2 (:) p (mN (m1) (n1) p)
exactly :: Stream s t => Int -> Parser s a -> Parser s [a]
exactly n = mN n n
atLeast :: Stream s t => Int -> Parser s a -> Parser s [a]
atLeast n = mN n (1)
atLeast_ :: Stream s t => Int -> Parser s a -> Parser s [a]
atLeast_ n = mN_ n (1)
atMost :: Stream s t => Int -> Parser s a -> Parser s [a]
atMost = mN 0
atMost_ :: Stream s t => Int -> Parser s a -> Parser s [a]
atMost_ = mN 0
many :: Stream s t => Parser s a -> Parser s [a]
many = A.many
many_ :: Parser s a -> Parser s [a]
many_ p = return [] <||> M.liftM2 (:) p (many_ p)
many1 :: Stream s t => Parser s a -> Parser s [a]
many1 p = M.liftM2 (:) p (many p)
many1_ :: Parser s a -> Parser s [a]
many1_ p = M.liftM2 (:) p (many_ p)
test :: Stream s t => Parser s a -> Parser s Bool
test p =
do
a <- optional (lookAhead p)
case a of
Nothing -> return False
_ -> return True
infixr 1 <|>
(<|>) :: Stream s t => Parser s a -> Parser s a -> Parser s a
(<|>) = (A.<|>)
choice :: Stream s t => [Parser s a] -> Parser s a
choice = foldl1' (A.<|>)
choice_ :: Stream s t => [Parser s a] -> Parser s a
choice_ = foldl1' (<||>)
select :: Stream s t => [Parser s a] -> Parser s (Int, a)
select [] = M.mzero
select (p:ps) = M.liftM (0,) p <|> M.liftM (\(x,y) -> (x+1,y)) (select ps)
select_ :: Stream s t => [Parser s a] -> Parser s (Int, a)
select_ [] = M.mzero
select_ (p:ps) = M.liftM (0,) p <||> M.liftM (\(x,y) -> (x+1,y)) (select_ ps)
greedy :: Stream s t => Parser s a -> Parser s a
greedy (Parser p) = Parser $ \s -> g (p s)
where
f Nothing = 0
f (Just s) = length s
g [] = []
g xs
| all isDone xs = [minimumBy (comparing (f . leftover)) xs]
| otherwise = [Partial $ \s -> g $ extend s xs]
option :: Stream s t => a -> Parser s a -> Parser s a
option v p =
do
r <- A.optional p
case r of
Nothing -> return v
Just v' -> return v'
option_ :: Stream s t => a -> Parser s a -> Parser s a
option_ v p = option v p <||> return v
optional :: Stream s t => Parser s a -> Parser s (Maybe a)
optional = A.optional
optional_ :: Stream s t => Parser s a -> Parser s (Maybe a)
optional_ p = M.liftM Just p <||> return Nothing
sepBy :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
sepBy p s = sepBy1 p s A.<|> return []
sepBy_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
sepBy_ p s = sepBy1_ p s <||> return []
sepBy1 :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
sepBy1 p s = M.liftM2 (:) p (many (s >> p))
sepBy1_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
sepBy1_ p s = M.liftM2 (:) p (many_ (s >> p))
lookAhead :: Stream s t => Parser s a -> Parser s a
lookAhead v@(Parser p) = Parser $ \s ->
let
g (Done a _) = Done a s
g (Partial p') = Partial $ \s' ->
case s' of
Nothing -> finalize (p' s)
_ -> parse (lookAhead v) (streamAppend s s')
in
map g (p s)
count :: Stream s t => Int -> Parser s a -> Parser s [a]
count = exactly
skipMany :: Stream s t => Parser s a -> Parser s ()
skipMany = M.void . many
skipMany_ :: Stream s t => Parser s a -> Parser s ()
skipMany_ = M.void . many_
skipMany1 :: Stream s t => Parser s a -> Parser s ()
skipMany1 = M.void . many1
skipMany1_ :: Stream s t => Parser s a -> Parser s ()
skipMany1_ = M.void . many1_
endBy :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
endBy p s = many (p A.<* s)
endBy_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
endBy_ p s = many_ (p A.<* s)
endBy1 :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
endBy1 p s = many1 (p A.<* s)
endBy1_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
endBy1_ p s = many1_ (p A.<* s)
sepEndBy :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
sepEndBy p s = sepBy p s A.<* optional s
sepEndBy_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
sepEndBy_ p s = sepBy_ p s A.<* optional s
sepEndBy1 :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
sepEndBy1 p s = sepBy1 p s A.<* optional s
sepEndBy1_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
sepEndBy1_ p s = sepBy1_ p s A.<* optional s
chainl :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
chainl p o x = chainl1 p o <|> return x
chainl_ :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
chainl_ p o x = chainl1_ p o <||> return x
chainl1 :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> Parser s a
chainl1 p o = p >>= f
where
f x =
do
g <- o
y <- p
f (g x y)
<|> return x
chainl1_ :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> Parser s a
chainl1_ p o = p >>= f
where
f x =
do
g <- o
y <- p
f (g x y)
<||> return x
chainr :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
chainr p o x = chainr1 p o <|> return x
chainr_ :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
chainr_ p o x = chainr1_ p o <||> return x
chainr1 :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> Parser s a
chainr1 p o = p >>= f
where
f x =
do
g <- o
y <- chainr1 p o
return (g x y)
<|> return x
chainr1_ :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> Parser s a
chainr1_ p o = p >>= f
where
f x =
do
g <- o
y <- chainr1_ p o
return (g x y)
<||> return x
notFollowedBy :: Stream s t => Parser s a -> Parser s ()
notFollowedBy p = test p >>= assert . not
manyTill :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
manyTill p e =
do
b <- test e
if b
then return []
else M.liftM2 (:) p (manyTill p e)
try :: Stream s t => Parser s a -> Parser s a
try = id
eitherP :: Stream s t => Parser s a -> Parser s b -> Parser s (Either a b)
eitherP a b = M.liftM Left a <|> M.liftM Right b
eitherP_ :: Stream s t => Parser s a -> Parser s b -> Parser s (Either a b)
eitherP_ a b = M.liftM Left a <||> M.liftM Right b
perm :: Stream s t => [Parser s a] -> Parser s [a]
perm [] = return []
perm ps =
do
(i, r) <- select ps
M.liftM (r:) (perm (let (a,b) = splitAt i ps in a ++ tail b))
perm_ :: Stream s t => [Parser s a] -> Parser s [a]
perm_ [] = return []
perm_ ps =
do
(i, r) <- select_ ps
M.liftM (r:) (perm_ (let (a,b) = splitAt i ps in a ++ tail b))