bookhound 0.1.5.0 → 0.1.6.0
raw patch · 3 files changed
+61/−49 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Parser: Error :: ParseError -> ParseResult a
- Parser: Result :: Input -> a -> ParseResult a
- ParserCombinators: contains :: Eq a => Parser [a] -> [a] -> Parser [a]
+ ParserCombinators: contains :: Eq a => [a] -> Parser [a] -> Parser [a]
- ParserCombinators: notContains :: Eq a => Parser [a] -> [a] -> Parser [a]
+ ParserCombinators: notContains :: Eq a => [a] -> Parser [a] -> Parser [a]
- ParserCombinators: satisfies :: Parser a -> (a -> Bool) -> Parser a
+ ParserCombinators: satisfies :: (a -> Bool) -> Parser a -> Parser a
- ParserCombinators: times :: Parser a -> Integer -> Parser [a]
+ ParserCombinators: times :: Integer -> Parser a -> Parser [a]
Files
- bookhound.cabal +1/−1
- src/Parser.hs +46/−36
- src/ParserCombinators.hs +14/−12
bookhound.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: bookhound-version: 0.1.5.0+version: 0.1.6.0 synopsis: Simple Parser Combinators & Parsers description: Please see the README on GitHub at <https://github.com/albertprz/bookhound#readme> category: Parsers
src/Parser.hs view
@@ -1,7 +1,8 @@-module Parser (Parser, ParseResult(..), ParseError(..), runParser, errorParser,+module Parser (Parser, ParseResult, ParseError(..), runParser, errorParser, andThen, exactly, isMatch, check, except, anyOf, allOf, char, withTransform) where +import Control.Applicative (liftA2) import Control.Monad (join) import Data.Maybe (isJust) import Data.Either (fromRight)@@ -37,29 +38,29 @@ fmap _ (Error pe) = Error pe instance Functor Parser where- fmap f (P p t) = P (fmap f . p) t+ fmap f (P p t) = applyTransform t $ mkParser (fmap f . p) instance Applicative Parser where pure a = mkParser (`Result` a)- (<*>) mf ma = mf >>= (<$> ma)--instance Monad Parser where- (>>=) (P p t) f = applyTransform transf combinedParser+ (liftA2) f (P p t) mb@(P _ t') =+ applyTransform (findJust t t') combinedParser where combinedParser = mkParser ( \x -> case p x of- Result i a -> (parse) (f a) i+ Result i a -> parse ((f a) <$> mb) i Error pe -> Error pe) - transf :: Maybe (Parser a -> Parser a)- transf = findJust t (transform $ f undefined)+instance Monad Parser where+ (>>=) (P p t) f = applyTransform t combinedParser+ where+ combinedParser = mkParser (+ \x -> case p x of+ Result i a -> parse (f a) i+ Error pe -> Error pe) -withTransform :: (forall b. Parser b -> Parser b) -> Parser a -> Parser a-withTransform f p = f $ p{transform = Just f}- runParser :: Parser a -> Input -> Either ParseError a-runParser p i = toEither $ (parse) (exactly p) i where+runParser p i = toEither $ parse (exactly p) i where toEither = \case Error pe -> Left pe@@ -77,35 +78,43 @@ andThen :: Parser Input -> Parser a -> Parser a-andThen p1 p2@(P _ t) = applyTransform t $ P (\i -> (parse) p2 $ fromRight i $ runParser p1 i) t+andThen p1 p2@(P _ t) = applyTransform t $ P (\i -> parse p2 $ fromRight i $ runParser p1 i) t exactly :: Parser a -> Parser a-exactly (P p t) = applyTransform t $ P (+exactly (P p t) = applyTransform t $ mkParser ( \x -> case p x of result@(Result "" _) -> result Result i _ -> Error $ ExpectedEof i- err@(Error _) -> err) t-+ err@(Error _) -> err) anyOf :: [Parser a] -> Parser a-anyOf [] = errorParser UnexpectedEof-anyOf [x] = x-anyOf ((P p t) : rest) = applyTransform t $ P (- \x -> case p x of+anyOf ps = anyOfHelper ps Nothing++allOf :: [Parser a] -> Parser a+allOf ps = allOfHelper ps Nothing+++anyOfHelper :: [Parser a] -> (forall b. Maybe (Parser b -> Parser b)) -> Parser a+anyOfHelper [] _ = errorParser $ NoMatch "anyOf"+anyOfHelper [p] _ = p+anyOfHelper ((P p t) : rest) t' = applyTransform (findJust t t') $ mkParser (+ \x -> case p x of result@(Result _ _) -> result- Error _ -> (parse) (anyOf rest) x) t+ Error _ -> parse (anyOfHelper rest t) x) -allOf :: [Parser a] -> Parser a-allOf [] = errorParser UnexpectedEof-allOf [x] = x-allOf ((P p t) : rest) = applyTransform t $ P (- \x -> case p x of- Result i _ -> (parse) (allOf rest) i- err@(Error _) -> err) t +allOfHelper :: [Parser a] -> (forall b. Maybe (Parser b -> Parser b)) -> Parser a+allOfHelper [] _ = errorParser $ NoMatch "allOf"+allOfHelper [p] _ = p+allOfHelper ((P p t) : rest) t' = applyTransform (findJust t t') $ mkParser (+ \x -> case p x of+ Result i _ -> parse (allOfHelper rest t) i+ err@(Error _) -> err) ++ isMatch :: (Char -> Char -> Bool) -> Parser Char -> Char -> Parser Char isMatch cond parser c1 = do c2 <- parser@@ -113,7 +122,6 @@ then pure c2 else errorParser $ UnexpectedChar c2 - check :: String -> (a -> Bool) -> Parser a -> Parser a check condName cond parser = do c2 <- parser@@ -123,18 +131,20 @@ except :: Show a => Parser a -> Parser a -> Parser a-except alt (P p t) = applyTransform t $ P (- \x -> case p x of+except (P p t) (P p' _) = applyTransform t $ mkParser (+ \x -> case p' x of Result _ a -> Error $ UnexpectedString (show a)- Error _ -> (parse) alt x) t+ Error _ -> p x) +withTransform :: (forall b. Parser b -> Parser b) -> Parser a -> Parser a+withTransform f = applyTransform $ Just f +applyTransform :: (forall a. Maybe (Parser a -> Parser a)) -> Parser b -> Parser b+applyTransform f p = maybe p (\f' -> (f' p){transform = f} ) f+ mkParser :: (Input -> ParseResult a) -> Parser a mkParser p = P {parse = p, transform = Nothing}--applyTransform :: (forall a. Maybe (Parser a -> Parser a)) -> Parser b -> Parser b-applyTransform f p = maybe id id f $ p findJust :: forall a. Maybe a -> Maybe a -> Maybe a findJust ma mb = join $ find isJust [ma, mb]
src/ParserCombinators.hs view
@@ -44,25 +44,26 @@ -- Condition combinators-satisfies :: Parser a -> (a -> Bool) -> Parser a-satisfies parser cond = check "satisfies" cond parser+satisfies :: (a -> Bool) -> Parser a -> Parser a+satisfies cond p = check "satisfies" cond p -contains :: Eq a => Parser [a] -> [a] -> Parser [a]-contains p str = check "contains" (isInfixOf str) p+contains :: Eq a => [a] -> Parser [a] -> Parser [a]+contains val p = check "contains" (isInfixOf val) p -notContains :: Eq a => Parser [a] -> [a] -> Parser [a]-notContains p str = check "notContains" (isInfixOf str) p+notContains :: Eq a => [a] -> Parser [a] -> Parser [a]+notContains val p = check "notContains" (isInfixOf val) p --- Frequency combinators-times :: Parser a -> Integer -> Parser [a]-times parser n = sequence $ parser <$ [1 .. n]+ -- Frequency combinators+times :: Integer -> Parser a -> Parser [a]+times n p = sequence $ p <$ [1 .. n] + maybeTimes :: Parser a -> Parser (Maybe a) maybeTimes = (listToMaybe <$>) . check "maybeTimes" (not . hasMany) . anyTimes anyTimes :: Parser a -> Parser [a]-anyTimes parser = (parser >>= \x -> (x :) <$> anyTimes parser) <|> pure []+anyTimes p = ((:) <$> p <*> anyTimes p) <|> pure [] someTimes :: Parser a -> Parser [a] someTimes = check "someTimes" hasSome . anyTimes@@ -111,11 +112,12 @@ infixl 6 <#> (<#>) :: Parser a -> Integer -> Parser [a]-(<#>) = times+(<#>) = flip times infixl 6 >>> (>>>) :: (ToString a, ToString b) => Parser a -> Parser b -> Parser String-(>>>) p1 p2 = p1 >>= (\x -> (x ++) <$> (toString <$> p2)) . toString+(>>>) p1 p2 = (++) <$> (toString <$> p1)+ <*> (toString <$> p2) -- Parser Unary Operators