packages feed

construct 0.2.0.1 → 0.3

raw patch · 5 files changed

+22/−203 lines, 5 filesdep +input-parsersdep ~incremental-parserPVP ok

version bump matches the API change (PVP)

Dependencies added: input-parsers

Dependency ranges changed: incremental-parser

API changes (from Hackage documentation)

- Construct.Classes: anyToken :: InputParsing m => m (ParserInput m)
- Construct.Classes: class (CharParsing m, InputParsing m) => InputCharParsing m
- Construct.Classes: class LookAheadParsing m => InputParsing m where {
- Construct.Classes: concatMany :: (InputParsing m, Monoid a, Alternative m) => m a -> m a
- Construct.Classes: getInput :: InputParsing m => m (ParserInput m)
- Construct.Classes: instance (Data.Monoid.Factorial.FactorialMonoid s, Data.Semigroup.Cancellative.LeftReductive s, Text.Parser.LookAhead.LookAheadParsing (Text.ParserCombinators.Incremental.Parser t s)) => Construct.Classes.InputParsing (Text.ParserCombinators.Incremental.Parser t s)
- Construct.Classes: instance (Data.Monoid.Textual.TextualMonoid s, Data.Semigroup.Cancellative.LeftReductive s, Text.Parser.LookAhead.LookAheadParsing (Text.ParserCombinators.Incremental.Parser t s)) => Construct.Classes.InputCharParsing (Text.ParserCombinators.Incremental.Parser t s)
- Construct.Classes: instance Construct.Classes.InputCharParsing Data.Attoparsec.ByteString.Internal.Parser
- Construct.Classes: instance Construct.Classes.InputCharParsing Data.Attoparsec.Text.Internal.Parser
- Construct.Classes: instance Construct.Classes.InputCharParsing Text.ParserCombinators.ReadP.ReadP
- Construct.Classes: instance Construct.Classes.InputParsing Data.Attoparsec.ByteString.Internal.Parser
- Construct.Classes: instance Construct.Classes.InputParsing Data.Attoparsec.Text.Internal.Parser
- Construct.Classes: instance Construct.Classes.InputParsing Text.ParserCombinators.ReadP.ReadP
- Construct.Classes: notSatisfy :: InputParsing m => (ParserInput m -> Bool) -> m ()
- Construct.Classes: notSatisfyChar :: InputCharParsing m => (Char -> Bool) -> m ()
- Construct.Classes: satisfy :: InputParsing m => (ParserInput m -> Bool) -> m (ParserInput m)
- Construct.Classes: satisfyCharInput :: (InputCharParsing m, IsString (ParserInput m)) => (Char -> Bool) -> m (ParserInput m)
- Construct.Classes: scan :: (InputParsing m, Monad m, FactorialMonoid (ParserInput m)) => state -> (state -> ParserInput m -> Maybe state) -> m (ParserInput m)
- Construct.Classes: scanChars :: (InputCharParsing m, Monad m, TextualMonoid (ParserInput m)) => state -> (state -> Char -> Maybe state) -> m (ParserInput m)
- Construct.Classes: string :: (InputParsing m, Monad m, LeftReductive (ParserInput m), FactorialMonoid (ParserInput m), Show (ParserInput m)) => ParserInput m -> m (ParserInput m)
- Construct.Classes: take :: InputParsing m => Int -> m (ParserInput m)
- Construct.Classes: takeCharsWhile :: (InputCharParsing m, Monad m, TextualMonoid (ParserInput m)) => (Char -> Bool) -> m (ParserInput m)
- Construct.Classes: takeCharsWhile1 :: (InputCharParsing m, Monad m, TextualMonoid (ParserInput m)) => (Char -> Bool) -> m (ParserInput m)
- Construct.Classes: takeWhile :: (InputParsing m, Monad m, FactorialMonoid (ParserInput m)) => (ParserInput m -> Bool) -> m (ParserInput m)
- Construct.Classes: takeWhile1 :: (InputParsing m, Monad m, FactorialMonoid (ParserInput m)) => (ParserInput m -> Bool) -> m (ParserInput m)
- Construct.Classes: type family ParserInput m;
- Construct.Classes: }

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for construct +## 0.3 -- 2020-07-18++* Import the Input[Char]Parser classes from the `input-parsers` package+ ## 0.2.0.1 -- 2020-03-08  * Incremented the upper bound for the `rank2classes` dependency
construct.cabal view
@@ -1,6 +1,6 @@ cabal-version:       >=1.10 name:                construct-version:             0.2.0.1+version:             0.3 synopsis:            Haskell version of the Construct library for easy specification of file formats description:    A Haskell version of the <https://construct.readthedocs.io/en/latest/intro.html Construct> library for Python. A@@ -32,8 +32,9 @@                        bytestring >= 0.10 && < 0.11,                        text >= 0.10 && < 1.3,                        monoid-subclasses >= 1.0 && < 1.1,-                       incremental-parser >= 0.4 && < 0.5,+                       incremental-parser >= 0.5 && < 0.6,                        parsers >= 0.11 && < 0.13,+                       input-parsers < 0.2,                        attoparsec >= 0.12 && < 0.14,                        cereal >= 0.5 && < 0.6,                        rank2classes >= 1 && < 1.5@@ -48,7 +49,7 @@   other-modules:       README   ghc-options:         -threaded -pgmL markdown-unlit   build-depends:       base, construct,-                       bytestring >= 0.10 && < 0.11, incremental-parser >= 0.4 && < 0.5, rank2classes >= 1.0.2 && < 1.5,+                       bytestring >= 0.10 && < 0.11, incremental-parser >= 0.5 && < 0.6, rank2classes >= 1.0.2 && < 1.5,                        doctest >= 0.8   build-tool-depends:  markdown-unlit:markdown-unlit >= 0.5 && < 0.6   x-doctest-options:   -XTypeApplications@@ -58,7 +59,7 @@   hs-source-dirs:      test   build-depends:       base >=4.9 && < 5, construct,                        bytestring < 0.11, text < 1.3, cereal, rank2classes >= 1.0.2 && < 1.5,-                       monoid-subclasses >= 1.0 && < 1.1, incremental-parser < 0.5, attoparsec >= 0.12 && < 0.14,+                       monoid-subclasses >= 1.0 && < 1.1, incremental-parser < 0.6, attoparsec >= 0.12 && < 0.14,                        directory < 2, filepath < 1.5,                        tasty >= 0.7, tasty-hunit   main-is:             Test.hs
src/Construct.hs view
@@ -50,12 +50,14 @@ import Text.ParserCombinators.Incremental.Symmetric (Symmetric) import Data.Serialize (Serialize, Result(Done, Fail, Partial), Get, Putter, runGetPartial, runPut) import qualified Data.Serialize as Serialize+import Text.Parser.Input (InputParsing (ParserInput), InputCharParsing)+import qualified Text.Parser.Input as Input  import qualified Rank2 -import qualified Construct.Classes as Input-import Construct.Classes (AlternativeFail(failure), InputParsing (ParserInput), InputCharParsing, InputMappableParsing,-                          FixTraversable, Error, errorString, expectedName)+import Construct.Classes (AlternativeFail(failure), InputMappableParsing(mapParserInput, mapMaybeParserInput),+                          FixTraversable(fixSequence), Error,+                          errorString, expectedName) import Construct.Internal  import Prelude hiding (pred, take, takeWhile)@@ -234,7 +236,7 @@                   s ~ ParserInput (m s), t ~ ParserInput (m t), InputMappableParsing m, Functor n) =>                  (s -> t) -> (t -> s) -> Format (m s) n s a -> Format (m t) n t a mapSerialized f f' format = Format{-   parse = Input.mapParserInput f f' (parse format),+   parse = mapParserInput f f' (parse format),    serialize = (f <$>) . serialize format}  -- | Converts a format for serialized streams of type @s@ so it works for streams of type @t@ instead. The argument@@ -243,7 +245,7 @@                        s ~ ParserInput (m s), t ~ ParserInput (m t), InputMappableParsing m, Functor n) =>                       (s -> Maybe t) -> (t -> Maybe s) -> Format (m s) n s a -> Format (m t) n t a mapMaybeSerialized f f' format = Format{-   parse = Input.mapMaybeParserInput f f' (parse format),+   parse = mapMaybeParserInput f f' (parse format),    serialize = (fromMaybe (error "Partial serialization") . f <$>) . serialize format}  -- | Converts a format for in-memory values of type @a@ so it works for values of type @b@ instead.@@ -328,7 +330,7 @@               (forall a. o (n a) -> n a) -> g (Format m n s) -> Format m n s (g o) -- | Converts a record of field formats into a single format of the whole record, a generalized form of 'record'. recordWith collapse formats = Format{-   parse = Input.fixSequence (parse Rank2.<$> formats),+   parse = fixSequence (parse Rank2.<$> formats),    serialize = getAp . Rank2.foldMap Functor.getConst . Rank2.liftA2 serializeField formats    }    where serializeField :: forall a. Format m n s a -> o a -> Functor.Const (Ap n s) a
src/Construct/Bits.hs view
@@ -16,6 +16,7 @@ import qualified Data.ByteString as ByteString import qualified Data.List as List import Data.Word (Word8)+import Text.Parser.Input (InputParsing (ParserInput, anyToken))  import Construct import Construct.Classes
src/Construct/Classes.hs view
@@ -9,40 +9,13 @@ import qualified Text.ParserCombinators.Incremental as Incremental  import Control.Applicative (Alternative ((<|>), empty))-import Control.Monad (void)-import Data.String (IsString (fromString))-import Text.ParserCombinators.ReadP (ReadP)-import qualified Text.ParserCombinators.ReadP as ReadP--import Text.Parser.Char (CharParsing)-import Text.Parser.Combinators (count, eof, notFollowedBy, try, unexpected)-import Text.Parser.LookAhead (LookAheadParsing, lookAhead)-import qualified Text.Parser.Char as Char--import qualified Data.Monoid.Factorial as Factorial-import qualified Data.Monoid.Null as Null-import qualified Data.Monoid.Textual as Textual-import qualified Data.Semigroup.Cancellative as Cancellative-import Data.Monoid.Factorial (FactorialMonoid)-import Data.Monoid.Textual (TextualMonoid)-import Data.Semigroup.Cancellative (LeftReductive)--import Data.ByteString (ByteString)-import Data.Text (Text)-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as ByteString.Char8-import qualified Data.Text as Text- import qualified Data.Attoparsec.ByteString as Attoparsec-import qualified Data.Attoparsec.ByteString.Char8 as Attoparsec.Char8-import qualified Data.Attoparsec.Text as Attoparsec.Text--import Prelude hiding (take, takeWhile)+import Text.Parser.Input (InputParsing (ParserInput))  -- | Subclass of 'Alternative' that carries an error message in case of failure class Alternative m => AlternativeFail m where    -- | Equivalent to 'empty' except it takes an error message it may carry or drop on the floor. The grammatical form-   --  of the argument be a noun representing the unexpected value.+   --  of the argument should be a noun representing the unexpected value.    failure :: String -> m a    -- | Sets or modifies the expected value.    expectedName :: String -> m a -> m a@@ -50,115 +23,10 @@    failure = const empty    expectedName = const id --- | Methods for parsing factorial monoid inputs-class LookAheadParsing m => InputParsing m where-   type ParserInput m-   -- | Always sucessful parser that returns the remaining input without consuming it.-   getInput :: m (ParserInput m)--   -- | A parser that accepts any single atomic prefix of the input stream.-   -- > anyToken == satisfy (const True)-   -- > anyToken == take 1-   anyToken :: m (ParserInput m)-   -- | A parser that accepts exactly the given number of input atoms.-   take :: Int -> m (ParserInput m)-   -- | A parser that accepts an input atom only if it satisfies the given predicate.-   satisfy :: (ParserInput m -> Bool) -> m (ParserInput m)-   -- | A parser that succeeds exactly when satisfy doesn't, equivalent to-   -- 'Text.Parser.Combinators.notFollowedBy' @. satisfy@-   notSatisfy :: (ParserInput m -> Bool) -> m ()--   -- | A stateful scanner. The predicate modifies a state argument, and each transformed state is passed to successive-   -- invocations of the predicate on each token of the input until one returns 'Nothing' or the input ends.-   ---   -- This parser does not fail.  It will return an empty string if the predicate returns 'Nothing' on the first-   -- character.-   ---   -- /Note/: Because this parser does not fail, do not use it with combinators such as 'many', because such parsers-   -- loop until a failure occurs.  Careless use will thus result in an infinite loop.-   scan :: state -> (state -> ParserInput m -> Maybe state) -> m (ParserInput m)-   -- | A parser that consumes and returns the given prefix of the input.-   string :: ParserInput m -> m (ParserInput m)--   -- | A parser accepting the longest sequence of input atoms that match the given predicate; an optimized version of-   -- 'concatMany . satisfy'.-   ---   -- /Note/: Because this parser does not fail, do not use it with combinators such as 'many', because such parsers-   -- loop until a failure occurs.  Careless use will thus result in an infinite loop.-   takeWhile :: (ParserInput m -> Bool) -> m (ParserInput m)-   -- | A parser accepting the longest non-empty sequence of input atoms that match the given predicate; an optimized-   -- version of 'concatSome . satisfy'.-   takeWhile1 :: (ParserInput m -> Bool) -> m (ParserInput m)-   -- | Zero or more argument occurrences like 'many', with concatenated monoidal results.-   concatMany :: Monoid a => m a -> m a--   anyToken = take 1-   notSatisfy predicate = try (void $ satisfy $ not . predicate) <|> eof-   default concatMany :: (Monoid a, Alternative m) => m a -> m a-   concatMany p = go-      where go = mappend <$> try p <*> go <|> pure mempty--   default string :: (Monad m, LeftReductive (ParserInput m), FactorialMonoid (ParserInput m), Show (ParserInput m))-                  => ParserInput m -> m (ParserInput m)-   string s = do i <- getInput-                 if s `Cancellative.isPrefixOf` i-                    then take (Factorial.length s)-                    else unexpected ("string " <> show s)-   default scan :: (Monad m, FactorialMonoid (ParserInput m)) =>-                   state -> (state -> ParserInput m -> Maybe state) -> m (ParserInput m)-   scan state f = do i <- getInput-                     let (prefix, _suffix, _state) = Factorial.spanMaybe' state f i-                     take (Factorial.length prefix)-   default takeWhile :: (Monad m, FactorialMonoid (ParserInput m)) => (ParserInput m -> Bool) -> m (ParserInput m)-   takeWhile predicate = do i <- getInput-                            take (Factorial.length $ Factorial.takeWhile predicate i)-   default takeWhile1 :: (Monad m, FactorialMonoid (ParserInput m)) => (ParserInput m -> Bool) -> m (ParserInput m)-   takeWhile1 predicate = do x <- takeWhile predicate-                             if Null.null x then unexpected "takeWhile1" else pure x-   {-# INLINE concatMany #-}---- | Methods for parsing textual monoid inputs-class (CharParsing m, InputParsing m) => InputCharParsing m where-   -- | Specialization of 'satisfy' on textual inputs, accepting an input character only if it satisfies the given-   -- predicate, and returning the input atom that represents the character. Equivalent to @fmap singleton-   -- . Char.satisfy@-   satisfyCharInput :: (Char -> Bool) -> m (ParserInput m)-   -- | A parser that succeeds exactly when satisfy doesn't, equivalent to @notFollowedBy . Char.satisfy@-   notSatisfyChar :: (Char -> Bool) -> m ()--   -- | Stateful scanner like `scan`, but specialized for 'TextualMonoid' inputs.-   scanChars :: state -> (state -> Char -> Maybe state) -> m (ParserInput m)--   -- | Specialization of 'takeWhile' on 'TextualMonoid' inputs, accepting the longest sequence of input characters that-   -- match the given predicate; an optimized version of @fmap fromString  . many . Char.satisfy@.-   ---   -- /Note/: Because this parser does not fail, do not use it with combinators such as 'many', because such parsers-   -- loop until a failure occurs.  Careless use will thus result in an infinite loop.-   takeCharsWhile :: (Char -> Bool) -> m (ParserInput m)-   -- | Specialization of 'takeWhile1' on 'TextualMonoid' inputs, accepting the longest sequence of input characters-   -- that match the given predicate; an optimized version of @fmap fromString  . some . Char.satisfy@.-   takeCharsWhile1 :: (Char -> Bool) -> m (ParserInput m)--   default satisfyCharInput :: IsString (ParserInput m) => (Char -> Bool) -> m (ParserInput m)-   satisfyCharInput = fmap (fromString . (:[])) . Char.satisfy-   notSatisfyChar = notFollowedBy . Char.satisfy-   default scanChars :: (Monad m, TextualMonoid (ParserInput m)) =>-                        state -> (state -> Char -> Maybe state) -> m (ParserInput m)-   scanChars state f = do i <- getInput-                          let (prefix, _suffix, _state) = Textual.spanMaybe' state (const $ const Nothing) f i-                          take (Factorial.length prefix)--   default takeCharsWhile :: (Monad m, TextualMonoid (ParserInput m)) => (Char -> Bool) -> m (ParserInput m)-   takeCharsWhile predicate = do i <- getInput-                                 take (Factorial.length $ Textual.takeWhile_ False predicate i)-   default takeCharsWhile1 :: (Monad m, TextualMonoid (ParserInput m)) => (Char -> Bool) -> m (ParserInput m)-   takeCharsWhile1 predicate = do x <- takeCharsWhile predicate-                                  if Null.null x then unexpected "takeCharsWhile1" else pure x- -- | A subclass of 'InputParsing' for parsers that can switch the input stream type class InputMappableParsing m where-   -- | Converts a parser accepting one input stream type to another. The functions @forth@ and @back@ must be inverses of-   -- each other and they must distribute through '<>':+   -- | Converts a parser accepting one input stream type to another. The functions @forth@ and @back@ must be+   -- inverses of each other and they must distribute through '<>':    --    -- > f (s1 <> s2) == f s1 <> f s2    mapParserInput :: (InputParsing (m s), s ~ ParserInput (m s), Monoid s, Monoid s') =>@@ -214,63 +82,6 @@ oxfordComma :: String -> [String] -> String oxfordComma e [] = "or " <> e oxfordComma e (e':es) = e <> ", " <> oxfordComma e' es--instance InputParsing ReadP where-   type ParserInput ReadP = String-   getInput = ReadP.look-   take n = count n ReadP.get-   anyToken = pure <$> ReadP.get-   satisfy predicate = pure <$> ReadP.satisfy (predicate . pure)-   string = ReadP.string--instance InputCharParsing ReadP where-   satisfyCharInput predicate = pure <$> ReadP.satisfy predicate--instance InputParsing Attoparsec.Parser where-   type ParserInput Attoparsec.Parser = ByteString-   getInput = lookAhead Attoparsec.takeByteString-   anyToken = Attoparsec.take 1-   take = Attoparsec.take-   satisfy predicate = Attoparsec.satisfyWith ByteString.singleton predicate-   string = Attoparsec.string--instance InputCharParsing Attoparsec.Parser where-   satisfyCharInput predicate = ByteString.Char8.singleton <$> Attoparsec.Char8.satisfy predicate-   scanChars = Attoparsec.Char8.scan-   takeCharsWhile = Attoparsec.Char8.takeWhile-   takeCharsWhile1 = Attoparsec.Char8.takeWhile1--instance InputParsing Attoparsec.Text.Parser where-   type ParserInput Attoparsec.Text.Parser = Text-   getInput = lookAhead Attoparsec.Text.takeText-   anyToken = Attoparsec.Text.take 1-   take = Attoparsec.Text.take-   satisfy predicate = Attoparsec.Text.satisfyWith Text.singleton predicate-   string = Attoparsec.Text.string--instance InputCharParsing Attoparsec.Text.Parser where-   satisfyCharInput predicate = Text.singleton <$> Attoparsec.Text.satisfy predicate-   scanChars = Attoparsec.Text.scan-   takeCharsWhile = Attoparsec.Text.takeWhile-   takeCharsWhile1 = Attoparsec.Text.takeWhile1--instance (FactorialMonoid s, Cancellative.LeftReductive s, LookAheadParsing (Incremental.Parser t s)) =>-         InputParsing (Incremental.Parser t s) where-   type ParserInput (Incremental.Parser t s) = s-   getInput = lookAhead Incremental.acceptAll-   anyToken = Incremental.anyToken-   take n = Incremental.count n Incremental.anyToken-   satisfy = Incremental.satisfy-   string = Incremental.string-   takeWhile = Incremental.takeWhile-   takeWhile1 = Incremental.takeWhile1-   concatMany = Incremental.concatMany--instance (TextualMonoid s, Cancellative.LeftReductive s, LookAheadParsing (Incremental.Parser t s)) =>-         InputCharParsing (Incremental.Parser t s) where-   satisfyCharInput = Incremental.satisfyChar-   takeCharsWhile = Incremental.takeCharsWhile-   takeCharsWhile1 = Incremental.takeCharsWhile1  instance FixTraversable Attoparsec.Parser