packages feed

grammatical-parsers 0.2 → 0.2.1

raw patch · 10 files changed

+1164/−213 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Text.Grampa.ContextFree.LeftRecursive: instance Text.Grampa.Class.MonoidParsing (Text.Grampa.ContextFree.LeftRecursive.Fixed Text.Grampa.PEG.Backtrack.Length.Parser g)
- Text.Grampa.ContextFree.Memoizing: instance (GHC.Show.Show s, GHC.Show.Show r) => GHC.Show.Show (Text.Grampa.ContextFree.Memoizing.ResultInfo g s r)
- Text.Grampa.ContextFree.Memoizing: instance (GHC.Show.Show s, GHC.Show.Show r) => GHC.Show.Show (Text.Grampa.ContextFree.Memoizing.ResultList g s r)
+ Text.Grampa.ContextFree.Continued: NoParse :: FailureInfo -> Result s v
+ Text.Grampa.ContextFree.Continued: Parsed :: !v -> !s -> Result s v
+ Text.Grampa.ContextFree.Continued: Parser :: (forall x. s -> (r -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x) -> Parser s r
+ Text.Grampa.ContextFree.Continued: [applyParser] :: Parser s r -> forall x. s -> (r -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x
+ Text.Grampa.ContextFree.Continued: [parsedPrefix] :: Result s v -> !v
+ Text.Grampa.ContextFree.Continued: [parsedSuffix] :: Result s v -> !s
+ Text.Grampa.ContextFree.Continued: alt :: forall g s a. Parser g s a -> Parser g s a -> Parser g s a
+ Text.Grampa.ContextFree.Continued: data Result (g :: (* -> *) -> *) s v
+ Text.Grampa.ContextFree.Continued: instance (GHC.Show.Show s, Data.Monoid.Textual.TextualMonoid s) => Text.Parser.Char.CharParsing (Text.Grampa.ContextFree.Continued.Parser g s)
+ Text.Grampa.ContextFree.Continued: instance (GHC.Show.Show s, Data.Monoid.Textual.TextualMonoid s) => Text.Parser.Token.TokenParsing (Text.Grampa.ContextFree.Continued.Parser g s)
+ Text.Grampa.ContextFree.Continued: instance Data.Functor.Classes.Show1 (Text.Grampa.ContextFree.Continued.Result g s)
+ Text.Grampa.ContextFree.Continued: instance Data.Monoid.Factorial.FactorialMonoid s => GHC.Base.Alternative (Text.Grampa.ContextFree.Continued.Parser g s)
+ Text.Grampa.ContextFree.Continued: instance Data.Monoid.Factorial.FactorialMonoid s => GHC.Base.MonadPlus (Text.Grampa.ContextFree.Continued.Parser g s)
+ Text.Grampa.ContextFree.Continued: instance Data.Monoid.Factorial.FactorialMonoid s => Text.Parser.Combinators.Parsing (Text.Grampa.ContextFree.Continued.Parser g s)
+ Text.Grampa.ContextFree.Continued: instance Data.Monoid.Factorial.FactorialMonoid s => Text.Parser.LookAhead.LookAheadParsing (Text.Grampa.ContextFree.Continued.Parser g s)
+ Text.Grampa.ContextFree.Continued: instance GHC.Base.Applicative (Text.Grampa.ContextFree.Continued.Parser g s)
+ Text.Grampa.ContextFree.Continued: instance GHC.Base.Functor (Text.Grampa.ContextFree.Continued.Parser g s)
+ Text.Grampa.ContextFree.Continued: instance GHC.Base.Functor (Text.Grampa.ContextFree.Continued.Result g s)
+ Text.Grampa.ContextFree.Continued: instance GHC.Base.Monad (Text.Grampa.ContextFree.Continued.Parser g s)
+ Text.Grampa.ContextFree.Continued: instance GHC.Base.Monoid x => GHC.Base.Monoid (Text.Grampa.ContextFree.Continued.Parser g s x)
+ Text.Grampa.ContextFree.Continued: instance Text.Grampa.Class.MonoidParsing (Text.Grampa.ContextFree.Continued.Parser g)
+ Text.Grampa.ContextFree.Continued: instance Text.Grampa.Class.MultiParsing Text.Grampa.ContextFree.Continued.Parser
+ Text.Grampa.ContextFree.Continued: newtype Parser (g :: (* -> *) -> *) s r
+ Text.Grampa.ContextFree.LeftRecursive: instance Text.Grampa.Class.MonoidParsing (Text.Grampa.ContextFree.LeftRecursive.Fixed Text.Grampa.PEG.Backtrack.Measured.Parser g)
+ Text.Grampa.ContextFree.Memoizing: instance GHC.Show.Show r => GHC.Show.Show (Text.Grampa.ContextFree.Memoizing.ResultInfo g s r)
+ Text.Grampa.ContextFree.Memoizing: instance GHC.Show.Show r => GHC.Show.Show (Text.Grampa.ContextFree.Memoizing.ResultList g s r)
- Text.Grampa.ContextFree.LeftRecursive: longest :: FactorialMonoid s => Fixed Parser g s a -> Fixed Parser g [(s, g (ResultList g s))] a
+ Text.Grampa.ContextFree.LeftRecursive: longest :: Fixed Parser g s a -> Fixed Parser g [(s, g (ResultList g s))] a
- Text.Grampa.ContextFree.Memoizing: longest :: FactorialMonoid s => Parser g s a -> Parser g [(s, g (ResultList g s))] a
+ Text.Grampa.ContextFree.Memoizing: longest :: Parser g s a -> Parser g [(s, g (ResultList g s))] a

Files

grammatical-parsers.cabal view
@@ -1,5 +1,5 @@ name:                grammatical-parsers-version:             0.2+version:             0.2.1 synopsis:            parsers that can combine into grammars description:   /Gram/matical-/pa/rsers, or Grampa for short, is a library of parser types whose values are meant to be assigned@@ -25,9 +25,12 @@   hs-source-dirs:      src   exposed-modules:     Text.Grampa,                        Text.Grampa.PEG.Backtrack, Text.Grampa.PEG.Packrat,-                       Text.Grampa.ContextFree.Parallel, Text.Grampa.ContextFree.Memoizing,-                       Text.Grampa.ContextFree.LeftRecursive-  other-modules:       Text.Grampa.Class, Text.Grampa.Internal, Text.Grampa.PEG.Backtrack.Length+                       Text.Grampa.ContextFree.Continued, Text.Grampa.ContextFree.Parallel,+                       Text.Grampa.ContextFree.Memoizing, Text.Grampa.ContextFree.LeftRecursive+  other-modules:       Text.Grampa.Class, Text.Grampa.Internal,+                       Text.Grampa.PEG.Backtrack.Measured,+                       Text.Grampa.PEG.Continued, Text.Grampa.PEG.Continued.Measured,+                       Text.Grampa.ContextFree.Continued.Measured   default-language:    Haskell2010   -- other-modules:   ghc-options:         -Wall
+ src/Text/Grampa/ContextFree/Continued.hs view
@@ -0,0 +1,230 @@+{-# LANGUAGE InstanceSigs, RankNTypes, ScopedTypeVariables, TypeFamilies #-}+-- | Continuation-passing parser for context-free grammars+module Text.Grampa.ContextFree.Continued (Parser(..), Result(..), alt) where++import Control.Applicative (Applicative(..), Alternative(..), liftA2)+import Control.Monad (Monad(..), MonadPlus(..))++import Data.Char (isSpace)+import Data.Functor.Classes (Show1(..))+import Data.Functor.Compose (Compose(..))+import Data.List (nub)+import Data.Monoid (Monoid(mappend, mempty), (<>))+import Data.Monoid.Factorial(FactorialMonoid)+import Data.Monoid.Textual(TextualMonoid)+import Data.String (fromString)++import qualified Data.Monoid.Cancellative as Cancellative+import qualified Data.Monoid.Factorial as Factorial+import qualified Data.Monoid.Null as Null+import qualified Data.Monoid.Textual as Textual++import qualified Rank2++import qualified Text.Parser.Char+import Text.Parser.Char (CharParsing)+import Text.Parser.Combinators (Parsing(..))+import Text.Parser.LookAhead (LookAheadParsing(..))+import Text.Parser.Token (TokenParsing(someSpace))+import Text.Grampa.Class (MonoidParsing(..), MultiParsing(..), ParseResults, ParseFailure(..))+import Text.Grampa.Internal (FailureInfo(..))++data Result (g :: (* -> *) -> *) s v = Parsed{parsedPrefix :: !v,+                                              parsedSuffix :: !s}+                                     | NoParse FailureInfo++-- | Parser type for context-free grammars that uses a continuation-passing algorithm, fast for grammars in LL(1)+-- class but with potentially exponential performance for longer ambiguous prefixes.+newtype Parser (g :: (* -> *) -> *) s r =+   Parser{applyParser :: forall x. s -> (r -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x}++instance Show1 (Result g s) where+   liftShowsPrec showsPrecSub _showList prec Parsed{parsedPrefix= r} rest = "Parsed " ++ showsPrecSub prec r rest+   liftShowsPrec _showsPrec _showList _prec (NoParse f) rest = "NoParse " ++ shows f rest++instance Functor (Result g s) where+   fmap f (Parsed a rest) = Parsed (f a) rest+   fmap _ (NoParse failure) = NoParse failure+   +instance Functor (Parser g s) where+   fmap f (Parser p) = Parser (\input success-> p input (success . f))+   {-# INLINABLE fmap #-}++instance Applicative (Parser g s) where+   pure a = Parser (\input success failure-> success a input failure)+   (<*>) :: forall a b. Parser g s (a -> b) -> Parser g s a -> Parser g s b+   Parser p <*> Parser q = Parser r where+      r :: forall x. s -> (b -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+      r rest success failure = p rest (\f rest'-> q rest' (success . f)) failure+   {-# INLINABLE (<*>) #-}++instance Factorial.FactorialMonoid s => Alternative (Parser g s) where+   empty = Parser (\rest _ failure-> failure $ FailureInfo 0 (fromIntegral $ Factorial.length rest) ["empty"])+   (<|>) = alt++-- | A named and unconstrained version of the '<|>' operator+alt :: forall g s a. Parser g s a -> Parser g s a -> Parser g s a+Parser p `alt` Parser q = Parser r where+   r :: forall x. s -> (a -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+   r rest success failure = p rest success' failure'+      where success' a rest' _ = success a rest' failure'+            failure' f1 = q rest success (\f2 -> failure (f1 <> f2))++instance Monad (Parser g s) where+   return = pure+   (>>=) :: forall a b. Parser g s a -> (a -> Parser g s b) -> Parser g s b+   Parser p >>= f = Parser r where+      r :: forall x. s -> (b -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+      r rest success failure = p rest (\a rest'-> applyParser (f a) rest' success) failure++instance Factorial.FactorialMonoid s => MonadPlus (Parser g s) where+   mzero = empty+   mplus = (<|>)++instance Monoid x => Monoid (Parser g s x) where+   mempty = pure mempty+   mappend = liftA2 mappend++instance Factorial.FactorialMonoid s => Parsing (Parser g s) where+   try = id+   (<?>) = const+   eof = endOfInput+   unexpected msg = Parser (\t _ failure -> failure $ FailureInfo 0 (fromIntegral $ Factorial.length t) [msg])+   notFollowedBy (Parser p) = Parser q+      where q :: forall x. s -> (() -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            q input success failure = p input success' failure'+               where success' _ _ _ = failure (FailureInfo 1 (fromIntegral $ Factorial.length input) ["notFollowedBy"])+                     failure' _ = success () input failure++instance Factorial.FactorialMonoid s => LookAheadParsing (Parser g s) where+   lookAhead :: forall a. Parser g s a -> Parser g s a+   lookAhead (Parser p) = Parser q+      where q :: forall x. s -> (a -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            q input success failure = p input success' failure'+               where success' a _ = success a input+                     failure' f = failure f++instance (Show s, TextualMonoid s) => CharParsing (Parser g s) where+   satisfy = satisfyChar+   string s = Textual.toString (error "unexpected non-character") <$> string (fromString s)+   char = satisfyChar . (==)+   notChar = satisfyChar . (/=)+   anyChar = satisfyChar (const True)+   text t = (fromString . Textual.toString (error "unexpected non-character")) <$> string (Textual.fromText t)++instance (Show s, TextualMonoid s) => TokenParsing (Parser g s) where+   someSpace = () <$ takeCharsWhile1 isSpace++instance MonoidParsing (Parser g) where+   endOfInput = Parser p+      where p rest success failure+               | Null.null rest = success () rest failure+               | otherwise = failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["endOfInput"])+   getInput = Parser p+      where p rest success failure = success rest mempty failure+   anyToken = Parser p+      where p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, suffix) -> success first suffix failure+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["anyToken"])+   satisfy :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   satisfy predicate = Parser p+      where p :: forall x. s -> (s -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, suffix) | predicate first -> success first suffix failure+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfy"])+   satisfyChar :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s Char+   satisfyChar predicate = Parser p+      where p :: forall x. s -> (Char -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> success first suffix failure+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   satisfyCharInput :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   satisfyCharInput predicate = Parser p+      where p :: forall x. s -> (s -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> success (Factorial.primePrefix rest) suffix failure+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   notSatisfy :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s ()+   notSatisfy predicate = Parser p+      where p :: forall x. s -> (() -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, _)+                     | predicate first -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["notSatisfy"])+                  _ -> success () rest failure+   notSatisfyChar :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s ()+   notSatisfyChar predicate = Parser p+      where p :: forall x. s -> (() -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.characterPrefix rest+               of Just first | predicate first+                               -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["notSatisfyChar"])+                  _ -> success () rest failure+   scan :: forall t s. FactorialMonoid t => s -> (s -> t -> Maybe s) -> Parser g t t+   scan s0 f = Parser (p s0)+      where p :: forall x. s -> t -> (t -> t -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p s rest success failure = success prefix suffix failure+               where (prefix, suffix, _) = Factorial.spanMaybe' s f rest+   scanChars :: forall t s. TextualMonoid t => s -> (s -> Char -> Maybe s) -> Parser g t t+   scanChars s0 f = Parser (p s0)+      where p :: forall x. s -> t -> (t -> t -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p s rest success failure = success prefix suffix failure+               where (prefix, suffix, _) = Textual.spanMaybe_' s f rest+   takeWhile :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   takeWhile predicate = Parser p+      where p :: forall x. s -> (s -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure | (prefix, suffix) <- Factorial.span predicate rest = success prefix suffix failure+   takeWhile1 :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   takeWhile1 predicate = Parser p+      where p :: forall x. s -> (s -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | (prefix, suffix) <- Factorial.span predicate rest =+                    if Null.null prefix+                    then failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeWhile1"])+                    else success prefix suffix failure+   takeCharsWhile :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   takeCharsWhile predicate = Parser p+      where p :: forall x. s -> (s -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | (prefix, suffix) <- Textual.span_ False predicate rest = success prefix suffix failure+   takeCharsWhile1 :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   takeCharsWhile1 predicate = Parser p+      where p :: forall x. s -> (s -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | Null.null prefix = failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeCharsWhile1"])+               | otherwise = success prefix suffix failure+               where (prefix, suffix) = Textual.span_ False predicate rest+   string :: forall s. (Cancellative.LeftReductiveMonoid s, FactorialMonoid s, Show s) => s -> Parser g s s+   string s = Parser p where+      p :: forall x. s -> (s -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+      p s' success failure+         | Just suffix <- Cancellative.stripPrefix s s' = success s suffix failure+         | otherwise = failure (FailureInfo 1 (fromIntegral $ Factorial.length s') ["string " ++ show s])+   whiteSpace = () <$ takeCharsWhile isSpace+   concatMany :: forall s a. Monoid a => Parser g s a -> Parser g s a+   concatMany (Parser p) = Parser q+      where q :: forall x. s -> (a -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            q rest success failure = p rest success' (const $ success mempty rest failure)+               where success' prefix suffix failure' =+                        q suffix (success . (prefix <>)) (const $ success prefix suffix failure')+   {-# INLINABLE string #-}++-- | Continuation-passing context-free parser+--+-- @+-- 'parseComplete' :: ("Rank2".'Rank2.Functor' g, 'FactorialMonoid' s) =>+--                  g (Continued.'Parser' g s) -> s -> g 'ParseResults'+-- @+instance MultiParsing Parser where+   type ResultFunctor Parser = ParseResults+   -- | Returns an input prefix parse paired with the remaining input suffix.+   parsePrefix g input = Rank2.fmap (Compose . (\p-> applyParser p input (\a rest _-> Right (rest, a)) (Left . fromFailure input))) g+   parseComplete g input = Rank2.fmap (\p-> applyParser p input (const . const . Right) (Left . fromFailure input))+                                      (Rank2.fmap (<* endOfInput) g)++fromFailure :: FactorialMonoid s => s -> FailureInfo -> ParseFailure+fromFailure s (FailureInfo _ pos msgs) = ParseFailure (Factorial.length s - fromIntegral pos + 1) (nub msgs)
+ src/Text/Grampa/ContextFree/Continued/Measured.hs view
@@ -0,0 +1,249 @@+{-# LANGUAGE BangPatterns, InstanceSigs, RankNTypes, ScopedTypeVariables, TypeFamilies #-}+-- | Continuation-passing parser for context-free grammars that keeps track of the parsed prefix length+module Text.Grampa.ContextFree.Continued.Measured (Parser(..), Result(..), alt) where++import Control.Applicative (Applicative(..), Alternative(..), liftA2)+import Control.Monad (Monad(..), MonadPlus(..))++import Data.Char (isSpace)+import Data.Functor.Classes (Show1(..))+import Data.Functor.Compose (Compose(..))+import Data.List (nub)+import Data.Monoid (Monoid(mappend, mempty), (<>))+import Data.Monoid.Factorial(FactorialMonoid)+import Data.Monoid.Textual(TextualMonoid)+import Data.String (fromString)++import qualified Data.Monoid.Cancellative as Cancellative+import qualified Data.Monoid.Factorial as Factorial+import qualified Data.Monoid.Null as Null+import qualified Data.Monoid.Textual as Textual++import qualified Rank2++import qualified Text.Parser.Char+import Text.Parser.Char (CharParsing)+import Text.Parser.Combinators (Parsing(..))+import Text.Parser.LookAhead (LookAheadParsing(..))+import Text.Parser.Token (TokenParsing(someSpace))+import Text.Grampa.Class (MonoidParsing(..), MultiParsing(..), ParseResults, ParseFailure(..))+import Text.Grampa.Internal (FailureInfo(..))++data Result (g :: (* -> *) -> *) s v = Parsed{parsedPrefix :: !v,+                                              parsedSuffix :: !s}+                                     | NoParse FailureInfo++-- | Parser type for context-free grammars that uses a continuation-passing algorithm, fast for grammars in LL(1)+-- class but with potentially exponential performance for longer ambiguous prefixes.+newtype Parser (g :: (* -> *) -> *) s r =+   Parser{applyParser :: forall x. s -> (r -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x}++instance Show1 (Result g s) where+   liftShowsPrec showsPrecSub _showList prec Parsed{parsedPrefix= r} rest = "Parsed " ++ showsPrecSub prec r rest+   liftShowsPrec _showsPrec _showList _prec (NoParse f) rest = "NoParse " ++ shows f rest++instance Functor (Result g s) where+   fmap f (Parsed a rest) = Parsed (f a) rest+   fmap _ (NoParse failure) = NoParse failure+   +instance Functor (Parser g s) where+   fmap f (Parser p) = Parser (\input success-> p input (success . f))+   {-# INLINABLE fmap #-}++instance Applicative (Parser g s) where+   pure a = Parser (\input success failure-> success a 0 input failure)+   (<*>) :: forall a b. Parser g s (a -> b) -> Parser g s a -> Parser g s b+   Parser p <*> Parser q = Parser r where+      r :: forall x. s -> (b -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+      r rest success failure = p rest (\f len rest'-> q rest' (\a len'-> success (f a) $! len + len')) failure+   {-# INLINABLE (<*>) #-}++instance Factorial.FactorialMonoid s => Alternative (Parser g s) where+   empty = Parser (\rest _ failure-> failure $ FailureInfo 0 (fromIntegral $ Factorial.length rest) ["empty"])+   (<|>) = alt++-- | A named and unconstrained version of the '<|>' operator+alt :: forall g s a. Parser g s a -> Parser g s a -> Parser g s a+Parser p `alt` Parser q = Parser r where+   r :: forall x. s -> (a -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+   r rest success failure = p rest success' failure'+      where success' a len rest' _ = success a len rest' failure'+            failure' f1 = q rest success (\f2 -> failure (f1 <> f2))++instance Monad (Parser g s) where+   return = pure+   (>>=) :: forall a b. Parser g s a -> (a -> Parser g s b) -> Parser g s b+   Parser p >>= f = Parser r where+      r :: forall x. s -> (b -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+      r rest success failure = p rest+                                 (\a len rest'-> applyParser (f a) rest' $ \b len'-> success b $! len + len')+                                 failure++instance Factorial.FactorialMonoid s => MonadPlus (Parser g s) where+   mzero = empty+   mplus = (<|>)++instance Monoid x => Monoid (Parser g s x) where+   mempty = pure mempty+   mappend = liftA2 mappend++instance Factorial.FactorialMonoid s => Parsing (Parser g s) where+   try = id+   (<?>) = const+   eof = endOfInput+   unexpected msg = Parser (\t _ failure -> failure $ FailureInfo 0 (fromIntegral $ Factorial.length t) [msg])+   notFollowedBy (Parser p) = Parser q+      where q :: forall x. s -> (() -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            q input success failure = p input success' failure'+               where success' _ _ _ _ = failure (FailureInfo 1 (fromIntegral $ Factorial.length input) +                                                             ["notFollowedBy"])+                     failure' _ = success () 0 input failure++instance Factorial.FactorialMonoid s => LookAheadParsing (Parser g s) where+   lookAhead :: forall a. Parser g s a -> Parser g s a+   lookAhead (Parser p) = Parser q+      where q :: forall x. s -> (a -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            q input success failure = p input success' failure'+               where success' a _ _ = success a 0 input+                     failure' f = failure f++instance (Show s, TextualMonoid s) => CharParsing (Parser g s) where+   satisfy = satisfyChar+   string s = Textual.toString (error "unexpected non-character") <$> string (fromString s)+   char = satisfyChar . (==)+   notChar = satisfyChar . (/=)+   anyChar = satisfyChar (const True)+   text t = (fromString . Textual.toString (error "unexpected non-character")) <$> string (Textual.fromText t)++instance (Show s, TextualMonoid s) => TokenParsing (Parser g s) where+   someSpace = () <$ takeCharsWhile1 isSpace++instance MonoidParsing (Parser g) where+   endOfInput = Parser p+      where p rest success failure+               | Null.null rest = success () 0 rest failure+               | otherwise = failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["endOfInput"])+   getInput = Parser p+      where p rest success failure = success rest len mempty failure+               where !len = Factorial.length rest+   anyToken = Parser p+      where p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, suffix) -> success first 1 suffix failure+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["anyToken"])+   satisfy :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   satisfy predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, suffix) | predicate first -> success first 1 suffix failure+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfy"])+   satisfyChar :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s Char+   satisfyChar predicate = Parser p+      where p :: forall x. s -> (Char -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> success first 1 suffix failure+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   satisfyCharInput :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   satisfyCharInput predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> success (Factorial.primePrefix rest) 1 suffix failure+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   notSatisfy :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s ()+   notSatisfy predicate = Parser p+      where p :: forall x. s -> (() -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, _)+                     | predicate first -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["notSatisfy"])+                  _ -> success () 0 rest failure+   notSatisfyChar :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s ()+   notSatisfyChar predicate = Parser p+      where p :: forall x. s -> (() -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.characterPrefix rest+               of Just first | predicate first+                               -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["notSatisfyChar"])+                  _ -> success () 0 rest failure+   scan :: forall t s. FactorialMonoid t => s -> (s -> t -> Maybe s) -> Parser g t t+   scan s0 f = Parser (p s0)+      where p :: forall x. s -> t -> (t -> Int -> t -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p s rest success failure = success prefix len suffix failure+               where (prefix, suffix, _) = Factorial.spanMaybe' s f rest+                     !len = Factorial.length prefix+   scanChars :: forall t s. TextualMonoid t => s -> (s -> Char -> Maybe s) -> Parser g t t+   scanChars s0 f = Parser (p s0)+      where p :: forall x. s -> t -> (t -> Int -> t -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p s rest success failure = success prefix len suffix failure+               where (prefix, suffix, _) = Textual.spanMaybe_' s f rest+                     !len = Factorial.length prefix+   takeWhile :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   takeWhile predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure +               | (prefix, suffix) <- Factorial.span predicate rest, +                 !len <- Factorial.length prefix = +                    success prefix len suffix failure+   takeWhile1 :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   takeWhile1 predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | (prefix, suffix) <- Factorial.span predicate rest, +                 !len <- Factorial.length prefix =+                    if len == 0+                    then failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeWhile1"])+                    else success prefix len suffix failure+   takeCharsWhile :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   takeCharsWhile predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | (prefix, suffix) <- Textual.span_ False predicate rest, +                 !len <- Factorial.length prefix = success prefix len suffix failure+   takeCharsWhile1 :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   takeCharsWhile1 predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | Null.null prefix = failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeCharsWhile1"])+               | otherwise = len `seq` success prefix len suffix failure+               where (prefix, suffix) = Textual.span_ False predicate rest+                     len = Factorial.length prefix+   string :: forall s. (Cancellative.LeftReductiveMonoid s, FactorialMonoid s, Show s) => s -> Parser g s s+   string s = Parser p where+      p :: forall x. s -> (s -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+      p s' success failure+         | Just suffix <- Cancellative.stripPrefix s s', !len <- Factorial.length s = success s len suffix failure+         | otherwise = failure (FailureInfo 1 (fromIntegral $ Factorial.length s') ["string " ++ show s])+   whiteSpace = () <$ takeCharsWhile isSpace+   concatMany :: forall s a. Monoid a => Parser g s a -> Parser g s a+   concatMany (Parser p) = Parser q+      where q :: forall x. s -> (a -> Int -> s -> (FailureInfo -> x) -> x) -> (FailureInfo -> x) -> x+            q rest success failure = p rest success' (const $ success mempty 0 rest failure)+               where success' prefix !len suffix failure' =+                        q suffix +                          (\prefix' !len'-> success (prefix <> prefix') (len + len')) +                          (const $ success prefix len suffix failure')+   {-# INLINABLE string #-}++-- | Continuation-passing context-free parser that keeps track of the parsed prefix length+--+-- @+-- 'parseComplete' :: ("Rank2".'Rank2.Functor' g, 'FactorialMonoid' s) =>+--                  g (Continued.'Parser' g s) -> s -> g 'ParseResults'+-- @+instance MultiParsing Parser where+   type ResultFunctor Parser = ParseResults+   -- | Returns an input prefix parse paired with the remaining input suffix.+   parsePrefix g input = Rank2.fmap (Compose . (\p-> applyParser p input+                                                                 (\a _ rest _-> Right (rest, a))+                                                                 (Left . fromFailure input))) +                                    g+   parseComplete g input = Rank2.fmap (\p-> applyParser p input+                                                        (const . const . const . Right)+                                                        (Left . fromFailure input))+                                      (Rank2.fmap (<* endOfInput) g)++fromFailure :: FactorialMonoid s => s -> FailureInfo -> ParseFailure+fromFailure s (FailureInfo _ pos msgs) = ParseFailure (Factorial.length s - fromIntegral pos + 1) (nub msgs)
src/Text/Grampa/ContextFree/LeftRecursive.hs view
@@ -32,7 +32,7 @@ import Text.Grampa.Internal (BinTree(EmptyTree)) import Text.Grampa.ContextFree.Memoizing (ResultList(..), fromResultList) import qualified Text.Grampa.ContextFree.Memoizing as Memoizing-import qualified Text.Grampa.PEG.Backtrack.Length as Backtrack+import qualified Text.Grampa.PEG.Backtrack.Measured as Backtrack  import Prelude hiding (cycle, null, span, takeWhile) @@ -509,7 +509,7 @@  -- | Turns a context-free parser into a backtracking PEG parser that consumes the longest possible prefix of the list -- of input tails, opposite of 'peg'-longest :: FactorialMonoid s => Fixed Memoizing.Parser g s a -> Fixed Backtrack.Parser g [(s, g (ResultList g s))] a+longest :: Fixed Memoizing.Parser g s a -> Fixed Backtrack.Parser g [(s, g (ResultList g s))] a longest (PositiveDirectParser p) = PositiveDirectParser (Memoizing.longest p) longest p@DirectParser{} = DirectParser{complete= Memoizing.longest (complete p),                                         direct0=  Memoizing.longest (direct0 p),
src/Text/Grampa/ContextFree/Memoizing.hs view
@@ -31,7 +31,7 @@  import Text.Grampa.Class (GrammarParsing(..), MonoidParsing(..), MultiParsing(..), ParseResults, ParseFailure(..)) import Text.Grampa.Internal (BinTree(..), FailureInfo(..))-import qualified Text.Grampa.PEG.Backtrack.Length as Backtrack+import qualified Text.Grampa.PEG.Backtrack.Measured as Backtrack  import Prelude hiding (iterate, length, null, showList, span, takeWhile) @@ -42,14 +42,14 @@ data ResultList g s r = ResultList !(BinTree (ResultInfo g s r)) {-# UNPACK #-} !FailureInfo data ResultInfo g s r = ResultInfo !Int ![(s, g (ResultList g s))] !r -instance (Show s, Show r) => Show (ResultList g s r) where+instance Show r => Show (ResultList g s r) where    show (ResultList l f) = "ResultList (" ++ shows l (") (" ++ shows f ")")  instance Show1 (ResultList g s) where    liftShowsPrec _sp showList _prec (ResultList l f) rest = "ResultList " ++ showList (simplify <$> toList l) (shows f rest)       where simplify (ResultInfo _ _ r) = r -instance (Show s, Show r) => Show (ResultInfo g s r) where+instance Show r => Show (ResultInfo g s r) where    show (ResultInfo l _ r) = "(ResultInfo @" ++ show l ++ " " ++ shows r ")"  instance Functor (ResultInfo g s) where@@ -262,7 +262,7 @@  -- | Turns a context-free parser into a backtracking PEG parser that consumes the longest possible prefix of the list -- of input tails, opposite of 'peg'-longest :: FactorialMonoid s => Parser g s a -> Backtrack.Parser g [(s, g (ResultList g s))] a+longest :: Parser g s a -> Backtrack.Parser g [(s, g (ResultList g s))] a longest p = Backtrack.Parser q where    q rest = case applyParser p rest             of ResultList EmptyTree failure -> Backtrack.NoParse failure
src/Text/Grampa/ContextFree/Parallel.hs view
@@ -177,7 +177,7 @@            | otherwise = ResultList mempty (FailureInfo 1 (Factorial.length s') ["string " ++ show s])    whiteSpace = () <$ takeCharsWhile isSpace    concatMany (Parser p) = Parser q-      where q s = ResultList mempty failure <> foldMap continue rs+      where q s = ResultList (Leaf $ ResultInfo s mempty) failure <> foldMap continue rs                where ResultList rs failure = p s             continue (ResultInfo suffix prefix) = (prefix <>) <$> q suffix 
− src/Text/Grampa/PEG/Backtrack/Length.hs
@@ -1,202 +0,0 @@-{-# LANGUAGE TypeFamilies #-}--- | Backtracking parser for Parsing Expression Grammars, tracking the consumed input length-module Text.Grampa.PEG.Backtrack.Length (Parser(..), Result(..), alt) where--import Control.Applicative (Applicative(..), Alternative(..), liftA2)-import Control.Monad (Monad(..), MonadPlus(..))--import Data.Char (isSpace)-import Data.Functor.Classes (Show1(..))-import Data.Functor.Compose (Compose(..))-import Data.List (nub)-import Data.Monoid (Monoid(mappend, mempty), (<>))-import Data.Monoid.Factorial(FactorialMonoid)-import Data.String (fromString)--import qualified Data.Monoid.Cancellative as Cancellative-import qualified Data.Monoid.Factorial as Factorial-import qualified Data.Monoid.Null as Null-import qualified Data.Monoid.Textual as Textual--import qualified Rank2--import qualified Text.Parser.Char-import Text.Parser.Char (CharParsing)-import Text.Parser.Combinators (Parsing(..))-import Text.Parser.LookAhead (LookAheadParsing(..))-import Text.Parser.Token (TokenParsing(someSpace))-import Text.Grampa.Class (MonoidParsing(..), MultiParsing(..), ParseResults, ParseFailure(..))-import Text.Grampa.Internal (FailureInfo(..))--data Result (g :: (* -> *) -> *) s v = Parsed{parsedLength :: !Int,-                                              parsedResult :: !v,-                                              parsedSuffix :: !s}-                                     | NoParse FailureInfo---- | Parser type for Parsing Expression Grammars that uses a backtracking algorithm, fast for grammars in LL(1) class--- but with potentially exponential performance for longer ambiguous prefixes.-newtype Parser g s r = Parser{applyParser :: s -> Result g s r}--instance Show1 (Result g s) where-   liftShowsPrec showsPrecSub _showList prec Parsed{parsedResult= r} rest = "Parsed " ++ showsPrecSub prec r rest-   liftShowsPrec _showsPrec _showList _prec (NoParse f) rest = "NoParse " ++ shows f rest--instance Functor (Result g s) where-   fmap f (Parsed l a rest) = Parsed l (f a) rest-   fmap _ (NoParse failure) = NoParse failure-   -instance Functor (Parser g s) where-   fmap f (Parser p) = Parser (fmap f . p)-   {-# INLINABLE fmap #-}--instance Applicative (Parser g s) where-   pure a = Parser (Parsed 0 a)-   Parser p <*> Parser q = Parser r where-      r rest = case p rest-               of Parsed l f rest' -> case q rest'-                                      of Parsed l' a rest'' -> Parsed (l+l') (f a) rest''-                                         NoParse failure -> NoParse failure-                  NoParse failure -> NoParse failure-   {-# INLINABLE (<*>) #-}--instance Factorial.FactorialMonoid s => Alternative (Parser g s) where-   empty = Parser (\rest-> NoParse $ FailureInfo 0 (fromIntegral $ Factorial.length rest) ["empty"])-   (<|>) = alt---- | A named and unconstrained version of the '<|>' operator-alt :: Parser g s a -> Parser g s a -> Parser g s a-Parser p `alt` Parser q = Parser r where-      r rest = case p rest-               of x@Parsed{} -> x-                  NoParse{} -> q rest--instance Monad (Parser g s) where-   return = pure-   Parser p >>= f = Parser r where-      r rest = case p rest-               of Parsed l a rest' -> case applyParser (f a) rest'-                                      of Parsed l' b rest'' -> Parsed (l+l') b rest''-                                         NoParse failure -> NoParse failure-                  NoParse failure -> NoParse failure--instance Factorial.FactorialMonoid s => MonadPlus (Parser g s) where-   mzero = empty-   mplus = (<|>)--instance Monoid x => Monoid (Parser g s x) where-   mempty = pure mempty-   mappend = liftA2 mappend--instance Factorial.FactorialMonoid s => Parsing (Parser g s) where-   try = id-   (<?>) = const-   eof = endOfInput-   unexpected msg = Parser (\t-> NoParse $ FailureInfo 0 (fromIntegral $ Factorial.length t) [msg])-   notFollowedBy (Parser p) = Parser (\input-> rewind input (p input))-      where rewind t Parsed{} = NoParse (FailureInfo 1 (fromIntegral $ Factorial.length t) ["notFollowedBy"])-            rewind t NoParse{} = Parsed 0 () t--instance Factorial.FactorialMonoid s => LookAheadParsing (Parser g s) where-   lookAhead (Parser p) = Parser (\input-> rewind input (p input))-      where rewind t (Parsed _ r _) = Parsed 0 r t-            rewind _ r@NoParse{} = r--instance (Show s, Textual.TextualMonoid s) => CharParsing (Parser g s) where-   satisfy = satisfyChar-   string s = Textual.toString (error "unexpected non-character") <$> string (fromString s)-   char = satisfyChar . (==)-   notChar = satisfyChar . (/=)-   anyChar = satisfyChar (const True)-   text t = (fromString . Textual.toString (error "unexpected non-character")) <$> string (Textual.fromText t)--instance (Show s, Textual.TextualMonoid s) => TokenParsing (Parser g s) where-   someSpace = () <$ takeCharsWhile1 isSpace--instance MonoidParsing (Parser g) where-   endOfInput = Parser p-      where p rest-               | Null.null rest = Parsed 0 () rest-               | otherwise = NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["endOfInput"])-   getInput = Parser p-      where p rest = Parsed (Factorial.length rest) rest mempty-   anyToken = Parser p-      where p rest = case Factorial.splitPrimePrefix rest-                     of Just (first, suffix) -> Parsed 1 first suffix-                        _ -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["anyToken"])-   satisfy predicate = Parser p-      where p rest =-               case Factorial.splitPrimePrefix rest-               of Just (first, suffix) | predicate first -> Parsed 1 first suffix-                  _ -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfy"])-   satisfyChar predicate = Parser p-      where p rest =-               case Textual.splitCharacterPrefix rest-               of Just (first, suffix) | predicate first -> Parsed 1 first suffix-                  _ -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])-   satisfyCharInput predicate = Parser p-      where p rest =-               case Textual.splitCharacterPrefix rest-               of Just (first, suffix) | predicate first -> Parsed 1 (Factorial.primePrefix rest) suffix-                  _ -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])-   notSatisfy predicate = Parser p-      where p s = case Factorial.splitPrimePrefix s-                  of Just (first, _) -                        | predicate first -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length s) ["notSatisfy"])-                     _ -> Parsed 0 () s-   notSatisfyChar predicate = Parser p-      where p s = case Textual.characterPrefix s-                  of Just first | predicate first -                                  -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length s) ["notSatisfyChar"])-                     _ -> Parsed 0 () s-   scan s0 f = Parser (p s0)-      where p s rest = Parsed (Factorial.length prefix) prefix suffix-               where (prefix, suffix, _) = Factorial.spanMaybe' s f rest-   scanChars s0 f = Parser (p s0)-      where p s rest = Parsed (Factorial.length prefix) prefix suffix-               where (prefix, suffix, _) = Textual.spanMaybe_' s f rest-   takeWhile predicate = Parser p-      where p rest | (prefix, suffix) <- Factorial.span predicate rest =-               Parsed (Factorial.length prefix) prefix suffix-   takeWhile1 predicate = Parser p-      where p rest | (prefix, suffix) <- Factorial.span predicate rest =-                        if Null.null prefix-                        then NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeWhile1"])-                        else Parsed (Factorial.length prefix) prefix suffix-   takeCharsWhile predicate = Parser p-      where p rest | (prefix, suffix) <- Textual.span_ False predicate rest = -               Parsed (Factorial.length prefix) prefix suffix-   takeCharsWhile1 predicate = Parser p-      where p rest | (prefix, suffix) <- Textual.span_ False predicate rest =-                     if Null.null prefix-                     then NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeCharsWhile1"])-                     else Parsed (Factorial.length prefix) prefix suffix-   string s = Parser p where-      p s' | Just suffix <- Cancellative.stripPrefix s s' = Parsed l s suffix-           | otherwise = NoParse (FailureInfo 1 (fromIntegral $ Factorial.length s') ["string " ++ show s])-      l = Factorial.length s-   whiteSpace = () <$ takeCharsWhile isSpace-   concatMany (Parser p) = Parser q-      where q rest = case p rest-                     of Parsed l prefix suffix -> let Parsed l' prefix' suffix' = q suffix-                                                  in Parsed (l+l') (prefix <> prefix') suffix'-                        NoParse{} -> Parsed 0 mempty rest-   {-# INLINABLE string #-}---- | Backtracking PEG parser------ @--- 'parseComplete' :: ("Rank2".'Rank2.Functor' g, 'FactorialMonoid' s) =>---                  g (Backtrack.'Parser' g s) -> s -> g 'ParseResults'--- @-instance MultiParsing Parser where-   type ResultFunctor Parser = ParseResults-   {-# NOINLINE parsePrefix #-}-   -- | Returns an input prefix parse paired with the remaining input suffix.-   parsePrefix g input = Rank2.fmap (Compose . fromResult input . (`applyParser` input)) g-   parseComplete g input = Rank2.fmap ((snd <$>) . fromResult input . (`applyParser` input))-                                      (Rank2.fmap (<* endOfInput) g)--fromResult :: FactorialMonoid s => s -> Result g s r -> ParseResults (s, r)-fromResult s (NoParse (FailureInfo _ pos msgs)) =-   Left (ParseFailure (Factorial.length s - fromIntegral pos + 1) (nub msgs))-fromResult _ (Parsed _ prefix suffix) = Right (suffix, prefix)
+ src/Text/Grampa/PEG/Backtrack/Measured.hs view
@@ -0,0 +1,202 @@+{-# LANGUAGE TypeFamilies #-}+-- | Backtracking parser for Parsing Expression Grammars, tracking the consumed input length+module Text.Grampa.PEG.Backtrack.Measured (Parser(..), Result(..), alt) where++import Control.Applicative (Applicative(..), Alternative(..), liftA2)+import Control.Monad (Monad(..), MonadPlus(..))++import Data.Char (isSpace)+import Data.Functor.Classes (Show1(..))+import Data.Functor.Compose (Compose(..))+import Data.List (nub)+import Data.Monoid (Monoid(mappend, mempty), (<>))+import Data.Monoid.Factorial(FactorialMonoid)+import Data.String (fromString)++import qualified Data.Monoid.Cancellative as Cancellative+import qualified Data.Monoid.Factorial as Factorial+import qualified Data.Monoid.Null as Null+import qualified Data.Monoid.Textual as Textual++import qualified Rank2++import qualified Text.Parser.Char+import Text.Parser.Char (CharParsing)+import Text.Parser.Combinators (Parsing(..))+import Text.Parser.LookAhead (LookAheadParsing(..))+import Text.Parser.Token (TokenParsing(someSpace))+import Text.Grampa.Class (MonoidParsing(..), MultiParsing(..), ParseResults, ParseFailure(..))+import Text.Grampa.Internal (FailureInfo(..))++data Result (g :: (* -> *) -> *) s v = Parsed{parsedLength :: !Int,+                                              parsedResult :: !v,+                                              parsedSuffix :: !s}+                                     | NoParse FailureInfo++-- | Parser type for Parsing Expression Grammars that uses a backtracking algorithm, fast for grammars in LL(1) class+-- but with potentially exponential performance for longer ambiguous prefixes.+newtype Parser g s r = Parser{applyParser :: s -> Result g s r}++instance Show1 (Result g s) where+   liftShowsPrec showsPrecSub _showList prec Parsed{parsedResult= r} rest = "Parsed " ++ showsPrecSub prec r rest+   liftShowsPrec _showsPrec _showList _prec (NoParse f) rest = "NoParse " ++ shows f rest++instance Functor (Result g s) where+   fmap f (Parsed l a rest) = Parsed l (f a) rest+   fmap _ (NoParse failure) = NoParse failure+   +instance Functor (Parser g s) where+   fmap f (Parser p) = Parser (fmap f . p)+   {-# INLINABLE fmap #-}++instance Applicative (Parser g s) where+   pure a = Parser (Parsed 0 a)+   Parser p <*> Parser q = Parser r where+      r rest = case p rest+               of Parsed l f rest' -> case q rest'+                                      of Parsed l' a rest'' -> Parsed (l+l') (f a) rest''+                                         NoParse failure -> NoParse failure+                  NoParse failure -> NoParse failure+   {-# INLINABLE (<*>) #-}++instance Factorial.FactorialMonoid s => Alternative (Parser g s) where+   empty = Parser (\rest-> NoParse $ FailureInfo 0 (fromIntegral $ Factorial.length rest) ["empty"])+   (<|>) = alt++-- | A named and unconstrained version of the '<|>' operator+alt :: Parser g s a -> Parser g s a -> Parser g s a+Parser p `alt` Parser q = Parser r where+      r rest = case p rest+               of x@Parsed{} -> x+                  NoParse{} -> q rest++instance Monad (Parser g s) where+   return = pure+   Parser p >>= f = Parser r where+      r rest = case p rest+               of Parsed l a rest' -> case applyParser (f a) rest'+                                      of Parsed l' b rest'' -> Parsed (l+l') b rest''+                                         NoParse failure -> NoParse failure+                  NoParse failure -> NoParse failure++instance Factorial.FactorialMonoid s => MonadPlus (Parser g s) where+   mzero = empty+   mplus = (<|>)++instance Monoid x => Monoid (Parser g s x) where+   mempty = pure mempty+   mappend = liftA2 mappend++instance Factorial.FactorialMonoid s => Parsing (Parser g s) where+   try = id+   (<?>) = const+   eof = endOfInput+   unexpected msg = Parser (\t-> NoParse $ FailureInfo 0 (fromIntegral $ Factorial.length t) [msg])+   notFollowedBy (Parser p) = Parser (\input-> rewind input (p input))+      where rewind t Parsed{} = NoParse (FailureInfo 1 (fromIntegral $ Factorial.length t) ["notFollowedBy"])+            rewind t NoParse{} = Parsed 0 () t++instance Factorial.FactorialMonoid s => LookAheadParsing (Parser g s) where+   lookAhead (Parser p) = Parser (\input-> rewind input (p input))+      where rewind t (Parsed _ r _) = Parsed 0 r t+            rewind _ r@NoParse{} = r++instance (Show s, Textual.TextualMonoid s) => CharParsing (Parser g s) where+   satisfy = satisfyChar+   string s = Textual.toString (error "unexpected non-character") <$> string (fromString s)+   char = satisfyChar . (==)+   notChar = satisfyChar . (/=)+   anyChar = satisfyChar (const True)+   text t = (fromString . Textual.toString (error "unexpected non-character")) <$> string (Textual.fromText t)++instance (Show s, Textual.TextualMonoid s) => TokenParsing (Parser g s) where+   someSpace = () <$ takeCharsWhile1 isSpace++instance MonoidParsing (Parser g) where+   endOfInput = Parser p+      where p rest+               | Null.null rest = Parsed 0 () rest+               | otherwise = NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["endOfInput"])+   getInput = Parser p+      where p rest = Parsed (Factorial.length rest) rest mempty+   anyToken = Parser p+      where p rest = case Factorial.splitPrimePrefix rest+                     of Just (first, suffix) -> Parsed 1 first suffix+                        _ -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["anyToken"])+   satisfy predicate = Parser p+      where p rest =+               case Factorial.splitPrimePrefix rest+               of Just (first, suffix) | predicate first -> Parsed 1 first suffix+                  _ -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfy"])+   satisfyChar predicate = Parser p+      where p rest =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> Parsed 1 first suffix+                  _ -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   satisfyCharInput predicate = Parser p+      where p rest =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> Parsed 1 (Factorial.primePrefix rest) suffix+                  _ -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   notSatisfy predicate = Parser p+      where p s = case Factorial.splitPrimePrefix s+                  of Just (first, _) +                        | predicate first -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length s) ["notSatisfy"])+                     _ -> Parsed 0 () s+   notSatisfyChar predicate = Parser p+      where p s = case Textual.characterPrefix s+                  of Just first | predicate first +                                  -> NoParse (FailureInfo 1 (fromIntegral $ Factorial.length s) ["notSatisfyChar"])+                     _ -> Parsed 0 () s+   scan s0 f = Parser (p s0)+      where p s rest = Parsed (Factorial.length prefix) prefix suffix+               where (prefix, suffix, _) = Factorial.spanMaybe' s f rest+   scanChars s0 f = Parser (p s0)+      where p s rest = Parsed (Factorial.length prefix) prefix suffix+               where (prefix, suffix, _) = Textual.spanMaybe_' s f rest+   takeWhile predicate = Parser p+      where p rest | (prefix, suffix) <- Factorial.span predicate rest =+               Parsed (Factorial.length prefix) prefix suffix+   takeWhile1 predicate = Parser p+      where p rest | (prefix, suffix) <- Factorial.span predicate rest =+                        if Null.null prefix+                        then NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeWhile1"])+                        else Parsed (Factorial.length prefix) prefix suffix+   takeCharsWhile predicate = Parser p+      where p rest | (prefix, suffix) <- Textual.span_ False predicate rest = +               Parsed (Factorial.length prefix) prefix suffix+   takeCharsWhile1 predicate = Parser p+      where p rest | (prefix, suffix) <- Textual.span_ False predicate rest =+                     if Null.null prefix+                     then NoParse (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeCharsWhile1"])+                     else Parsed (Factorial.length prefix) prefix suffix+   string s = Parser p where+      p s' | Just suffix <- Cancellative.stripPrefix s s' = Parsed l s suffix+           | otherwise = NoParse (FailureInfo 1 (fromIntegral $ Factorial.length s') ["string " ++ show s])+      l = Factorial.length s+   whiteSpace = () <$ takeCharsWhile isSpace+   concatMany (Parser p) = Parser q+      where q rest = case p rest+                     of Parsed l prefix suffix -> let Parsed l' prefix' suffix' = q suffix+                                                  in Parsed (l+l') (prefix <> prefix') suffix'+                        NoParse{} -> Parsed 0 mempty rest+   {-# INLINABLE string #-}++-- | Backtracking PEG parser+--+-- @+-- 'parseComplete' :: ("Rank2".'Rank2.Functor' g, 'FactorialMonoid' s) =>+--                  g (Backtrack.'Parser' g s) -> s -> g 'ParseResults'+-- @+instance MultiParsing Parser where+   type ResultFunctor Parser = ParseResults+   {-# NOINLINE parsePrefix #-}+   -- | Returns an input prefix parse paired with the remaining input suffix.+   parsePrefix g input = Rank2.fmap (Compose . fromResult input . (`applyParser` input)) g+   parseComplete g input = Rank2.fmap ((snd <$>) . fromResult input . (`applyParser` input))+                                      (Rank2.fmap (<* endOfInput) g)++fromResult :: FactorialMonoid s => s -> Result g s r -> ParseResults (s, r)+fromResult s (NoParse (FailureInfo _ pos msgs)) =+   Left (ParseFailure (Factorial.length s - fromIntegral pos + 1) (nub msgs))+fromResult _ (Parsed _ prefix suffix) = Right (suffix, prefix)
+ src/Text/Grampa/PEG/Continued.hs view
@@ -0,0 +1,227 @@+{-# LANGUAGE InstanceSigs, RankNTypes, ScopedTypeVariables, TypeFamilies #-}+-- | Continuation-passing parser for Parsing Expression Grammars+module Text.Grampa.PEG.Continued (Parser(..), Result(..), alt) where++import Control.Applicative (Applicative(..), Alternative(..), liftA2)+import Control.Monad (Monad(..), MonadPlus(..))++import Data.Char (isSpace)+import Data.Functor.Classes (Show1(..))+import Data.Functor.Compose (Compose(..))+import Data.List (nub)+import Data.Monoid (Monoid(mappend, mempty), (<>))+import Data.Monoid.Factorial(FactorialMonoid)+import Data.Monoid.Textual(TextualMonoid)+import Data.String (fromString)++import qualified Data.Monoid.Cancellative as Cancellative+import qualified Data.Monoid.Factorial as Factorial+import qualified Data.Monoid.Null as Null+import qualified Data.Monoid.Textual as Textual++import qualified Rank2++import qualified Text.Parser.Char+import Text.Parser.Char (CharParsing)+import Text.Parser.Combinators (Parsing(..))+import Text.Parser.LookAhead (LookAheadParsing(..))+import Text.Parser.Token (TokenParsing(someSpace))+import Text.Grampa.Class (MonoidParsing(..), MultiParsing(..), ParseResults, ParseFailure(..))+import Text.Grampa.Internal (FailureInfo(..))++data Result (g :: (* -> *) -> *) s v = Parsed{parsedPrefix :: !v,+                                              parsedSuffix :: !s}+                                     | NoParse FailureInfo++-- | Parser type for Parsing Expression Grammars that uses a continuation-passing algorithm, fast for grammars in+-- LL(1) class but with potentially exponential performance for longer ambiguous prefixes.+newtype Parser (g :: (* -> *) -> *) s r =+   Parser{applyParser :: forall x. s -> (r -> s -> x) -> (FailureInfo -> x) -> x}++instance Show1 (Result g s) where+   liftShowsPrec showsPrecSub _showList prec Parsed{parsedPrefix= r} rest = "Parsed " ++ showsPrecSub prec r rest+   liftShowsPrec _showsPrec _showList _prec (NoParse f) rest = "NoParse " ++ shows f rest++instance Functor (Result g s) where+   fmap f (Parsed a rest) = Parsed (f a) rest+   fmap _ (NoParse failure) = NoParse failure+   +instance Functor (Parser g s) where+   fmap f (Parser p) = Parser (\input success-> p input (success . f))+   {-# INLINABLE fmap #-}++instance Applicative (Parser g s) where+   pure a = Parser (\input success _-> success a input)+   (<*>) :: forall a b. Parser g s (a -> b) -> Parser g s a -> Parser g s b+   Parser p <*> Parser q = Parser r where+      r :: forall x. s -> (b -> s -> x) -> (FailureInfo -> x) -> x+      r rest success failure = p rest (\f rest'-> q rest' (success . f) failure) failure+   {-# INLINABLE (<*>) #-}++instance Factorial.FactorialMonoid s => Alternative (Parser g s) where+   empty = Parser (\rest _ failure-> failure $ FailureInfo 0 (fromIntegral $ Factorial.length rest) ["empty"])+   (<|>) = alt++-- | A named and unconstrained version of the '<|>' operator+alt :: forall g s a. Parser g s a -> Parser g s a -> Parser g s a+Parser p `alt` Parser q = Parser r where+   r :: forall x. s -> (a -> s -> x) -> (FailureInfo -> x) -> x+   r rest success failure = p rest success (\f1-> q rest success $ \f2 -> failure (f1 <> f2))++instance Monad (Parser g s) where+   return = pure+   (>>=) :: forall a b. Parser g s a -> (a -> Parser g s b) -> Parser g s b+   Parser p >>= f = Parser r where+      r :: forall x. s -> (b -> s -> x) -> (FailureInfo -> x) -> x+      r rest success failure = p rest (\a rest'-> applyParser (f a) rest' success failure) failure++instance Factorial.FactorialMonoid s => MonadPlus (Parser g s) where+   mzero = empty+   mplus = (<|>)++instance Monoid x => Monoid (Parser g s x) where+   mempty = pure mempty+   mappend = liftA2 mappend++instance Factorial.FactorialMonoid s => Parsing (Parser g s) where+   try = id+   (<?>) = const+   eof = endOfInput+   unexpected msg = Parser (\t _ failure -> failure $ FailureInfo 0 (fromIntegral $ Factorial.length t) [msg])+   notFollowedBy (Parser p) = Parser q+      where q :: forall x. s -> (() -> s -> x) -> (FailureInfo -> x) -> x+            q input success failure = p input success' failure'+               where success' _ _ = failure (FailureInfo 1 (fromIntegral $ Factorial.length input) ["notFollowedBy"])+                     failure' _ = success () input++instance Factorial.FactorialMonoid s => LookAheadParsing (Parser g s) where+   lookAhead :: forall a. Parser g s a -> Parser g s a+   lookAhead (Parser p) = Parser q+      where q :: forall x. s -> (a -> s -> x) -> (FailureInfo -> x) -> x+            q input success failure = p input success' failure'+               where success' a _ = success a input+                     failure' f = failure f++instance (Show s, TextualMonoid s) => CharParsing (Parser g s) where+   satisfy = satisfyChar+   string s = Textual.toString (error "unexpected non-character") <$> string (fromString s)+   char = satisfyChar . (==)+   notChar = satisfyChar . (/=)+   anyChar = satisfyChar (const True)+   text t = (fromString . Textual.toString (error "unexpected non-character")) <$> string (Textual.fromText t)++instance (Show s, TextualMonoid s) => TokenParsing (Parser g s) where+   someSpace = () <$ takeCharsWhile1 isSpace++instance MonoidParsing (Parser g) where+   endOfInput = Parser p+      where p rest success failure+               | Null.null rest = success () rest+               | otherwise = failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["endOfInput"])+   getInput = Parser p+      where p rest success _ = success rest mempty+   anyToken = Parser p+      where p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, suffix) -> success first suffix+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["anyToken"])+   satisfy :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   satisfy predicate = Parser p+      where p :: forall x. s -> (s -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, suffix) | predicate first -> success first suffix+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfy"])+   satisfyChar :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s Char+   satisfyChar predicate = Parser p+      where p :: forall x. s -> (Char -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> success first suffix+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   satisfyCharInput :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   satisfyCharInput predicate = Parser p+      where p :: forall x. s -> (s -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> success (Factorial.primePrefix rest) suffix+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   notSatisfy :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s ()+   notSatisfy predicate = Parser p+      where p :: forall x. s -> (() -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, _)+                     | predicate first -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["notSatisfy"])+                  _ -> success () rest+   notSatisfyChar :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s ()+   notSatisfyChar predicate = Parser p+      where p :: forall x. s -> (() -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.characterPrefix rest+               of Just first | predicate first+                               -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["notSatisfyChar"])+                  _ -> success () rest+   scan :: forall t s. FactorialMonoid t => s -> (s -> t -> Maybe s) -> Parser g t t+   scan s0 f = Parser (p s0)+      where p :: forall x. s -> t -> (t -> t -> x) -> (FailureInfo -> x) -> x+            p s rest success _ = success prefix suffix+               where (prefix, suffix, _) = Factorial.spanMaybe' s f rest+   scanChars :: forall t s. TextualMonoid t => s -> (s -> Char -> Maybe s) -> Parser g t t+   scanChars s0 f = Parser (p s0)+      where p :: forall x. s -> t -> (t -> t -> x) -> (FailureInfo -> x) -> x+            p s rest success _ = success prefix suffix+               where (prefix, suffix, _) = Textual.spanMaybe_' s f rest+   takeWhile :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   takeWhile predicate = Parser p+      where p :: forall x. s -> (s -> s -> x) -> (FailureInfo -> x) -> x+            p rest success _ | (prefix, suffix) <- Factorial.span predicate rest = success prefix suffix+   takeWhile1 :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   takeWhile1 predicate = Parser p+      where p :: forall x. s -> (s -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | (prefix, suffix) <- Factorial.span predicate rest =+                    if Null.null prefix+                    then failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeWhile1"])+                    else success prefix suffix+   takeCharsWhile :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   takeCharsWhile predicate = Parser p+      where p :: forall x. s -> (s -> s -> x) -> (FailureInfo -> x) -> x+            p rest success _ | (prefix, suffix) <- Textual.span_ False predicate rest = success prefix suffix+   takeCharsWhile1 :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   takeCharsWhile1 predicate = Parser p+      where p :: forall x. s -> (s -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | Null.null prefix = failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeCharsWhile1"])+               | otherwise = success prefix suffix+               where (prefix, suffix) = Textual.span_ False predicate rest+   string :: forall s. (Cancellative.LeftReductiveMonoid s, FactorialMonoid s, Show s) => s -> Parser g s s+   string s = Parser p where+      p :: forall x. s -> (s -> s -> x) -> (FailureInfo -> x) -> x+      p s' success failure+         | Just suffix <- Cancellative.stripPrefix s s' = success s suffix+         | otherwise = failure (FailureInfo 1 (fromIntegral $ Factorial.length s') ["string " ++ show s])+   whiteSpace = () <$ takeCharsWhile isSpace+   concatMany :: forall s a. Monoid a => Parser g s a -> Parser g s a+   concatMany (Parser p) = Parser q+      where q :: forall x. s -> (a -> s -> x) -> (FailureInfo -> x) -> x+            q rest success _ = p rest success' failure+               where success' prefix suffix = q suffix (success . (prefix <>)) (const $ success prefix suffix)+                     failure _ = success mempty rest+   {-# INLINABLE string #-}++-- | Continuation-passing PEG parser+--+-- @+-- 'parseComplete' :: ("Rank2".'Rank2.Functor' g, 'FactorialMonoid' s) =>+--                  g (Continued.'Parser' g s) -> s -> g 'ParseResults'+-- @+instance MultiParsing Parser where+   type ResultFunctor Parser = ParseResults+   -- | Returns an input prefix parse paired with the remaining input suffix.+   parsePrefix g input = Rank2.fmap (Compose . (\p-> applyParser p input (flip $ curry Right) (Left . fromFailure input))) g+   parseComplete g input = Rank2.fmap (\p-> applyParser p input (const . Right) (Left . fromFailure input))+                                      (Rank2.fmap (<* endOfInput) g)++fromFailure :: FactorialMonoid s => s -> FailureInfo -> ParseFailure+fromFailure s (FailureInfo _ pos msgs) = ParseFailure (Factorial.length s - fromIntegral pos + 1) (nub msgs)
+ src/Text/Grampa/PEG/Continued/Measured.hs view
@@ -0,0 +1,242 @@+{-# LANGUAGE BangPatterns, InstanceSigs, RankNTypes, ScopedTypeVariables, TypeFamilies #-}+-- | Continuation-passing parser for Parsing Expression Grammars that keeps track of the parsed prefix length+module Text.Grampa.PEG.Continued.Measured (Parser(..), Result(..), alt) where++import Control.Applicative (Applicative(..), Alternative(..), liftA2)+import Control.Monad (Monad(..), MonadPlus(..))++import Data.Char (isSpace)+import Data.Functor.Classes (Show1(..))+import Data.Functor.Compose (Compose(..))+import Data.List (nub)+import Data.Monoid (Monoid(mappend, mempty), (<>))+import Data.Monoid.Factorial(FactorialMonoid)+import Data.Monoid.Textual(TextualMonoid)+import Data.String (fromString)++import qualified Data.Monoid.Cancellative as Cancellative+import qualified Data.Monoid.Factorial as Factorial+import qualified Data.Monoid.Null as Null+import qualified Data.Monoid.Textual as Textual++import qualified Rank2++import qualified Text.Parser.Char+import Text.Parser.Char (CharParsing)+import Text.Parser.Combinators (Parsing(..))+import Text.Parser.LookAhead (LookAheadParsing(..))+import Text.Parser.Token (TokenParsing(someSpace))+import Text.Grampa.Class (MonoidParsing(..), MultiParsing(..), ParseResults, ParseFailure(..))+import Text.Grampa.Internal (FailureInfo(..))++data Result (g :: (* -> *) -> *) s v = Parsed{parsedPrefix :: !v,+                                              parsedSuffix :: !s}+                                     | NoParse FailureInfo++-- | Parser type for Parsing Expression Grammars that uses a continuation-passing algorithm and keeps track of the+-- parsed prefix length, fast for grammars in LL(1) class but with potentially exponential performance for longer+-- ambiguous prefixes.+newtype Parser (g :: (* -> *) -> *) s r =+   Parser{applyParser :: forall x. s -> (r -> Int -> s -> x) -> (FailureInfo -> x) -> x}++instance Show1 (Result g s) where+   liftShowsPrec showsPrecSub _showList prec Parsed{parsedPrefix= r} rest = "Parsed " ++ showsPrecSub prec r rest+   liftShowsPrec _showsPrec _showList _prec (NoParse f) rest = "NoParse " ++ shows f rest++instance Functor (Result g s) where+   fmap f (Parsed a rest) = Parsed (f a) rest+   fmap _ (NoParse failure) = NoParse failure+   +instance Functor (Parser g s) where+   fmap f (Parser p) = Parser (\input success-> p input (success . f))+   {-# INLINABLE fmap #-}++instance Applicative (Parser g s) where+   pure a = Parser (\input success _-> success a 0 input)+   (<*>) :: forall a b. Parser g s (a -> b) -> Parser g s a -> Parser g s b+   Parser p <*> Parser q = Parser r where+      r :: forall x. s -> (b -> Int -> s -> x) -> (FailureInfo -> x) -> x+      r rest success failure = p rest (\f len rest'-> q rest' (\a len'-> success (f a) $! len + len') failure) failure+   {-# INLINABLE (<*>) #-}++instance Factorial.FactorialMonoid s => Alternative (Parser g s) where+   empty = Parser (\rest _ failure-> failure $ FailureInfo 0 (fromIntegral $ Factorial.length rest) ["empty"])+   (<|>) = alt++-- | A named and unconstrained version of the '<|>' operator+alt :: forall g s a. Parser g s a -> Parser g s a -> Parser g s a+Parser p `alt` Parser q = Parser r where+   r :: forall x. s -> (a -> Int -> s -> x) -> (FailureInfo -> x) -> x+   r rest success failure = p rest success (\f1-> q rest success $ \f2 -> failure (f1 <> f2))++instance Monad (Parser g s) where+   return = pure+   (>>=) :: forall a b. Parser g s a -> (a -> Parser g s b) -> Parser g s b+   Parser p >>= f = Parser r where+      r :: forall x. s -> (b -> Int -> s -> x) -> (FailureInfo -> x) -> x+      r rest success failure = p rest +                                 (\a len rest'-> applyParser (f a) rest' (\b len'-> success b $! len + len') failure)+                                 failure++instance Factorial.FactorialMonoid s => MonadPlus (Parser g s) where+   mzero = empty+   mplus = (<|>)++instance Monoid x => Monoid (Parser g s x) where+   mempty = pure mempty+   mappend = liftA2 mappend++instance Factorial.FactorialMonoid s => Parsing (Parser g s) where+   try = id+   (<?>) = const+   eof = endOfInput+   unexpected msg = Parser (\t _ failure -> failure $ FailureInfo 0 (fromIntegral $ Factorial.length t) [msg])+   notFollowedBy (Parser p) = Parser q+      where q :: forall x. s -> (() -> Int -> s -> x) -> (FailureInfo -> x) -> x+            q input success failure = p input success' failure'+               where success' _ _ _ = failure (FailureInfo 1 (fromIntegral $ Factorial.length input) ["notFollowedBy"])+                     failure' _ = success () 0 input++instance Factorial.FactorialMonoid s => LookAheadParsing (Parser g s) where+   lookAhead :: forall a. Parser g s a -> Parser g s a+   lookAhead (Parser p) = Parser q+      where q :: forall x. s -> (a -> Int -> s -> x) -> (FailureInfo -> x) -> x+            q input success failure = p input success' failure'+               where success' a _ _ = success a 0 input+                     failure' f = failure f++instance (Show s, TextualMonoid s) => CharParsing (Parser g s) where+   satisfy = satisfyChar+   string s = Textual.toString (error "unexpected non-character") <$> string (fromString s)+   char = satisfyChar . (==)+   notChar = satisfyChar . (/=)+   anyChar = satisfyChar (const True)+   text t = (fromString . Textual.toString (error "unexpected non-character")) <$> string (Textual.fromText t)++instance (Show s, TextualMonoid s) => TokenParsing (Parser g s) where+   someSpace = () <$ takeCharsWhile1 isSpace++instance MonoidParsing (Parser g) where+   endOfInput = Parser p+      where p rest success failure+               | Null.null rest = success () 0 rest+               | otherwise = failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["endOfInput"])+   getInput = Parser p+      where p rest success _ = success rest len mempty+               where !len = Factorial.length rest+   anyToken = Parser p+      where p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, suffix) -> success first 1 suffix+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["anyToken"])+   satisfy :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   satisfy predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, suffix) | predicate first -> success first 1 suffix+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfy"])+   satisfyChar :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s Char+   satisfyChar predicate = Parser p+      where p :: forall x. s -> (Char -> Int -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> success first 1 suffix+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   satisfyCharInput :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   satisfyCharInput predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.splitCharacterPrefix rest+               of Just (first, suffix) | predicate first -> success (Factorial.primePrefix rest) 1 suffix+                  _ -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["satisfyChar"])+   notSatisfy :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s ()+   notSatisfy predicate = Parser p+      where p :: forall x. s -> (() -> Int -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Factorial.splitPrimePrefix rest+               of Just (first, _)+                     | predicate first -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["notSatisfy"])+                  _ -> success () 0 rest+   notSatisfyChar :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s ()+   notSatisfyChar predicate = Parser p+      where p :: forall x. s -> (() -> Int -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure =+               case Textual.characterPrefix rest+               of Just first | predicate first+                               -> failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["notSatisfyChar"])+                  _ -> success () 0 rest+   scan :: forall t s. FactorialMonoid t => s -> (s -> t -> Maybe s) -> Parser g t t+   scan s0 f = Parser (p s0)+      where p :: forall x. s -> t -> (t -> Int -> t -> x) -> (FailureInfo -> x) -> x+            p s rest success _ = success prefix len suffix+               where (prefix, suffix, _) = Factorial.spanMaybe' s f rest+                     !len = Factorial.length prefix+   scanChars :: forall t s. TextualMonoid t => s -> (s -> Char -> Maybe s) -> Parser g t t+   scanChars s0 f = Parser (p s0)+      where p :: forall x. s -> t -> (t -> Int -> t -> x) -> (FailureInfo -> x) -> x+            p s rest success _ = success prefix len suffix+               where (prefix, suffix, _) = Textual.spanMaybe_' s f rest+                     !len = Factorial.length prefix+   takeWhile :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   takeWhile predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> x) -> (FailureInfo -> x) -> x+            p rest success _ +               | (prefix, suffix) <- Factorial.span predicate rest, +                 !len <- Factorial.length prefix = success prefix len suffix+   takeWhile1 :: forall s. FactorialMonoid s => (s -> Bool) -> Parser g s s+   takeWhile1 predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | (prefix, suffix) <- Factorial.span predicate rest, +                 !len <- Factorial.length prefix =+                    if len == 0+                    then failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeWhile1"])+                    else success prefix len suffix+   takeCharsWhile :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   takeCharsWhile predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> x) -> (FailureInfo -> x) -> x+            p rest success _ +               | (prefix, suffix) <- Textual.span_ False predicate rest, +                 !len <- Factorial.length prefix = success prefix len suffix+   takeCharsWhile1 :: forall s. TextualMonoid s => (Char -> Bool) -> Parser g s s+   takeCharsWhile1 predicate = Parser p+      where p :: forall x. s -> (s -> Int -> s -> x) -> (FailureInfo -> x) -> x+            p rest success failure+               | Null.null prefix = failure (FailureInfo 1 (fromIntegral $ Factorial.length rest) ["takeCharsWhile1"])+               | otherwise = success prefix len suffix+               where (prefix, suffix) = Textual.span_ False predicate rest+                     !len = Factorial.length prefix+   string :: forall s. (Cancellative.LeftReductiveMonoid s, FactorialMonoid s, Show s) => s -> Parser g s s+   string s = Parser p where+      p :: forall x. s -> (s -> Int -> s -> x) -> (FailureInfo -> x) -> x+      p s' success failure+         | Just suffix <- Cancellative.stripPrefix s s', !len <- Factorial.length s = success s len suffix+         | otherwise = failure (FailureInfo 1 (fromIntegral $ Factorial.length s') ["string " ++ show s])+   whiteSpace = () <$ takeCharsWhile isSpace+   concatMany :: forall s a. Monoid a => Parser g s a -> Parser g s a+   concatMany (Parser p) = Parser q+      where q :: forall x. s -> (a -> Int -> s -> x) -> (FailureInfo -> x) -> x+            q rest success _ = p rest success' failure+               where success' prefix !len suffix = +                        q suffix (\prefix' !len'-> success (prefix <> prefix') (len + len')) +                          (const $ success prefix len suffix)+                     failure _ = success mempty 0 rest+   {-# INLINABLE string #-}++-- | Continuation-passing PEG parser that keeps track of the parsed prefix length+--+-- @+-- 'parseComplete' :: ("Rank2".'Rank2.Functor' g, 'FactorialMonoid' s) =>+--                  g (Continued.'Parser' g s) -> s -> g 'ParseResults'+-- @+instance MultiParsing Parser where+   type ResultFunctor Parser = ParseResults+   -- | Returns an input prefix parse paired with the remaining input suffix.+   parsePrefix g input = Rank2.fmap (Compose . (\p-> applyParser p input (\a _ rest-> Right (rest, a)) +                                                                 (Left . fromFailure input))) g+   parseComplete g input = Rank2.fmap (\p-> applyParser p input (const . const . Right) (Left . fromFailure input))+                                      (Rank2.fmap (<* endOfInput) g)++fromFailure :: FactorialMonoid s => s -> FailureInfo -> ParseFailure+fromFailure s (FailureInfo _ pos msgs) = ParseFailure (Factorial.length s - fromIntegral pos + 1) (nub msgs)