packages feed

Earley 0.7.1 → 0.8.0

raw patch · 3 files changed

+55/−34 lines, 3 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

- Text.Earley.Grammar: [Empty] :: Prod r e t a
- Text.Earley.Grammar: [Plus] :: !(Prod r e t a) -> !(Prod r e t a) -> Prod r e t a
+ Text.Earley.Grammar: [Alts] :: ![Prod r e t a] -> !(Prod r e t (a -> b)) -> Prod r e t b

Files

Earley.cabal view
@@ -1,5 +1,5 @@ name:                Earley-version:             0.7.1+version:             0.8.0 synopsis:            Parsing all context-free grammars using Earley's algorithm. description:         See <https://www.github.com/ollef/Earley> for more                      information and@@ -21,7 +21,7 @@ library   exposed-modules:     Text.Earley.Derived, Text.Earley.Grammar, Text.Earley.Parser Text.Earley   -- other-modules:-  build-depends:       base ==4.8.*, containers >=0.5, ListLike >=4.1+  build-depends:       base >=4.7 && <4.9, containers >=0.5, ListLike >=4.1   -- hs-source-dirs:   default-language:    Haskell2010-  ghc-options:         -Wall -funbox-strict-fields -O2+  ghc-options:         -Wall -funbox-strict-fields
Text/Earley/Grammar.hs view
@@ -1,5 +1,5 @@ -- | Context-free grammars.-{-# LANGUAGE GADTs, RankNTypes #-}+{-# LANGUAGE CPP, GADTs, RankNTypes #-} module Text.Earley.Grammar   ( Prod(..)   , satisfy@@ -10,6 +10,9 @@ import Control.Applicative import Control.Monad import Control.Monad.Fix+#if !MIN_VERSION_base(4,8,0)+import Data.Monoid+#endif  infixr 0 <?> @@ -41,9 +44,8 @@   Pure        :: a -> Prod r e t a   -- Monoid/Alternative. We have to special-case 'many' (though it can be done   -- with rules) to be able to satisfy the Alternative interface.-  Plus        :: !(Prod r e t a) -> !(Prod r e t a) -> Prod r e t a+  Alts        :: ![Prod r e t a] -> !(Prod r e t (a -> b)) -> Prod r e t b   Many        :: !(Prod r e t a) -> !(Prod r e t ([a] -> b)) -> Prod r e t b-  Empty       :: Prod r e t a   -- Error reporting.   Named       :: !(Prod r e t a) -> e -> Prod r e t a @@ -65,32 +67,39 @@   fmap f (Terminal b p)    = Terminal b $ fmap (f .) p   fmap f (NonTerminal r p) = NonTerminal r $ fmap (f .) p   fmap f (Pure x)          = Pure $ f x-  fmap f (Plus p q)        = Plus (fmap f p) (fmap f q)+  fmap f (Alts as p)       = Alts as $ fmap (f .) p   fmap f (Many p q)        = Many p $ fmap (f .) q-  fmap _ Empty             = Empty   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+  where+    go (Alts as' (Pure f)) = fmap f <$> as'+    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-  Plus a b        <*> q = a <*> q <|> b <*> q+  Alts as p       <*> q = alts' as $ flip <$> p <*> q   Many a p        <*> q = Many a $ flip <$> p <*> q-  Empty           <*> _ = Empty   Named p n       <*> q = Named (p <*> q) n  instance Alternative (Prod r e t) where-  empty = Empty-  Empty     <|> q         = q-  p         <|> Empty     = p+  empty = alts []   Named p m <|> q         = Named (p <|> q) m   p         <|> Named q n = Named (p <|> q) n-  p         <|> q         = Plus p q-  many Empty = pure []-  many p     = Many p $ Pure id-  some p     = (:) <$> p <*> many p+  p         <|> q         = alts [p, q]+  many (Alts [] _) = pure []+  many p           = Many p $ Pure id+  some p           = (:) <$> p <*> many p  -- | A context-free grammar. --
Text/Earley/Parser.hs view
@@ -1,5 +1,5 @@ -- | Parsing.-{-# LANGUAGE BangPatterns, DeriveFunctor, GADTs, Rank2Types #-}+{-# LANGUAGE CPP, BangPatterns, DeriveFunctor, GADTs, Rank2Types #-} module Text.Earley.Parser   ( Report(..)   , Result(..)@@ -17,6 +17,9 @@ import qualified Data.ListLike as ListLike import Data.STRef.Lazy import Text.Earley.Grammar+#if !MIN_VERSION_base(4,8,0)+import Data.Monoid+#endif  ------------------------------------------------------------------------------- -- * Concrete rules and productions@@ -47,13 +50,16 @@   as <- nullable r   concat <$> mapM (\a -> nullableProd $ fmap ($ a) p) as nullableProd (Pure a)          = return [a]-nullableProd (Plus a b)        = mappend <$> nullableProd a <*> nullableProd b+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 Empty             = return mempty 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]@@ -61,6 +67,9 @@ 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) @@ -102,6 +111,9 @@   , contsArgs :: !(STRef s (Maybe (STRef s (ST 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 pos g p args cs) = Cont pos (composeArgs f g) p args cs contraMapCont f (FinalCont args)       = FinalCont (composeArgs f args)@@ -142,9 +154,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-              <$> (Conts <$> newSTRef [FinalCont noArgs] <*> newSTRef Nothing)-+initialState p = State (-1) p noArgs <$> (newConts =<< newSTRef [FinalCont noArgs])  ------------------------------------------------------------------------------- -- * Parsing@@ -172,7 +182,7 @@     -- The 'Int' is the position in the input where these results were     -- obtained, the @i@ the rest of the input, and the last component is the     -- continuation.-  deriving (Functor)+  deriving Functor  {-# INLINE uncons #-} uncons :: ListLike i t => i -> Maybe (t, i)@@ -228,12 +238,11 @@       nulls <- nullable r       let nullStates = [State spos p (pureArg a args) scont | a <- nulls]       if null ks then do -- The rule has not been expanded at this position.-        asref <- newSTRef Nothing-        let st' = State pos (ruleProd r) noArgs (Conts rkref asref)+        st' <- State pos (ruleProd r) noArgs <$> newConts rkref         parse (st' : nullStates ++ ss)               results               next-              ((writeSTRef (ruleConts r) =<< newSTRef mempty) >> reset)+              (resetConts r >> reset)               names               pos               ts@@ -247,8 +256,7 @@           modifySTRef asref (((++) <$> args a) <*>)           parse ss results next reset names pos ts         Nothing    -> do -- It hasn't.-          asref <- newSTRef (return mempty)-          modifySTRef asref (((++) <$> args a) <*>)+          asref <- newSTRef $ args a           writeSTRef argsRef $ Just asref           ks  <- simplifyCont scont           let kstates = map (contToState $ join $ readSTRef asref) ks@@ -260,15 +268,19 @@                 pos                 ts            | otherwise -> parse ss results next reset names pos ts--    Plus p q    -> parse (State spos p args scont : State spos q args scont : ss) results next reset names pos ts+    Alts as (Pure f) -> do+      let args' = funArg f `composeArgs` args+          sts   = [State pos a args' scont | a <- as]+      parse (sts ++ ss) results next reset names pos ts+    Alts as p -> do+      scont' <- newConts =<< newSTRef [Cont spos noArgs p args scont]+      let sts = [State pos a noArgs scont' | a <- as]+      parse (sts ++ ss) results next reset names pos ts     Many p q    -> do-      scont' <- Conts <$> newSTRef [Cont spos noArgs (Many p ((\f as a -> f (a : as)) <$> q)) args scont]-                      <*> newSTRef Nothing+      scont' <- newConts =<< newSTRef [Cont spos noArgs (Many p ((\f as a -> f (a : as)) <$> q)) args scont]       let st' = State pos p noArgs scont'           nst = State spos q (pureArg [] args) scont       parse (st' : nst : ss) results next reset names pos ts-    Empty       -> parse ss results next reset names pos ts     Named pr' n -> parse (State spos pr' args scont : ss) results next reset (n : names) pos ts  {-# INLINE parser #-}