module ParserCombinators( Parse , none , suceed , token , spot , (>*>) , use , use2 , (*>) , (>*) , alt , list , some ) where type Parse a b = [a]-> [(b, [a])] none :: Parse a b none = const [] suceed :: b-> Parse a b suceed b inp = [(b, inp)] spot :: (a-> Bool)-> Parse a a spot p [] = [] spot p (x:xs) = if p x then [(x, xs)] else [] token :: Eq a=> a-> Parse a a token t = spot (\c-> t == c) infixl 3 `alt` alt :: Parse a b-> Parse a b-> Parse a b alt p1 p2 i = p1 i ++ p2 i infixl 5 >*> (>*>) :: Parse a b-> Parse a c-> Parse a (b, c) (>*>) p1 p2 i = concatMap (\(b, r)-> map (\(c, s)-> ((b, c), s)) (p2 r)) (p1 i) infix 4 `use`, `use2` use :: Parse a b-> (b-> c)-> Parse a c use p f i = map (\(o, r)-> (f o, r)) (p i) use2 :: Parse a (b, c)-> (b-> c-> d)-> Parse a d use2 p f = use p (uncurry f) infixl 5 *>, >* (*>) :: Parse a b-> Parse a c-> Parse a c (>*) :: Parse a b-> Parse a c-> Parse a b p1 *> p2 = p1 >*> p2 `use` snd p1 >* p2 = p1 >*> p2 `use` fst list :: Parse a b-> Parse a [b] list p = p >*> list p `use2` (:) `alt` suceed [] some :: Parse a b-> Parse a [b] some p = p >*> list p `use2` (:)