> module CPSParser ( > -- get next token etc > item, unItem, end, > -- error handling > Parser, ParseResult, > runParserCPS, > parseError, mandatory, probe > ) > where > import CPS Parsing based on the CPS Monad The state is instantiated to a list of tokens. item returns the first item of the input, and fails if the input is exhausted. > item :: BT [tok] tok res > item = \c f s -> case s of [] -> f; a:x -> c a f x unItem pushes the given token back. > unItem :: tok -> BT [tok] () res > unItem a = \c f s -> c () f (a:s) end succeeds only if the input is empty. > end :: BT [tok] () res > end = \c f s -> case s of [] -> c () f []; _:_ -> f Error handling > type Parser tok val res = BT [tok] val (ParseResult tok res) > type ParseResult tok val = Either (val, [tok]) String > succCont = \v f x -> Left (v, x) > failCont s = Right s Running a parser. > runParserCPS :: Parser tok val val -> [tok] -> ParseResult tok val > runParserCPS p = p succCont (failCont syntaxError) Signal an error. > parseError :: String -> Parser tok val res > parseError s = hardFail (failCont s) Turn soft into hard failure. > mandatory s p = p ? parseError s Turn hard into soft failure. > probe :: Parser tok val val -> Parser tok val val > probe p = \c f s -> case runParserCPS p s of > Left (v, x) -> c v f x > Right _ -> f > syntaxError = "syntax error" Optimizations. > {-# INLINE item #-} > {-# INLINE unItem #-}