hydrogen-util-0.8: src/Hydrogen/Util/Parsec.hs
module Hydrogen.Util.Parsec (
module Text.Parsec.Combinator
, module Text.Parsec.Prim
, module Text.Parsec.Pos
, Parser
, ParseError
, SomethingBad
, Tokens
, runTokenParser
, mkError
, sourceToken
, manyBetween
, (>+>)
, (<+<)
) where
import Hydrogen.Prelude
import Text.Parsec.Combinator
import Text.Parsec.Error
import Text.Parsec.Pos
import Text.Parsec.Prim
type SomethingBad = (SourcePos, [String])
type Parser source result = source -> Either SomethingBad result
type Tokens t = [(SourcePos, t)]
mkError :: ParseError -> Either SomethingBad b
mkError e = Left (errorPos e, map messageString (errorMessages e))
runTokenParser :: (Stream a Identity t) => ParsecT a () Identity b -> Parser a b
runTokenParser p = either mkError Right . runIdentity . runParserT p () ""
sourceToken :: (Show t, Stream (Tokens t) m (SourcePos, t))
=> (t -> Maybe a)
-> ParsecT [(SourcePos, t)] u m a
sourceToken f = tokenPrim (show . snd) nextPos (f . snd)
where
nextPos p _ = \case
((p', _) : _) -> p'
_ -> p
manyBetween :: (Monad m, Stream s m t)
=> ParsecT s u m open -> ParsecT s u m close -> ParsecT s u m p -> ParsecT s u m [p]
manyBetween o c p = o *> manyTill p c
(>+>) :: Parser a b -> Parser b c -> Parser a c
p1 >+> p2 = join <$> fmap p2 <$> p1
(<+<) :: Parser b c -> Parser a b -> Parser a c
(<+<) = flip (>+>)