input-parsers 0.1.0.1 → 0.2
raw patch · 4 files changed
+51/−27 lines, 4 filesdep ~bytestringdep ~monoid-subclassesPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: bytestring, monoid-subclasses
API changes (from Hackage documentation)
- Text.Parser.Input: data Position
- Text.Parser.Input.Position: data Position
- Text.Parser.Input.Position: instance GHC.Classes.Eq Text.Parser.Input.Position.Position
- Text.Parser.Input.Position: instance GHC.Read.Read Text.Parser.Input.Position.Position
- Text.Parser.Input.Position: instance GHC.Show.Show Text.Parser.Input.Position.Position
+ Text.Parser.Input: type ParserPosition m = Dual Int;
+ Text.Parser.Input.Position: class Position p
+ Text.Parser.Input.Position: instance Text.Parser.Input.Position.Position GHC.Types.Int
+ Text.Parser.Input.Position: instance Text.Parser.Input.Position.Position a => Text.Parser.Input.Position.Position (Data.Semigroup.Internal.Dual a)
- Text.Parser.Input: getSourcePos :: (InputParsing m, FactorialMonoid (ParserInput m), Functor m) => m Position
+ Text.Parser.Input: getSourcePos :: (InputParsing m, FactorialMonoid (ParserInput m), Functor m, ParserPosition m ~ Dual Int) => m (ParserPosition m)
- Text.Parser.Input: type family ParserInput m;
+ Text.Parser.Input: type family ParserPosition m;
- Text.Parser.Input.Position: context :: (Eq s, TextualMonoid s) => s -> Position -> Int -> s
+ Text.Parser.Input.Position: context :: (Eq s, TextualMonoid s, Position p) => s -> p -> Int -> s
- Text.Parser.Input.Position: fromEnd :: Int -> Position
+ Text.Parser.Input.Position: fromEnd :: Int -> Dual Int
- Text.Parser.Input.Position: fromStart :: Int -> Position
+ Text.Parser.Input.Position: fromStart :: Int -> Int
- Text.Parser.Input.Position: lineAndColumn :: (Eq s, IsString s, FactorialMonoid s) => s -> Position -> ([s], Int)
+ Text.Parser.Input.Position: lineAndColumn :: (Eq s, IsString s, FactorialMonoid s, Position p) => s -> p -> ([s], Int)
- Text.Parser.Input.Position: offset :: FactorialMonoid s => s -> Position -> Int
+ Text.Parser.Input.Position: offset :: (Position p, FactorialMonoid s) => s -> p -> Int
Files
- CHANGELOG.md +4/−0
- input-parsers.cabal +3/−3
- src/Text/Parser/Input.hs +17/−4
- src/Text/Parser/Input/Position.hs +27/−20
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for input-parsers +## 0.2 -- 2021-03-07++* Added `ParserPosition` and made `Position` a class.+ ## 0.1.0.1 -- 2020-07-19 * Incremented the upper bound of `base` dependency.
input-parsers.cabal view
@@ -1,6 +1,6 @@ cabal-version: >=1.10 name: input-parsers-version: 0.1.0.1+version: 0.2 synopsis: Extension of the parsers library with more capability and efficiency description: Extended version of the parsers library, with the additional classes providing more@@ -36,8 +36,8 @@ Text.Parser.Input.Position, Text.Parser.Wrapper other-modules: Text.Parser.Internal- build-depends: base >=4.9 && <5, bytestring >=0.10 && <0.11, text >=1.2 && <1.3,- monoid-subclasses >= 1.0 && < 1.1, parsers >= 0.12 && < 0.13,+ build-depends: base >=4.9 && <5, bytestring >=0.10 && <0.12, text >=1.2 && <1.3,+ monoid-subclasses >= 1.0 && < 1.2, parsers >= 0.12 && < 0.13, transformers >=0.2 && <0.6 if flag(binary) build-depends: binary >= 0.7.2 && < 1
src/Text/Parser/Input.hs view
@@ -12,7 +12,7 @@ -- | Parsers that can consume and return a prefix of their input. module Text.Parser.Input (InputParsing(..), InputCharParsing(..), ConsumedInputParsing(..),- Lazy(..), Strict(..), Position) where+ Lazy(..), Strict(..)) where import Control.Applicative (Applicative ((<*>), pure), Alternative ((<|>), empty), (<**>)) import Control.Monad (MonadPlus, void)@@ -27,7 +27,7 @@ import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST(RWST)) import Data.Functor ((<$>)) import qualified Data.List as List-import Data.Monoid (Monoid, mappend, mempty)+import Data.Monoid (Monoid, Dual, mappend, mempty) import Data.String (IsString (fromString)) import Text.ParserCombinators.ReadP (ReadP) import qualified Text.ParserCombinators.ReadP as ReadP@@ -79,10 +79,11 @@ class LookAheadParsing m => InputParsing m where -- | The type of the input stream that the parser @m@ expects to parse. type ParserInput m+ type ParserPosition m -- | Always sucessful parser that returns the entire remaining input without consuming it. getInput :: m (ParserInput m) -- | Retrieve the 'Position' reached by the parser in the input source.- getSourcePos :: m Position+ getSourcePos :: m (ParserPosition m) -- | A parser that accepts any single atomic prefix of the input stream. --@@ -121,7 +122,9 @@ -- version of 'concat' @.@ 'Control.Applicative.some' @.@ 'satisfy'. takeWhile1 :: (ParserInput m -> Bool) -> m (ParserInput m) - default getSourcePos :: (FactorialMonoid (ParserInput m), Functor m) => m Position+ type ParserPosition m = Dual Int+ default getSourcePos :: (FactorialMonoid (ParserInput m), Functor m, ParserPosition m ~ Dual Int)+ => m (ParserPosition m) getSourcePos = fromEnd . Factorial.length <$> getInput anyToken = take 1 default satisfy :: Monad m => (ParserInput m -> Bool) -> m (ParserInput m)@@ -202,6 +205,7 @@ instance (Monad m, InputParsing m) => InputParsing (IdentityT m) where type ParserInput (IdentityT m) = ParserInput m+ type ParserPosition (IdentityT m) = ParserPosition m getInput = IdentityT getInput getSourcePos = IdentityT getSourcePos anyToken = IdentityT anyToken@@ -225,6 +229,7 @@ instance (MonadPlus m, InputParsing m) => InputParsing (ReaderT e m) where type ParserInput (ReaderT e m) = ParserInput m+ type ParserPosition (ReaderT e m) = ParserPosition m getInput = lift getInput getSourcePos = lift getSourcePos anyToken = lift anyToken@@ -248,6 +253,7 @@ instance (MonadPlus m, InputParsing m, Monoid w) => InputParsing (Lazy.WriterT w m) where type ParserInput (Lazy.WriterT w m) = ParserInput m+ type ParserPosition (Lazy.WriterT w m) = ParserPosition m getInput = lift getInput getSourcePos = lift getSourcePos anyToken = lift anyToken@@ -271,6 +277,7 @@ instance (MonadPlus m, InputParsing m, Monoid w) => InputParsing (Strict.WriterT w m) where type ParserInput (Strict.WriterT w m) = ParserInput m+ type ParserPosition (Strict.WriterT w m) = ParserPosition m getInput = lift getInput getSourcePos = lift getSourcePos anyToken = lift anyToken@@ -294,6 +301,7 @@ instance (MonadPlus m, InputParsing m) => InputParsing (Lazy.StateT s m) where type ParserInput (Lazy.StateT s m) = ParserInput m+ type ParserPosition (Lazy.StateT s m) = ParserPosition m getInput = lift getInput getSourcePos = lift getSourcePos anyToken = lift anyToken@@ -317,6 +325,7 @@ instance (MonadPlus m, InputParsing m) => InputParsing (Strict.StateT s m) where type ParserInput (Strict.StateT s m) = ParserInput m+ type ParserPosition (Strict.StateT s m) = ParserPosition m getInput = lift getInput getSourcePos = lift getSourcePos anyToken = lift anyToken@@ -340,6 +349,7 @@ instance (MonadPlus m, InputParsing m, Monoid w) => InputParsing (Lazy.RWST r w s m) where type ParserInput (Lazy.RWST r w s m) = ParserInput m+ type ParserPosition (Lazy.RWST r w s m) = ParserPosition m getInput = lift getInput getSourcePos = lift getSourcePos anyToken = lift anyToken@@ -363,6 +373,7 @@ instance (MonadPlus m, InputParsing m, Monoid w) => InputParsing (Strict.RWST r w s m) where type ParserInput (Strict.RWST r w s m) = ParserInput m+ type ParserPosition (Strict.RWST r w s m) = ParserPosition m getInput = lift getInput getSourcePos = lift getSourcePos anyToken = lift anyToken@@ -448,6 +459,7 @@ #ifdef MIN_VERSION_binary instance InputParsing (Lazy Binary.Get) where type ParserInput (Lazy Binary.Get) = Lazy.ByteString+ type ParserPosition (Lazy Binary.Get) = Int getInput = Lazy (Binary.lookAhead Binary.getRemainingLazyByteString) getSourcePos = Lazy (fromStart . fromIntegral <$> Binary.bytesRead) anyToken = Lazy (Binary.getLazyByteString 1)@@ -455,6 +467,7 @@ instance InputParsing (Strict Binary.Get) where type ParserInput (Strict Binary.Get) = ByteString+ type ParserPosition (Strict Binary.Get) = Int getInput = Strict (Lazy.toStrict <$> Binary.lookAhead Binary.getRemainingLazyByteString) getSourcePos = Strict (fromStart . fromIntegral <$> Binary.bytesRead) anyToken = Strict (Binary.getByteString 1)
src/Text/Parser/Input/Position.hs view
@@ -7,37 +7,44 @@ import Data.Char (isSpace) import Data.String (IsString(fromString))+import Data.Monoid (Dual(Dual)) import qualified Data.Monoid.Factorial as Factorial import qualified Data.Monoid.Textual as Textual import Data.Monoid.Factorial (FactorialMonoid) import Data.Monoid.Textual (TextualMonoid) --- | Opaque data type that represents an input position.-data Position = PositionFromStart !Int- -- ^ the length of the input from the start to the position- | PositionFromEnd Int- -- ^ the length of the input from the position to end- deriving (Eq, Read, Show)+-- | A class for representing position values.+--+-- > move (distance pos1 pos2) pos1 == pos2+class Position p where+ -- | Distance from the first position to the second+ distance :: p -> p -> Int+ -- | Move the position by the given distance.+ move :: Int -> p -> p+ -- | Map the position into its offset from the beginning of the full input.+ offset :: FactorialMonoid s => s -> p -> Int +instance Position Int where+ distance = flip (-)+ move = (+)+ offset = const id++instance Position a => Position (Dual a) where+ distance (Dual p1) (Dual p2) = distance p2 p1+ move distance (Dual p) = Dual (move (negate distance) p)+ offset wholeInput (Dual p) = Factorial.length wholeInput - offset wholeInput p+ -- | Construct a 'Position' given the offset from the beginning of the full input.-fromStart :: Int -> Position-fromStart = PositionFromStart+fromStart :: Int -> Int+fromStart = id -- | Construct a 'Position' given the length remaining from the position to the end of the input.-fromEnd :: Int -> Position-fromEnd = PositionFromEnd---- | Map the position into its offset from the beginning of the full input.------ > offset input . fromStart === id-offset :: FactorialMonoid s => s -> Position -> Int-offset wholeInput (PositionFromStart offset) = offset-offset wholeInput (PositionFromEnd remainderLength) = Factorial.length wholeInput - remainderLength-{-# INLINE offset #-}+fromEnd :: Int -> Dual Int+fromEnd = Dual -- | Given the parser input, a 'Position' within it, and desired number of context lines, returns a description of -- the offset position in English.-context :: (Eq s, TextualMonoid s) => s -> Position -> Int -> s+context :: (Eq s, TextualMonoid s, Position p) => s -> p -> Int -> s context input pos contextLineCount = foldMap (<> "\n") prevLines <> lastLinePadding <> "at line " <> fromString (show $ length allPrevLines) <> ", column " <> fromString (show $ column+1) <> "\n"@@ -50,7 +57,7 @@ -- | Given the full input and an offset within it, returns all the input lines up to and including the offset -- in reverse order, as well as the zero-based column number of the offset-lineAndColumn :: (Eq s, IsString s, FactorialMonoid s) => s -> Position -> ([s], Int)+lineAndColumn :: (Eq s, IsString s, FactorialMonoid s, Position p) => s -> p -> ([s], Int) lineAndColumn input pos = context [] (offset input pos) (Factorial.split (== "\n") input) where context revLines restCount [] | restCount > 0 = (["Error: the offset is beyond the input length"], -1)