> module CPSParser      (  CPS ..,
>                       -- get next token etc
>                          item, unItem, end,
>                       -- error handling
>                          Parser(..), ParseResult(..),
>                          runParser,
>                          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.


> runParser             :: Parser tok val val -> [tok] -> ParseResult tok val
> runParser 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 runParser p s of
>                             Left (v, x) -> c v f x
>                             Right _     -> f



> syntaxError           =  "syntax error"


Optimizations.


> {-# INLINE item   #-}
> {-# INLINE unItem #-}