zot-0.0.2: src/Parse.hs
module Parse (
Parse,
none,
succeed,
spot,
token,
tokens,
eof,
(>*>),
alt,
build,
list1,
recL1
) where
import Control.Arrow ( first, ( &&& ) )
infixr 8 >*>
infix 7 `build`
infixl 6 `alt`
type Parse a b = [ a ] -> [ ( b, [ a ] ) ]
none :: Parse a b
none = const [ ]
succeed :: b -> Parse a b
succeed = curry ( : [] )
spot :: ( a -> Bool ) -> Parse a a
spot p ( x : xs ) | p x = [ ( x, xs ) ]
spot _ _ = [ ]
token :: Eq a => a -> Parse a a
token = spot . ( == )
tokens :: Eq a => [ a ] -> Parse a [ a ]
tokens [ ] = succeed [ ]
tokens ( x : xs ) = token x >*> tokens xs `build` uncurry (:)
eof :: Parse a ()
eof [ ] = [ ( (), [ ] ) ]
eof _ = [ ]
(>*>) :: Parse a b -> Parse a c -> Parse a ( b, c )
( p >*> q ) inp = [ ( ( x, y ), r' ) | ( x, r ) <- p inp, ( y, r' ) <- q r ]
alt :: Parse a b -> Parse a b -> Parse a b
p1 `alt` p2 = uncurry ( ++ ) . ( p1 &&& p2 )
build :: Parse a b -> ( b -> c ) -> Parse a c
build p f = map ( first f ) . p
list1 :: Parse a b -> Parse a [ b ]
list1 p = p `build` ( : [] ) `alt` p >*> list1 p `build` uncurry ( : )
recL1 :: ( b -> b -> b ) -> Parse a b -> Parse a b
recL1 f p = ( p >*> recL1' f p ) `build` ( \( x, xs ) -> xs x )
recL1' :: ( b -> c -> b ) -> Parse a c -> Parse a ( b -> b )
recL1' f p = succeed id `alt`
( p >*> recL1' f p `build` ( \( x, xs ) y -> xs ( f y x ) ) )