packages feed

Earley 0.9.0 → 0.10.0

raw patch · 13 files changed

+238/−218 lines, 13 filesdep ~basenew-component:exe:earley-infinitePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

- Text.Earley.Grammar: instance Control.Monad.Fix.MonadFix (Text.Earley.Grammar.Grammar r e)
- Text.Earley.Grammar: instance GHC.Base.Applicative (Text.Earley.Grammar.Grammar r e)
- Text.Earley.Grammar: instance GHC.Base.Functor (Text.Earley.Grammar.Grammar r e)
- Text.Earley.Grammar: instance GHC.Base.Monad (Text.Earley.Grammar.Grammar r e)
- Text.Earley.Internal: [ruleNullable] :: Rule s r e t a -> !(STRef s (Maybe [a]))
- Text.Earley.Internal: composeArgs :: Args s a b -> Args s b c -> Args s a c
- Text.Earley.Internal: funArg :: (f -> a) -> Args s f a
- Text.Earley.Internal: impureArgs :: ST s [x] -> Args s f a -> Args s (x -> f) a
- Text.Earley.Internal: mapArgs :: (a -> b) -> Args s f a -> Args s f b
- Text.Earley.Internal: noArgs :: Args s a a
- Text.Earley.Internal: nullable :: Rule s r e t a -> ST s [a]
- Text.Earley.Internal: nullableProd :: ProdR s r e t a -> ST s [a]
- Text.Earley.Internal: pureArg :: x -> Args s f a -> Args s (x -> f) a
- Text.Earley.Internal: pureArgs :: [x] -> Args s f a -> Args s (x -> f) a
- Text.Earley.Internal: safeTail :: ListLike i t => i -> i
- Text.Earley.Internal: type Args s f a = f -> ST s [a]
- Text.Earley.Internal: type Pos = Int
+ Text.Earley: infixr 0 <?>
+ Text.Earley.Grammar: alts :: [Prod r e t a] -> Prod r e t (a -> b) -> Prod r e t b
+ Text.Earley.Grammar: infixr 0 <?>
+ Text.Earley.Grammar: instance Control.Monad.Fix.MonadFix (Text.Earley.Grammar.Grammar r)
+ Text.Earley.Grammar: instance GHC.Base.Applicative (Text.Earley.Grammar.Grammar r)
+ Text.Earley.Grammar: instance GHC.Base.Functor (Text.Earley.Grammar.Grammar r)
+ Text.Earley.Grammar: instance GHC.Base.Monad (Text.Earley.Grammar.Grammar r)
+ Text.Earley.Internal: Results :: ST s [a] -> Results s a
+ Text.Earley.Internal: [unResults] :: Results s a -> ST s [a]
+ Text.Earley.Internal: instance GHC.Base.Applicative (Text.Earley.Internal.Results s)
+ Text.Earley.Internal: instance GHC.Base.Functor (Text.Earley.Internal.Results s)
+ Text.Earley.Internal: instance GHC.Base.Monad (Text.Earley.Internal.Results s)
+ Text.Earley.Internal: instance GHC.Base.Monoid (Text.Earley.Internal.Results s a)
+ Text.Earley.Internal: lazyResults :: ST s [a] -> ST s (Results s a)
+ Text.Earley.Internal: mkRule :: ProdR s r e t a -> ST s (Rule s r e t a)
+ Text.Earley.Internal: newtype Results s a
+ Text.Earley.Mixfix: mixfixExpressionSeparate :: [[(Holey (Prod r e t ident), Associativity, Holey ident -> [expr] -> expr)]] -> Prod r e t expr -> Grammar r (Prod r e t expr)
- Text.Earley: allParses :: (forall s. ST s (Result s e i a)) -> ([(a, Int)], Report e i)
+ Text.Earley: allParses :: (forall s. ST s (i -> ST s (Result s e i a))) -> i -> ([(a, Int)], Report e i)
- Text.Earley: data Grammar r e a
+ Text.Earley: data Grammar r a
- Text.Earley: fullParses :: ListLike i t => (forall s. ST s (Result s e i a)) -> ([a], Report e i)
+ Text.Earley: fullParses :: ListLike i t => (forall s. ST s (i -> ST s (Result s e i a))) -> i -> ([a], Report e i)
- Text.Earley: parser :: ListLike i t => (forall r. Grammar r e (Prod r e t a)) -> i -> ST s (Result s e i a)
+ Text.Earley: parser :: ListLike i t => (forall r. Grammar r (Prod r e t a)) -> ST s (i -> ST s (Result s e i a))
- Text.Earley: report :: ListLike i t => (forall s. ST s (Result s e i a)) -> Report e i
+ Text.Earley: report :: ListLike i t => (forall s. ST s (i -> ST s (Result s e i a))) -> i -> Report e i
- Text.Earley: rule :: Prod r e t a -> Grammar r e (Prod r e t a)
+ Text.Earley: rule :: Prod r e t a -> Grammar r (Prod r e t a)
- Text.Earley.Grammar: FixBind :: (a -> Grammar r e a) -> (a -> Grammar r e b) -> Grammar r e b
+ Text.Earley.Grammar: FixBind :: (a -> Grammar r a) -> (a -> Grammar r b) -> Grammar r b
- Text.Earley.Grammar: Return :: a -> Grammar r e a
+ Text.Earley.Grammar: Return :: a -> Grammar r a
- Text.Earley.Grammar: RuleBind :: Prod r e t a -> (Prod r e t a -> Grammar r e b) -> Grammar r e b
+ Text.Earley.Grammar: RuleBind :: Prod r e t a -> (Prod r e t a -> Grammar r b) -> Grammar r b
- Text.Earley.Grammar: data Grammar r e a
+ Text.Earley.Grammar: data Grammar r a
- Text.Earley.Grammar: rule :: Prod r e t a -> Grammar r e (Prod r e t a)
+ Text.Earley.Grammar: rule :: Prod r e t a -> Grammar r (Prod r e t a)
- Text.Earley.Internal: Cont :: !Pos -> !(Args s a b) -> !(ProdR s r e t (b -> c)) -> !(Args s c d) -> !(Conts s r e t d e') -> Cont s r e t a e'
+ Text.Earley.Internal: Cont :: !(a -> Results s b) -> !(ProdR s r e t (b -> c)) -> !(c -> Results s d) -> !(Conts s r e t d e') -> Cont s r e t a e'
- Text.Earley.Internal: Conts :: !(STRef s [Cont s r e t a c]) -> !(STRef s (Maybe (STRef s (ST s [a])))) -> Conts s r e t a c
+ Text.Earley.Internal: Conts :: !(STRef s [Cont s r e t a c]) -> !(STRef s (Maybe (STRef s (Results s a)))) -> Conts s r e t a c
- Text.Earley.Internal: Final :: f -> Args s f a -> State s r e t a
+ Text.Earley.Internal: Final :: !(Results s a) -> State s r e t a
- Text.Earley.Internal: FinalCont :: Args s a c -> Cont s r e t a c
+ Text.Earley.Internal: FinalCont :: (a -> Results s c) -> Cont s r e t a c
- Text.Earley.Internal: ParseEnv :: ![ST s [a]] -> ![State s a e t a] -> !(ST s ()) -> ![e] -> !Pos -> !i -> ParseEnv s e i t a
+ Text.Earley.Internal: ParseEnv :: ![ST s [a]] -> ![State s a e t a] -> !(ST s ()) -> ![e] -> !Int -> !i -> ParseEnv s e i t a
- Text.Earley.Internal: Rule :: ProdR s r e t a -> !(STRef s (Maybe [a])) -> !(STRef s (STRef s [Cont s r e t a r])) -> Rule s r e t a
+ Text.Earley.Internal: Rule :: ProdR s r e t a -> !(STRef s (STRef s [Cont s r e t a r])) -> Rule s r e t a
- Text.Earley.Internal: State :: !Pos -> !(ProdR s r e t f) -> !(Args s f b) -> !(Conts s r e t b a) -> State s r e t a
+ Text.Earley.Internal: State :: !(ProdR s r e t a) -> !(a -> Results s b) -> !(Conts s r e t b c) -> State s r e t c
- Text.Earley.Internal: [contsArgs] :: Conts s r e t a c -> !(STRef s (Maybe (STRef s (ST s [a]))))
+ Text.Earley.Internal: [contsArgs] :: Conts s r e t a c -> !(STRef s (Maybe (STRef s (Results s a))))
- Text.Earley.Internal: [pos] :: ParseEnv s e i t a -> !Pos
+ Text.Earley.Internal: [pos] :: ParseEnv s e i t a -> !Int
- Text.Earley.Internal: allParses :: (forall s. ST s (Result s e i a)) -> ([(a, Int)], Report e i)
+ Text.Earley.Internal: allParses :: (forall s. ST s (i -> ST s (Result s e i a))) -> i -> ([(a, Int)], Report e i)
- Text.Earley.Internal: contToState :: ST s [a] -> Cont s r e t a c -> State s r e t c
+ Text.Earley.Internal: contToState :: Results s a -> Cont s r e t a c -> State s r e t c
- Text.Earley.Internal: contraMapCont :: Args s b a -> Cont s r e t a c -> Cont s r e t b c
+ Text.Earley.Internal: contraMapCont :: (b -> Results s a) -> Cont s r e t a c -> Cont s r e t b c
- Text.Earley.Internal: fullParses :: ListLike i t => (forall s. ST s (Result s e i a)) -> ([a], Report e i)
+ Text.Earley.Internal: fullParses :: ListLike i t => (forall s. ST s (i -> ST s (Result s e i a))) -> i -> ([a], Report e i)
- Text.Earley.Internal: grammar :: Grammar (Rule s r) e a -> ST s a
+ Text.Earley.Internal: grammar :: Grammar (Rule s r) a -> ST s a
- Text.Earley.Internal: parser :: ListLike i t => (forall r. Grammar r e (Prod r e t a)) -> i -> ST s (Result s e i a)
+ Text.Earley.Internal: parser :: ListLike i t => (forall r. Grammar r (Prod r e t a)) -> ST s (i -> ST s (Result s e i a))
- Text.Earley.Internal: report :: ListLike i t => (forall s. ST s (Result s e i a)) -> Report e i
+ Text.Earley.Internal: report :: ListLike i t => (forall s. ST s (i -> ST s (Result s e i a))) -> i -> Report e i
- Text.Earley.Mixfix: mixfixExpression :: [[(Holey (Prod r e t ident), Associativity)]] -> Prod r e t expr -> (Holey ident -> [expr] -> expr) -> Grammar r e (Prod r e t expr)
+ Text.Earley.Mixfix: mixfixExpression :: [[(Holey (Prod r e t ident), Associativity)]] -> Prod r e t expr -> (Holey ident -> [expr] -> expr) -> Grammar r (Prod r e t expr)
- Text.Earley.Parser: allParses :: (forall s. ST s (Result s e i a)) -> ([(a, Int)], Report e i)
+ Text.Earley.Parser: allParses :: (forall s. ST s (i -> ST s (Result s e i a))) -> i -> ([(a, Int)], Report e i)
- Text.Earley.Parser: fullParses :: ListLike i t => (forall s. ST s (Result s e i a)) -> ([a], Report e i)
+ Text.Earley.Parser: fullParses :: ListLike i t => (forall s. ST s (i -> ST s (Result s e i a))) -> i -> ([a], Report e i)
- Text.Earley.Parser: parser :: ListLike i t => (forall r. Grammar r e (Prod r e t a)) -> i -> ST s (Result s e i a)
+ Text.Earley.Parser: parser :: ListLike i t => (forall r. Grammar r (Prod r e t a)) -> ST s (i -> ST s (Result s e i a))
- Text.Earley.Parser: report :: ListLike i t => (forall s. ST s (Result s e i a)) -> Report e i
+ Text.Earley.Parser: report :: ListLike i t => (forall s. ST s (i -> ST s (Result s e i a))) -> i -> Report e i

Files

Earley.cabal view
@@ -1,5 +1,5 @@ name:                Earley-version:             0.9.0+version:             0.10.0 synopsis:            Parsing all context-free grammars using Earley's algorithm. description:         See <https://www.github.com/ollef/Earley> for more                      information and@@ -13,6 +13,13 @@ category:            Parsing build-type:          Simple cabal-version:       >=1.10+tested-with:+                     GHC == 7.8.1,+                     GHC == 7.8.2,+                     GHC == 7.8.3,+                     GHC == 7.8.4,+                     GHC == 7.10.1,+                     GHC == 7.10.2  Flag Examples   Description: "Build examples"@@ -86,6 +93,15 @@   if !flag(examples)     buildable:         False   main-is:             Words.hs+  ghc-options:         -Wall+  hs-source-dirs:      examples+  default-language:    Haskell2010+  build-depends:       base, Earley++executable earley-infinite+  if !flag(examples)+    buildable:         False+  main-is:             Infinite.hs   ghc-options:         -Wall   hs-source-dirs:      examples   default-language:    Haskell2010
Text/Earley/Grammar.hs view
@@ -6,6 +6,7 @@   , (<?>)   , Grammar(..)   , rule+  , alts   ) where import Control.Applicative import Control.Monad@@ -71,32 +72,33 @@   fmap f (Many p q)        = Many p $ fmap (f .) q   fmap f (Named p n)       = Named (fmap f p) n -alts :: [Prod r e t a] -> Prod r e t a-alts as = Alts (as >>= go) $ pure id+-- | Smart constructor for alternatives.+alts :: [Prod r e t a] -> Prod r e t (a -> b) -> Prod r e t b+alts as p = case as >>= go of+  []  -> empty+  [a] -> a <**> p+  as' -> Alts as' p   where+    go (Alts [] _)         = []     go (Alts as' (Pure f)) = fmap f <$> as'+    go (Named p' n)        = map (<?> n) $ go p'     go a                   = [a] -alts' :: [Prod r e t a] -> Prod r e t (a -> b) -> Prod r e t b-alts' [] _        = Alts [] $ pure id-alts' as (Pure f) = alts $ fmap f <$> as-alts' as p        = Alts as p- instance Applicative (Prod r e t) where   pure = Pure   {-# INLINE (<*>) #-}   Terminal b p    <*> q = Terminal b $ flip <$> p <*> q   NonTerminal r p <*> q = NonTerminal r $ flip <$> p <*> q   Pure f          <*> q = fmap f q-  Alts as p       <*> q = alts' as $ flip <$> p <*> q+  Alts as p       <*> q = alts as $ flip <$> p <*> q   Many a p        <*> q = Many a $ flip <$> p <*> q   Named p n       <*> q = Named (p <*> q) n  instance Alternative (Prod r e t) where-  empty = alts []+  empty = Alts [] $ pure id   Named p m <|> q         = Named (p <|> q) m   p         <|> Named q n = Named (p <|> q) n-  p         <|> q         = alts [p, q]+  p         <|> q         = alts [p, q] $ pure id   many (Alts [] _) = pure []   many p           = Many p $ Pure id   some p           = (:) <$> p <*> many p@@ -107,8 +109,6 @@ -- -- @a@: The return type of the grammar (often a 'Prod'). ----- @e@: The type of names, used for example to report expected tokens.--- -- @r@: The type of a non-terminal. This plays a role similar to the @s@ in the --      type @ST s a@.  Since the 'parser' function expects the @r@ to be --      universally quantified, there is not much to do with this parameter@@ -118,29 +118,29 @@ -- e.g.  'Monad' and 'MonadFix'. Note that GHC has syntactic sugar for -- 'MonadFix': use @{-\# LANGUAGE RecursiveDo \#-}@ and @mdo@ instead of -- @do@.-data Grammar r e a where-  RuleBind :: Prod r e t a -> (Prod r e t a -> Grammar r e b) -> Grammar r e b-  FixBind  :: (a -> Grammar r e a) -> (a -> Grammar r e b) -> Grammar r e b-  Return   :: a -> Grammar r e a+data Grammar r a where+  RuleBind :: Prod r e t a -> (Prod r e t a -> Grammar r b) -> Grammar r b+  FixBind  :: (a -> Grammar r a) -> (a -> Grammar r b) -> Grammar r b+  Return   :: a -> Grammar r a -instance Functor (Grammar r e) where+instance Functor (Grammar r) where   fmap f (RuleBind ps h) = RuleBind ps (fmap f . h)   fmap f (FixBind g h)   = FixBind g (fmap f . h)   fmap f (Return x)      = Return $ f x -instance Applicative (Grammar r e) where+instance Applicative (Grammar r) where   pure  = return   (<*>) = ap -instance Monad (Grammar r e) where+instance Monad (Grammar r) where   return = Return   RuleBind ps f >>= k = RuleBind ps (f >=> k)   FixBind f g   >>= k = FixBind f (g >=> k)   Return x      >>= k = k x -instance MonadFix (Grammar r e) where+instance MonadFix (Grammar r) where   mfix f = FixBind f return  -- | Create a new non-terminal by giving its production.-rule :: Prod r e t a -> Grammar r e (Prod r e t a)+rule :: Prod r e t a -> Grammar r (Prod r e t a) rule p = RuleBind p return
Text/Earley/Internal.hs view
@@ -1,10 +1,11 @@-{-# LANGUAGE CPP, BangPatterns, DeriveFunctor, GADTs, Rank2Types #-}--- | This module exposes the internals of the package: its API may change independently of the PVP-compliant version number.+{-# LANGUAGE CPP, BangPatterns, DeriveFunctor, GADTs, Rank2Types, RecursiveDo #-}+-- | This module exposes the internals of the package: its API may change+-- independently of the PVP-compliant version number. module Text.Earley.Internal where import Control.Applicative import Control.Arrow-import Control.Monad import Control.Monad.Fix+import Control.Monad import Control.Monad.ST import Data.ListLike(ListLike) import qualified Data.ListLike as ListLike@@ -19,115 +20,79 @@ ------------------------------------------------------------------------------- -- | The concrete rule type that the parser uses data Rule s r e t a = Rule-  { ruleProd     :: ProdR s r e t a-  , ruleNullable :: !(STRef s (Maybe [a]))-  , ruleConts    :: !(STRef s (STRef s [Cont s r e t a r]))+  { ruleProd  :: ProdR s r e t a+  , ruleConts :: !(STRef s (STRef s [Cont s r e t a r]))   }  type ProdR s r e t a = Prod (Rule s r) e t a -nullable :: Rule s r e t a -> ST s [a]-nullable r = do-  mn <- readSTRef $ ruleNullable r-  case mn of-    Just xs -> return xs-    Nothing -> do-      writeSTRef (ruleNullable r) $ Just mempty-      res <- nullableProd $ ruleProd r-      writeSTRef (ruleNullable r) $ Just res-      return res--nullableProd :: ProdR s r e t a -> ST s [a]-nullableProd (Terminal _ _)    = return mempty-nullableProd (NonTerminal r p) = do-  as <- nullable r-  concat <$> mapM (\a -> nullableProd $ fmap ($ a) p) as-nullableProd (Pure a)          = return [a]-nullableProd (Alts as p)       = (\ass fs -> fs <*> concat ass)-                              <$> mapM nullableProd as <*> nullableProd p-nullableProd (Many p q)        = do-  as <- nullableProd $ (:[]) <$> p <|> pure []-  concat <$> mapM (\a -> nullableProd $ fmap ($ a) q) as-nullableProd (Named p _)       = nullableProd p- resetConts :: Rule s r e t a -> ST s ()-resetConts r = writeSTRef (ruleConts r) =<< newSTRef []---- | If we have something of type @f@, @'Args' s f a@ is what we need to do to--- @f@ to produce @a@s.-type Args s f a = f -> ST s [a]--noArgs :: Args s a a-noArgs = return . pure--funArg :: (f -> a) -> Args s f a-funArg f = mapArgs f noArgs--pureArg :: x -> Args s f a -> Args s (x -> f) a-pureArg x args = args . ($ x)+resetConts r = writeSTRef (ruleConts r) =<< newSTRef mempty -pureArgs :: [x] -> Args s f a -> Args s (x -> f) a-pureArgs xs args f = concat <$> mapM (args . f) xs+-------------------------------------------------------------------------------+-- * Delayed results+-------------------------------------------------------------------------------+newtype Results s a = Results { unResults :: ST s [a] }+  deriving Functor -impureArgs :: ST s [x] -> Args s f a -> Args s (x -> f) a-impureArgs mxs args f = fmap concat . mapM (args . f) =<< mxs+instance Applicative (Results s) where+  pure  = return+  (<*>) = ap -mapArgs :: (a -> b) -> Args s f a -> Args s f b-mapArgs = fmap . fmap . fmap+instance Monad (Results s) where+  return = Results . pure . pure+  Results stxs >>= f = Results $ do+    xs <- stxs+    concat <$> mapM (unResults . f) xs -composeArgs :: Args s a b -> Args s b c -> Args s a c-composeArgs ab bc a = fmap concat . mapM bc =<< ab a+instance Monoid (Results s a) where+  mempty = Results $ pure []+  mappend (Results sxs) (Results sys) = Results $ (++) <$> sxs <*> sys  ------------------------------------------------------------------------------- -- * States and continuations --------------------------------------------------------------------------------type Pos = Int- -- | An Earley state with result type @a@. data State s r e t a where-  State :: !Pos-        -> !(ProdR s r e t f)-        -> !(Args s f b)-        -> !(Conts s r e t b a)-        -> State s r e t a-  Final :: f -> Args s f a -> State s r e t a+  State :: !(ProdR s r e t a)+        -> !(a -> Results s b)+        -> !(Conts s r e t b c)+        -> State s r e t c+  Final :: Results s a -> State s r e t a  -- | A continuation accepting an @a@ and producing a @b@. data Cont s r e t a b where-  Cont      :: !Pos-            -> !(Args s a b)+  Cont      :: !(a -> Results s b)             -> !(ProdR s r e t (b -> c))-            -> !(Args s c d)+            -> !(c -> Results s d)             -> !(Conts s r e t d e')             -> Cont s r e t a e'-  FinalCont :: Args s a c -> Cont s r e t a c+  FinalCont :: (a -> Results s c) -> Cont s r e t a c  data Conts s r e t a c = Conts   { conts     :: !(STRef s [Cont s r e t a c])-  , contsArgs :: !(STRef s (Maybe (STRef s (ST s [a]))))+  , contsArgs :: !(STRef s (Maybe (STRef s (Results s a))))   }  newConts :: STRef s [Cont s r e t a c] -> ST s (Conts s r e t a c) newConts r = Conts r <$> newSTRef Nothing -contraMapCont :: Args s b a -> Cont s r e t a c -> Cont s r e t b c-contraMapCont f (Cont cpos g p args cs) = Cont cpos (composeArgs f g) p args cs-contraMapCont f (FinalCont args)       = FinalCont (composeArgs f args)+contraMapCont :: (b -> Results s a) -> Cont s r e t a c -> Cont s r e t b c+contraMapCont f (Cont g p args cs) = Cont (f >=> g) p args cs+contraMapCont f (FinalCont args)   = FinalCont (f >=> args) -contToState :: ST s [a] -> Cont s r e t a c -> State s r e t c-contToState r (Cont cpos g p args cs) = -  let mb = fmap concat . mapM g =<< r in-  State cpos p (impureArgs mb args) cs-contToState r (FinalCont args)       = Final id (impureArgs r args)+contToState :: Results s a -> Cont s r e t a c -> State s r e t c+contToState r (Cont g p args cs) = State p (\f -> fmap f (r >>= g) >>= args) cs+contToState r (FinalCont args)   = Final $ r >>= args  -- | Strings of non-ambiguous continuations can be optimised by removing---   indirections.+-- indirections. simplifyCont :: Conts s r e t b a -> ST s [Cont s r e t b a] simplifyCont Conts {conts = cont} = readSTRef cont >>= go False   where-    go !_ [Cont _ g (Pure f) args cont'] = do+    go !_ [Cont g (Pure f) args cont'] = do       ks' <- simplifyCont cont'-      go True $ map (contraMapCont $ mapArgs f g `composeArgs` args) ks'+      go True $ map (contraMapCont $ \b -> fmap f (g b) >>= args) ks'     go True ks = do       writeSTRef cont ks       return ks@@ -136,13 +101,17 @@ ------------------------------------------------------------------------------- -- * Grammars -------------------------------------------------------------------------------+mkRule :: ProdR s r e t a -> ST s (Rule s r e t a)+mkRule p = do+  c  <- newSTRef =<< newSTRef mempty+  return $ Rule p c+ -- | Interpret an abstract 'Grammar'.-grammar :: Grammar (Rule s r) e a -> ST s a+grammar :: Grammar (Rule s r) a -> ST s a grammar g = case g of   RuleBind p k -> do-    c  <- newSTRef =<< newSTRef mempty-    nr <- newSTRef Nothing-    grammar $ k $ NonTerminal (Rule p nr c) $ Pure id+    r <- mkRule p+    grammar $ k $ NonTerminal r $ Pure id   FixBind f k   -> do     a <- mfix $ fmap grammar f     grammar $ k a@@ -150,7 +119,7 @@  -- | Given a grammar, construct an initial state. initialState :: ProdR s a e t a -> ST s (State s a e t a)-initialState p = State (-1) p noArgs <$> (newConts =<< newSTRef [FinalCont noArgs])+initialState p = State p pure <$> (newConts =<< newSTRef [FinalCont pure])  ------------------------------------------------------------------------------- -- * Parsing@@ -186,12 +155,6 @@   | ListLike.null ts = Nothing   | otherwise        = Just $ ListLike.head ts -{-# INLINE safeTail #-}-safeTail :: ListLike i t => i -> i-safeTail ts-  | ListLike.null ts = ts-  | otherwise        = ListLike.tail ts- data ParseEnv s e i t a = ParseEnv   { results :: ![ST s [a]]     -- ^ Results ready to be reported (when this position has been processed)@@ -201,7 +164,7 @@     -- ^ Computation that resets the continuation refs of productions   , names :: ![e]     -- ^ Named productions encountered at this position-  , pos   :: !Pos+  , pos   :: !Int     -- ^ The current position in the input string   , input :: !i     -- ^ The input string@@ -235,83 +198,76 @@     } parse [] env@ParseEnv {results = []} = do   reset env-  parse (next env) (emptyParseEnv $ safeTail $ input env) {pos = pos env + 1}+  parse (next env) (emptyParseEnv $ ListLike.tail $ input env) {pos = pos env + 1} parse [] env = do   reset env   return $ Parsed (concat <$> sequence (results env)) (pos env) (input env)          $ parse [] env {results = [], reset = return ()} parse (st:ss) env = case st of-  Final f args -> parse ss env {results = args f : results env}-  State spos pr args scont -> case pr of+  Final res -> parse ss env {results = unResults res : results env}+  State pr args scont -> case pr of     Terminal f p -> case safeHead $ input env of-      Just t | f t -> parse ss env {next = State spos p (pureArg t args) scont+      Just t | f t -> parse ss env {next = State p (args . ($ t)) scont                                          : next env}       _            -> parse ss env     NonTerminal r p -> do       rkref <- readSTRef $ ruleConts r       ks    <- readSTRef rkref-      writeSTRef rkref (Cont spos noArgs p args scont : ks)-      nulls <- nullable r-      let nullStates | null nulls = mempty-                     | otherwise  = pure $ State spos p (pureArgs nulls args) scont+      writeSTRef rkref (Cont pure p args scont : ks)       if null ks then do -- The rule has not been expanded at this position.-        st' <- State (pos env) (ruleProd r) noArgs <$> newConts rkref-        parse (st' : nullStates ++ ss)+        st' <- State (ruleProd r) pure <$> newConts rkref+        parse (st' : ss)               env {reset = resetConts r >> reset env}       else -- The rule has already been expanded at this position.-        parse (nullStates ++ ss) env-    Pure a | spos /= pos env -> do+        parse ss env+    Pure a -> do       let argsRef = contsArgs scont       masref  <- readSTRef argsRef       case masref of         Just asref -> do -- The continuation has already been followed at this position.-          modifySTRef asref (((++) <$> args a) <*>)+          modifySTRef asref $ mappend $ args a           parse ss env         Nothing    -> do -- It hasn't.           asref <- newSTRef $ args a           writeSTRef argsRef $ Just asref           ks  <- simplifyCont scont-          let kstates = map (contToState $ join $ readSTRef asref) ks+          let kstates = map (contToState $ Results $ join $ unResults <$> readSTRef asref) ks           parse (kstates ++ ss)                 env {reset = writeSTRef argsRef Nothing >> reset env}-           | otherwise -> parse ss env     Alts as (Pure f) -> do-      let args' = funArg f `composeArgs` args-          sts   = [State spos a args' scont | a <- as]+      let args' = args . f+          sts   = [State a args' scont | a <- as]       parse (sts ++ ss) env     Alts as p -> do-      scont' <- newConts =<< newSTRef [Cont spos noArgs p args scont]-      -- State is (-1) so that nullable alts are expanded correctly-      let sts = [State (-1) a noArgs scont' | a <- as]+      scont' <- newConts =<< newSTRef [Cont pure p args scont]+      let sts = [State a pure scont' | a <- as]       parse (sts ++ ss) env-    Many p q    -> do-      c  <- newSTRef =<< newSTRef mempty-      nr <- newSTRef Nothing-      let r   = Rule (pure [] <|> (:) <$> p <*> NonTerminal r (Pure id)) nr c-          st' = State spos (NonTerminal r q) args scont-      parse (st' : ss) env-    Named pr' n -> parse (State spos pr' args scont : ss)+    Many p q -> mdo+      r <- mkRule $ pure [] <|> (:) <$> p <*> NonTerminal r (Pure id)+      parse (State (NonTerminal r q) args scont : ss) env+    Named pr' n -> parse (State pr' args scont : ss)                          env {names = n : names env}  {-# INLINE parser #-} -- | Create a parser from the given grammar. parser :: ListLike i t-       => (forall r. Grammar r e (Prod r e t a))-       -> i-       -> ST s (Result s e i a)-parser g xs = do+       => (forall r. Grammar r (Prod r e t a))+       -> ST s (i -> ST s (Result s e i a))+parser g = do   s <- initialState =<< grammar g-  parse [s] $ emptyParseEnv xs+  return $ parse [s] . emptyParseEnv  -- | Return all parses from the result of a given parser. The result may -- contain partial parses. The 'Int's are the position at which a result was -- produced.-allParses :: (forall s. ST s (Result s e i a)) -> ([(a, Int)], Report e i)-allParses p = runST $ p >>= go+allParses :: (forall s. ST s (i -> ST s (Result s e i a)))+          -> i+          -> ([(a, Int)], Report e i)+allParses p i = runST $ p >>= ($ i) >>= go   where     go :: Result s e i a -> ST s ([(a, Int)], Report e i)     go r = case r of-      Ended rep          -> return ([], rep)+      Ended rep           -> return ([], rep)       Parsed mas cpos _ k -> do         as <- mas         fmap (first (zip as (repeat cpos) ++)) $ go =<< k@@ -319,24 +275,30 @@ {-# INLINE fullParses #-} -- | Return all parses that reached the end of the input from the result of a --   given parser.-fullParses :: ListLike i t => (forall s. ST s (Result s e i a)) -> ([a], Report e i)-fullParses p = runST $ p >>= go+fullParses :: ListLike i t+           => (forall s. ST s (i -> ST s (Result s e i a)))+           -> i+           -> ([a], Report e i)+fullParses p i = runST $ p >>= ($ i) >>= go   where     go :: ListLike i t => Result s e i a -> ST s ([a], Report e i)     go r = case r of       Ended rep -> return ([], rep)-      Parsed mas _ i k-        | ListLike.null i -> do+      Parsed mas _ i' k+        | ListLike.null i' -> do           as <- mas           fmap (first (as ++)) $ go =<< k-        | otherwise       -> go =<< k+        | otherwise -> go =<< k  {-# INLINE report #-} -- | See e.g. how far the parser is able to parse the input string before it -- fails.  This can be much faster than getting the parse results for highly -- ambiguous grammars.-report :: ListLike i t => (forall s. ST s (Result s e i a)) -> Report e i-report p = runST $ p >>= go+report :: ListLike i t+       => (forall s. ST s (i -> ST s (Result s e i a)))+       -> i+       -> Report e i+report p i = runST $ p >>= ($ i) >>= go   where     go :: ListLike i t => Result s e i a -> ST s (Report e i)     go r = case r of
Text/Earley/Mixfix.hs view
@@ -3,14 +3,15 @@   ( Associativity(..)   , Holey   , mixfixExpression+  , mixfixExpressionSeparate   ) where  #if !MIN_VERSION_base(4,8,0) import Control.Applicative+import Data.Traversable(sequenceA) #endif import Data.Either import Data.Foldable(asum, foldrM)-import Data.Traversable(sequenceA) import Text.Earley  replicateA :: Applicative f => Int -> f a -> f [a]@@ -51,13 +52,33 @@   -> (Holey ident -> [expr] -> expr)   -- ^ How to combine the successful application of a holey identifier to its   -- arguments into an expression.-  -> Grammar r e (Prod r e t expr)-mixfixExpression table atom app = mdo+  -> Grammar r (Prod r e t expr)+mixfixExpression table atom app = mixfixExpressionSeparate table' atom+  where+    table' = [[(holey, assoc, app) | (holey, assoc) <- row] | row <- table]++-- | A version of 'mixfixExpression' with a separate semantic action for each+-- individual 'Holey' identifier.+mixfixExpressionSeparate+  :: [[(Holey (Prod r e t ident), Associativity, Holey ident -> [expr] -> expr)]]+  -- ^ A table of holey identifier parsers, with associativity information and+  -- semantic actions.  The identifiers should be in groups of precedence+  -- levels listed from binding the least to the most tightly.+  --+  -- The associativity is taken into account when an identifier starts or ends+  -- with holes, or both. Internal holes (e.g. after "if" in "if_then_else_")+  -- start from the beginning of the table.+  --+  -- Note that this rule also applies to identifiers with multiple consecutive+  -- holes, e.g. "if__" --- the associativity then applies to both holes.+  -> Prod r e t expr+  -- ^ An atom, i.e. what is parsed at the lowest level. This will+  -- commonly be a (non-mixfix) identifier or a parenthesised expression.+  -> Grammar r (Prod r e t expr)+mixfixExpressionSeparate table atom = mdo   expr <- foldrM ($) atom $ map (level expr) table   return expr   where-    app' xs = app (concatMap (either (map $ const Nothing) $ map Just) xs)-            $ concat $ lefts xs     level expr idents next = mdo       same <- rule $ asum $ next : map (mixfixIdent same) idents       return same@@ -71,8 +92,10 @@           Right ps':rest -> Right (consA p ps')       : rest           rest           -> Right (consA p $ pure []) : rest -        mixfixIdent same (ps, a) = app' <$> go (grp ps)+        mixfixIdent same (ps, a, f) = f' <$> go (grp ps)           where+            f' xs = f (concatMap (either (map $ const Nothing) $ map Just) xs)+                   $ concat $ lefts xs             go ps' = case ps' of               [] -> pure []               [Right p] -> pure . Right <$> p
bench/BenchAll.hs view
@@ -45,7 +45,7 @@  -- Earley parser -expr :: Grammar r String (Prod r String Token Expr)+expr :: Grammar r (Prod r String Token Expr) expr = mdo   x1 <- rule $ Add <$> x1 <* namedSymbol "+" <*> x2             <|> x2@@ -61,12 +61,12 @@ isIdent (x:_) = isAlpha x isIdent _     = False -sepBy1 :: Prod r e t a -> Prod r e t op -> Grammar r e (Prod r e t [a])+sepBy1 :: Prod r e t a -> Prod r e t op -> Grammar r (Prod r e t [a]) sepBy1 p op = mdo   ops <- rule $ pure [] <|> (:) <$ op <*> p <*> ops   rule $ (:) <$> p <*> ops -expr' :: Grammar r String (Prod r String Token Expr)+expr' :: Grammar r (Prod r String Token Expr) expr' = mdo   let var = Var <$> satisfy isIdent <|> symbol "(" *> mul <* symbol ")"   mul <- fmap (foldl1 Mul) <$> add `sepBy1` symbol "*"@@ -74,10 +74,10 @@   return mul  parseEarley :: [Token] -> Maybe Expr-parseEarley input = listToMaybe (fst (fullParses (parser expr input)))+parseEarley input = listToMaybe (fst (fullParses (parser expr) input))  parseEarley' :: [Token] -> Maybe Expr-parseEarley' input = listToMaybe (fst (fullParses (parser expr' input)))+parseEarley' input = listToMaybe (fst (fullParses (parser expr') input))  -- Parsec parsec 
examples/English.hs view
@@ -22,7 +22,7 @@                 | Verb Verb   deriving Show -sentence :: Grammar r String (Prod r String String Sentence)+sentence :: Grammar r (Prod r String String Sentence) sentence = mdo   noun       <- rule $ satisfy (`HS.member` nouns)      <?> "noun"   verb       <- rule $ satisfy (`HS.member` verbs)      <?> "verb"@@ -37,9 +37,9 @@  main :: IO () main = do-  let p = parser sentence . words-  print $ fullParses $ p "parsers use grammars"-  print $ fullParses $ p "parsers munch long sentences"-  print $ fullParses $ p "many great sentences confuse parsers"-  print $ fullParses $ p "parsers use use"-  print $ fullParses $ p "grammars many great confusing"+  let p = fullParses (parser sentence) . words+  print $ p "parsers use grammars"+  print $ p "parsers munch long sentences"+  print $ p "many great sentences confuse parsers"+  print $ p "parsers use use"+  print $ p "grammars many great confusing"
examples/Expr.hs view
@@ -10,7 +10,7 @@   | Var String   deriving (Eq, Ord, Show) -expr :: Grammar r String (Prod r String String Expr)+expr :: Grammar r (Prod r String String Expr) expr = mdo   x1 <- rule $ Add <$> x1 <* namedSymbol "+" <*> x2             <|> x2@@ -28,4 +28,4 @@ main :: IO () main = do   x:_ <- getArgs-  print $ fullParses $ parser expr $ words x+  print $ fullParses (parser expr) $ words x
examples/Expr2.hs view
@@ -11,7 +11,7 @@   | Lit Int   deriving (Show) -grammar :: forall r. Grammar r String (Prod r String Char Expr)+grammar :: forall r. Grammar r (Prod r String Char Expr) grammar = mdo    whitespace <- rule $ many $ satisfy isSpace@@ -42,4 +42,4 @@ main :: IO () main = do   x:_ <- getArgs-  print $ fullParses $ parser grammar x+  print $ fullParses (parser grammar) x
+ examples/Infinite.hs view
@@ -0,0 +1,19 @@+{-# LANGUAGE RecursiveDo #-}+module Testa where+import Control.Applicative+import Text.Earley++grammar :: Grammar r (Prod r () Char [Maybe Char])+grammar = mdo+  as <- rule $ pure []+            <|> (:) <$> optional (symbol 'a') <*> as+  return as++-- This grammar has an infinite number of results. We can still recognise the+-- language, i.e. get a report, but we can't get the results, because in doing+-- so the library will try to force a circular value.+main :: IO ()+main = do+  let input = "aaa"+  print $ report (parser grammar) input -- Works+  print $ fullParses (parser grammar) input -- Hangs
examples/Mixfix.hs view
@@ -29,7 +29,7 @@   , [("_*_",           LeftAssoc)]   ] -grammar :: Grammar r String (Prod r String String Expr)+grammar :: Grammar r (Prod r String String Expr) grammar = mdo   ident     <- rule $ (V . pure . Just) <$> satisfy (not . (`HS.member` mixfixParts))                    <?> "identifier"@@ -63,4 +63,4 @@ main :: IO () main = do   x:_ <- getArgs-  print $ first (map pretty) $ fullParses $ parser grammar $ tokenize x+  print $ first (map pretty) $ fullParses (parser grammar) $ tokenize x
examples/VeryAmbiguous.hs view
@@ -3,7 +3,7 @@ import System.Environment import Text.Earley -g :: Grammar r Char (Prod r Char Char ())+g :: Grammar r (Prod r Char Char ()) g = mdo   s <- rule $ () <$ symbol 'b'            <|> () <$ s <* s@@ -14,4 +14,4 @@ main :: IO () main = do   xs:_ <- getArgs-  print $ report $ parser g xs+  print $ report (parser g) xs
examples/Words.hs view
@@ -5,7 +5,7 @@  import Text.Earley -grammar :: Grammar r String (Prod r String Char [String])+grammar :: Grammar r (Prod r String Char [String]) grammar = mdo   whitespace  <- rule $ () <$ many (satisfy isSpace)   whitespace1 <- rule $ () <$ satisfy isSpace <* whitespace <?> "whitespace"@@ -23,4 +23,4 @@ main :: IO () main = do   x:_ <- getArgs-  print $ fullParses $ parser grammar x+  print $ fullParses (parser grammar) x
tests/Tests.hs view
@@ -22,14 +22,14 @@     \e -> e `elem` parseAmbiguousExpr (prettyExpr 0 e)   , QC.testProperty "The empty parser doesn't parse anything" $     \(input :: String) ->-      allParses (parser (return empty :: forall r. Grammar r () (Prod r () Char ())) input)+      allParses (parser (return empty :: forall r. Grammar r (Prod r () Char ()))) input       == (,) [] Report { position   = 0                        , expected   = []                        , unconsumed = input                        }   , QC.testProperty "Many empty parsers parse very little" $     \(input :: String) ->-      allParses (parser (return $ many empty <* pure "blah" :: forall r. Grammar r () (Prod r () Char [()])) input)+      allParses (parser (return $ many empty <* pure "blah" :: forall r. Grammar r (Prod r () Char [()]))) input       == (,) [([], 0)] Report { position   = 0                               , expected   = []                               , unconsumed = input@@ -39,104 +39,104 @@ unitTests :: TestTree unitTests = testGroup "Unit Tests"   [ HU.testCase "VeryAmbiguous gives the right number of results" $-      length (fst $ fullParses $ parser veryAmbiguous $ replicate 8 'b') @?= 2871+      length (fst $ fullParses (parser veryAmbiguous) $ replicate 8 'b') @?= 2871   , HU.testCase "VeryAmbiguous gives the correct report" $-      report (parser veryAmbiguous $ replicate 3 'b') @?=+      report (parser veryAmbiguous) (replicate 3 'b') @?=       Report {position = 3, expected = "s", unconsumed = ""}   , HU.testCase "Inline alternatives work" $       let input = "ababbbaaabaa" in-      allParses (parser inlineAlts input) @?= allParses (parser nonInlineAlts input)+      allParses (parser inlineAlts) input @?= allParses (parser nonInlineAlts) input   , HU.testCase "Some reversed words" $       let input = "wordwordstop"           l     = length input in-      allParses (parser someWords input)+      allParses (parser someWords) input       @?= (,) [(["stop", "drow", "drow"], l)] Report { position   = l                                                      , expected   = []                                                      , unconsumed = []                                                      }   , HU.testCase "Optional Nothing" $-      fullParses (parser (return optional_) "b")+      fullParses (parser $ return optional_) "b"       @?= (,) [(Nothing, 'b')] Report {position = 1, expected = "", unconsumed = ""}   , HU.testCase "Optional Just" $-      fullParses (parser (return optional_) "ab")+      fullParses (parser $ return optional_) "ab"       @?= (,) [(Just 'a', 'b')] Report {position = 2, expected = "", unconsumed = ""}   , HU.testCase "Optional using rules Nothing" $-      fullParses (parser optionalRule "b")+      fullParses (parser $ optionalRule) "b"       @?= (,) [(Nothing, 'b')] Report {position = 1, expected = "", unconsumed = ""}   , HU.testCase "Optional using rules Just" $-      fullParses (parser optionalRule "ab")+      fullParses (parser $ optionalRule) "ab"       @?= (,) [(Just 'a', 'b')] Report {position = 2, expected = "", unconsumed = ""}   , HU.testCase "Optional without continuation Nothing" $-      fullParses (parser (return $ optional $ namedSymbol 'a') "")+      fullParses (parser $ return $ optional $ namedSymbol 'a') ""       @?= (,) [Nothing] Report {position = 0, expected = "a", unconsumed = ""}   , HU.testCase "Optional without continuation Just" $-      fullParses (parser (return $ optional $ namedSymbol 'a') "a")+      fullParses (parser $ return $ optional $ namedSymbol 'a') "a"       @?= (,) [Just 'a'] Report {position = 1, expected = "", unconsumed = ""}   , HU.testCase "Optional using rules without continuation Nothing" $-      fullParses (parser (rule $ optional $ namedSymbol 'a') "")+      fullParses (parser $ rule $ optional $ namedSymbol 'a') ""       @?= (,) [Nothing] Report {position = 0, expected = "a", unconsumed = ""}   , HU.testCase "Optional using rules without continuation Just" $-      fullParses (parser (rule $ optional $ namedSymbol 'a') "a")+      fullParses (parser $ rule $ optional $ namedSymbol 'a') "a"       @?= (,) [Just 'a'] Report {position = 1, expected = "", unconsumed = ""}    , HU.testCase "Mixfix 1" $       let x = Ident [Just "x"] in-      fullParses (parser mixfixGrammar $ words "if x then x else x")+      fullParses (parser mixfixGrammar) (words "if x then x else x")       @?= (,) [App ifthenelse [x, x, x]] Report {position = 6, expected = [], unconsumed = []}   , HU.testCase "Mixfix 2" $       let x = Ident [Just "x"] in-      fullParses (parser mixfixGrammar $ words "prefix x postfix")+      fullParses (parser mixfixGrammar) (words "prefix x postfix")       @?= (,) [App prefix [App postfix [x]]] Report {position = 3, expected = [], unconsumed = []}   , HU.testCase "Mixfix 3" $       let x = Ident [Just "x"] in-      fullParses (parser mixfixGrammar $ words "x infix1 x infix2 x")+      fullParses (parser mixfixGrammar) (words "x infix1 x infix2 x")       @?= (,) [App infix1 [x, App infix2 [x, x]]] Report {position = 5, expected = [], unconsumed = []}   , HU.testCase "Mixfix 4" $       let x = Ident [Just "x"] in-      fullParses (parser mixfixGrammar $ words "[ x ]")+      fullParses (parser mixfixGrammar) (words "[ x ]")       @?= (,) [App closed [x]] Report {position = 3, expected = [], unconsumed = []}    , let x = words "+ + 5 6 7" in     HU.testCase "Mixfix issue #11 1" $-    fullParses (parser (issue11 LeftAssoc) x)+    fullParses (parser $ issue11 LeftAssoc) x     @?= (,) [] Report {position = 1, expected = [], unconsumed = drop 1 x}   , let x = words "+ 5 + 6 7" in     HU.testCase "Mixfix issue #11 2" $-    fullParses (parser (issue11 LeftAssoc) x)+    fullParses (parser $ issue11 LeftAssoc) x     @?= (,) [] Report {position = 2, expected = [], unconsumed = drop 2 x}   , let x = words "+ 5 6" in     HU.testCase "Mixfix issue #11 3" $-    fullParses (parser (issue11 LeftAssoc) x)+    fullParses (parser $ issue11 LeftAssoc) x     @?= (,) [Plus11 (Var11 "5") (Var11 "6")]             Report {position = 3, expected = [], unconsumed = []}   , let x = words "+ + 5 6 7" in     HU.testCase "Mixfix issue #11 4" $-    fullParses (parser (issue11 RightAssoc) x)+    fullParses (parser $ issue11 RightAssoc) x     @?= (,) [Plus11 (Plus11 (Var11 "5") (Var11 "6")) (Var11 "7")]             Report {position = 5, expected = [], unconsumed = []}   , let x = words "+ 5 + 6 7" in     HU.testCase "Mixfix issue #11 5" $-    fullParses (parser (issue11 RightAssoc) x)+    fullParses (parser $ issue11 RightAssoc) x     @?= (,) [Plus11 (Var11 "5") (Plus11 (Var11 "6") (Var11 "7"))]             Report {position = 5, expected = [], unconsumed = []}   , let x = words "+ 5 6" in     HU.testCase "Mixfix issue #11 6" $-    fullParses (parser (issue11 RightAssoc) x)+    fullParses (parser $ issue11 RightAssoc) x     @?= (,) [Plus11 (Var11 "5") (Var11 "6")]             Report {position = 3, expected = [], unconsumed = []}   , let x = words "+ + 5 6 7" in     HU.testCase "Mixfix issue #11 7" $-    fullParses (parser (issue11 NonAssoc) x)+    fullParses (parser $ issue11 NonAssoc) x     @?= (,) [Plus11 (Plus11 (Var11 "5") (Var11 "6")) (Var11 "7")]             Report {position = 5, expected = [], unconsumed = []}   , let x = words "+ 5 + 6 7" in     HU.testCase "Mixfix issue #11 8" $-    fullParses (parser (issue11 NonAssoc) x)+    fullParses (parser $ issue11 NonAssoc) x     @?= (,) [Plus11 (Var11 "5") (Plus11 (Var11 "6") (Var11 "7"))]             Report {position = 5, expected = [], unconsumed = []}   , let x = words "+ 5 6" in     HU.testCase "Mixfix issue #11 9" $-    fullParses (parser (issue11 NonAssoc) x)+    fullParses (parser $ issue11 NonAssoc) x     @?= (,) [Plus11 (Var11 "5") (Var11 "6")]             Report {position = 3, expected = [], unconsumed = []}   ]@@ -144,27 +144,27 @@ optional_ :: Prod r Char Char (Maybe Char, Char) optional_ = (,) <$> optional (namedSymbol 'a') <*> namedSymbol 'b' -optionalRule :: Grammar r Char (Prod r Char Char (Maybe Char, Char))+optionalRule :: Grammar r (Prod r Char Char (Maybe Char, Char)) optionalRule = mdo   test <- rule $ (,) <$> optional (namedSymbol 'a') <*> namedSymbol 'b'   return test -inlineAlts :: Grammar r Char (Prod r Char Char String)+inlineAlts :: Grammar r (Prod r Char Char String) inlineAlts = mdo   p <- rule $ pure []            <|> (:) <$> (namedSymbol 'a' <|> namedSymbol 'b') <*> p   return p -nonInlineAlts :: Grammar r Char (Prod r Char Char String)+nonInlineAlts :: Grammar r (Prod r Char Char String) nonInlineAlts = mdo   ab <- rule $ namedSymbol 'a' <|> namedSymbol 'b'   p  <- rule $ pure [] <|> (:) <$> ab <*> p   return p -someWords :: Grammar r () (Prod r () Char [String])+someWords :: Grammar r (Prod r () Char [String]) someWords = return $ flip (:) <$> (map reverse <$> some (word "word")) <*> word "stop" -veryAmbiguous :: Grammar r Char (Prod r Char Char ())+veryAmbiguous :: Grammar r (Prod r Char Char ()) veryAmbiguous = mdo   s <- rule $ () <$ symbol 'b'            <|> () <$ s <* s@@ -173,10 +173,10 @@   return s  parseExpr :: String -> [Expr]-parseExpr input = fst (fullParses (parser expr (lexExpr input))) -- We need to annotate types for point-free version+parseExpr input = fst (fullParses (parser expr) (lexExpr input)) -- We need to annotate types for point-free version  parseAmbiguousExpr :: String -> [Expr]-parseAmbiguousExpr input = fst (fullParses (parser ambiguousExpr (lexExpr input)))+parseAmbiguousExpr input = fst (fullParses (parser ambiguousExpr) (lexExpr input))  data Expr   = Add Expr Expr@@ -198,7 +198,7 @@   shrink (Add a b)  = a : b : [ Add a' b | a' <- shrink a ] ++ [ Add a b' | b' <- shrink b ]   shrink (Mul a b)  = a : b : [ Mul a' b | a' <- shrink a ] ++ [ Mul a b' | b' <- shrink b ] -expr :: Grammar r String (Prod r String String Expr)+expr :: Grammar r (Prod r String String Expr) expr = mdo   x1 <- rule $ Add <$> x1 <* namedSymbol "+" <*> x2             <|> x2@@ -213,7 +213,7 @@     ident (x:_) = isAlpha x     ident _     = False -ambiguousExpr :: Grammar r String (Prod r String String Expr)+ambiguousExpr :: Grammar r (Prod r String String Expr) ambiguousExpr = mdo   x1 <- rule $ Add <$> x1 <* namedSymbol "+" <*> x1             <|> x2@@ -251,7 +251,7 @@ data MixfixExpr = Ident (Holey String) | App (Holey String) [MixfixExpr]   deriving (Eq, Show) -mixfixGrammar :: Grammar r String (Prod r String String MixfixExpr)+mixfixGrammar :: Grammar r (Prod r String String MixfixExpr) mixfixGrammar = mixfixExpression table                                  (Ident . pure . Just <$> namedSymbol "x")                                  App@@ -280,7 +280,7 @@   | Plus11 Mixfix11 Mixfix11   deriving (Eq, Ord, Show) -issue11 :: Associativity -> Grammar r String (Prod r String String Mixfix11)+issue11 :: Associativity -> Grammar r (Prod r String String Mixfix11) issue11 a = mdo     atomicExpr <- rule $ Var11 <$> satisfy (/= "+")