packages feed

parcom-lib-0.1.0.0: Text/Parcom/Prim.hs

module Text.Parcom.Prim
( anyToken, oneOf, eof
, satisfy
, token, tokens
)
where

import Text.Parcom.Core
import Text.Parcom.Internal

-- | Gets the next token from the stream
anyToken :: (Stream s t, Token t) => Parcom s t t
anyToken = next

-- | Succeeds iff end-of-input has been reached
eof :: (Stream s t, Token t) => Parcom s t ()
eof = notFollowedBy anyToken <?> "end of input"

-- | Matches one token against a list of possible tokens; returns the
-- matching token.
oneOf :: (Stream s t, Token t, Show t, Eq t) => [t] -> Parcom s t t
oneOf xs = satisfy (`elem` xs) <?> (formatOptionList . map show) xs

-- | Succeeds if the given predicate is met for the next token.
satisfy :: (Stream s t, Token t) => (t -> Bool) -> Parcom s t t
satisfy p = do
    c <- peek
    if p c
        then next
        else fail "Predicate not met"

-- | Exactly match one particular token
token :: (Stream s t, Token t, Show t, Eq t) => t -> Parcom s t t
token t = satisfy (== t) <?> show t

-- | Match a series of tokens exactly
tokens :: (Stream s t, Token t, Eq t, Show t) => [t] -> Parcom s t [t]
tokens [] = return []
tokens (x:xs) = do
    c <- token x
    cs <- tokens xs
    return (c:cs)