regex-applicative 0.3.1 → 0.3.2
raw patch · 10 files changed
+51/−23 lines, 10 files
Files
- CHANGES.md +5/−0
- Text/Regex/Applicative.hs +1/−0
- Text/Regex/Applicative/Compile.hs +4/−2
- Text/Regex/Applicative/Interface.hs +10/−5
- Text/Regex/Applicative/Object.hs +5/−5
- Text/Regex/Applicative/Reference.hs +3/−1
- Text/Regex/Applicative/StateQueue.hs +17/−7
- Text/Regex/Applicative/Types.hs +1/−1
- regex-applicative.cabal +2/−2
- tests/test.hs +3/−0
CHANGES.md view
@@ -1,6 +1,11 @@ Changes ======= +0.3.2+-----++Add `msym`+ 0.3.1 -----
Text/Regex/Applicative.hs view
@@ -15,6 +15,7 @@ ( RE , sym , psym+ , msym , anySym , string , reFoldl
Text/Regex/Applicative/Compile.hs view
@@ -48,7 +48,9 @@ Symbol i p -> \k -> [t $ nonEmptyCont k] where -- t :: (a -> [Thread s r]) -> Thread s r t k = Thread i $ \s ->- if p s then k s else []+ case p s of+ Just r -> k r+ Nothing -> [] App n1 n2 -> let a1 = compile2 n1 a2 = compile2 n2@@ -95,7 +97,7 @@ Eps -> return k Symbol i@(ThreadId n) p -> do modify $ IntMap.insert n $- (p, k)+ (isJust . p, k) return [STransition i] App n1 n2 -> go n1 =<< go n2 k Alt n1 n2 -> (++) <$> go n1 k <*> go n2 k
Text/Regex/Applicative/Interface.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TypeFamilies, GADTs #-}+{-# LANGUAGE TypeFamilies, GADTs, TupleSections #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Text.Regex.Applicative.Interface where import Control.Applicative hiding (empty)@@ -36,7 +36,7 @@ comap f re = case re of Eps -> Eps- Symbol t p -> Fmap f $ Symbol t (p . f)+ Symbol t p -> Symbol t (p . f) Alt r1 r2 -> Alt (comap f r1) (comap f r2) App r1 r2 -> App (comap f r1) (comap f r2) Fmap g r -> Fmap g (comap f r)@@ -46,15 +46,20 @@ -- | Match and return a single symbol which satisfies the predicate psym :: (s -> Bool) -> RE s s-psym p = Symbol (error "Not numbered symbol") p+psym p = msym (\s -> if p s then Just s else Nothing) +-- | Like 'psym', but allows to return a computed value instead of the+-- original symbol+msym :: (s -> Maybe a) -> RE s a+msym p = Symbol (error "Not numbered symbol") p+ -- | Match and return the given symbol sym :: Eq s => s -> RE s s sym s = psym (s ==) -- | Match and return any single symbol anySym :: RE s s-anySym = psym (const True)+anySym = msym Just -- | Match and return the given sequence of symbols. --@@ -98,7 +103,7 @@ -- | Return matched symbols as part of the return value withMatched :: RE s a -> RE s (a, [s]) withMatched Eps = flip (,) [] <$> Eps-withMatched x@(Symbol _ _) = (id &&& pure) <$> x+withMatched (Symbol t p) = Symbol t (\s -> (,[s]) <$> p s) withMatched (Alt a b) = withMatched a <|> withMatched b withMatched (App a b) = (\(f, s) (x, t) -> (f x, s ++ t)) <$>
Text/Regex/Applicative/Object.hs view
@@ -32,7 +32,7 @@ import qualified Text.Regex.Applicative.StateQueue as SQ import qualified Text.Regex.Applicative.Compile as Compile import Data.Maybe-import Data.List+import Data.Foldable as F import Control.Monad.Trans.State import Control.Applicative hiding (empty) @@ -45,13 +45,13 @@ -- | List of all threads of an object. Each non-result thread has a unique id. threads :: ReObject s r -> [Thread s r]-threads (ReObject sq) = SQ.getElements sq+threads (ReObject sq) = F.toList sq -- | Create an object from a list of threads. It is recommended that all -- threads come from the same 'ReObject', unless you know what you're doing. -- However, it should be safe to filter out or rearrange threads. fromThreads :: [Thread s r] -> ReObject s r-fromThreads ts = foldl' (flip addThread) emptyObject ts+fromThreads ts = F.foldl' (flip addThread) emptyObject ts -- | Check whether a thread is a result thread isResult :: Thread s r -> Bool@@ -85,8 +85,8 @@ case t of Accept {} -> q Thread _ c ->- foldl' (\q x -> addThread x q) q $ c s- newQueue = SQ.fold accum emptyObject sq+ F.foldl' (\q x -> addThread x q) q $ c s+ newQueue = F.foldl' accum emptyObject sq in newQueue -- | Feed a symbol into a non-result thread. It is an error to call 'stepThread'
Text/Regex/Applicative/Reference.hs view
@@ -52,7 +52,9 @@ Eps -> return $ error "eps" Symbol _ p -> do c <- getChar- if p c then return c else empty+ case p c of+ Just r -> return r+ Nothing -> empty Alt a1 a2 -> re2monad a1 <|> re2monad a2 App a1 a2 -> re2monad a1 <*> re2monad a2 Fmap f a -> fmap f $ re2monad a
Text/Regex/Applicative/StateQueue.hs view
@@ -1,25 +1,35 @@+-- | This internal module is exposed only for testing and benchmarking. You+-- don't need to import it. module Text.Regex.Applicative.StateQueue ( StateQueue , empty , insert , insertUnique- , fold , getElements ) where import Prelude hiding (read, lookup, replicate) import qualified Data.IntSet as IntSet-import Data.List (foldl')+import Data.Foldable as F +-- | 'StateQueue' is a data structure that can efficiently insert elements+-- (preserving their order)+-- and check whether an element with the given 'Int' key is already in the queue. data StateQueue a = StateQueue { elements :: [a] , ids :: !IntSet.IntSet }+ deriving (Eq,Show) +instance Foldable StateQueue where+ foldr f a = F.foldr f a . getElements++-- | Get the list of all elements getElements :: StateQueue a -> [a] getElements = reverse . elements {-# INLINE empty #-}+-- | The empty state queue empty :: StateQueue a empty = StateQueue { elements = []@@ -27,8 +37,9 @@ } {-# INLINE insert #-}+-- | Insert an element in the state queue, unless there is already an element with the same key insertUnique- :: Int+ :: Int -- ^ key -> a -> StateQueue a -> StateQueue a@@ -39,13 +50,12 @@ , ids = IntSet.insert i ids } +-- | Insert an element in the state queue without a key.+--+-- Since 'insert' doesn't take a key, it won't affect any 'insertUnique'. insert :: a -> StateQueue a -> StateQueue a insert v sq = sq { elements = v : elements sq }--{-# INLINE fold #-}-fold :: (a -> x -> a) -> a -> StateQueue x -> a-fold f acc0 sq = foldl' f acc0 (reverse $ elements sq)
Text/Regex/Applicative/Types.hs view
@@ -57,7 +57,7 @@ -- and returns the list of @ra@'s return values on those strings. data RE s a where Eps :: RE s ()- Symbol :: ThreadId -> (s -> Bool) -> RE s s+ Symbol :: ThreadId -> (s -> Maybe a) -> RE s a Alt :: RE s a -> RE s a -> RE s a App :: RE s (a -> b) -> RE s a -> RE s b Fmap :: (a -> b) -> RE s a -> RE s b
regex-applicative.cabal view
@@ -1,5 +1,5 @@ Name: regex-applicative-Version: 0.3.1+Version: 0.3.2 Synopsis: Regex-based parsing with applicative interface Description: regex-applicative is a Haskell library for parsing using regular expressions.@@ -27,10 +27,10 @@ Text.Regex.Applicative.Object Text.Regex.Applicative.Common Text.Regex.Applicative.Reference+ Text.Regex.Applicative.StateQueue Other-modules: Text.Regex.Applicative.Interface Text.Regex.Applicative.Types Text.Regex.Applicative.Compile- Text.Regex.Applicative.StateQueue GHC-Options: -O2 -Wall -fno-warn-name-shadowing
tests/test.hs view
@@ -13,6 +13,8 @@ import Test.Tasty.SmallCheck import Test.Tasty.HUnit +import StateQueue+ -- Small alphabets as SmallCheck's series newtype A = A { a :: Char } deriving Show instance Monad m => Serial m A where@@ -173,6 +175,7 @@ (Just ("ta", "bc","")) ] ]+ , stateQueueTests ] where t name n = localOption (SmallCheckDepth n) . testProperty name