Skip to content

Commit 0038e24

Browse files
committed
1 parent f7ce5c7 commit 0038e24

File tree

4 files changed

+223
-3
lines changed

4 files changed

+223
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 1.3.1.0
2+
3+
- Merge <http://hackage.haskell.org/package/regex-tdfa-text> into `regex-tdfa` <https://github.com/haskell-hvr/regex-tdfa/issues/4>
4+
15
# 1.3.0
26

37
Same as 1.2.3.3.

lib/Text/Regex/TDFA/Text.hs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
{-|
2+
Module : Text.Regex.TDFA.Text
3+
Copyright : Chris Kuklewicz 2007-2009, shelarcy 2012
4+
License : BSD-style (see the file LICENSE)
5+
6+
Maintainer : shelarcy <shelarcy@gmail.com>
7+
Stability : experimental
8+
Portability : GHC (uses text)
9+
10+
This modules provides 'RegexMaker' and 'RegexLike' instances for using
11+
'Text' with the TDFA backend ("Text.Regex.TDFA.NewDFA.Engine" and
12+
"Text.Regex.TDFA.NewDFA.Tester").
13+
14+
This exports instances of the high level API and the medium level
15+
API of 'compile','execute', and 'regexec'.
16+
-}
17+
module Text.Regex.TDFA.Text(
18+
Regex
19+
,CompOption
20+
,ExecOption
21+
,compile
22+
,execute
23+
,regexec
24+
) where
25+
26+
import Data.Array((!),elems)
27+
import qualified Data.Text as T(Text,empty,take,drop,uncons,unpack)
28+
29+
import Text.Regex.Base(RegexLike(..),RegexMaker(..),Extract(..),MatchArray,RegexContext(..))
30+
import Text.Regex.Base.Impl(polymatch,polymatchM)
31+
import Text.Regex.TDFA.ReadRegex(parseRegex)
32+
import Text.Regex.TDFA.String() -- piggyback on RegexMaker for String
33+
import Text.Regex.TDFA.TDFA(patternToRegex)
34+
import Text.Regex.TDFA.Common(Regex(..),CompOption,ExecOption(captureGroups),Position)
35+
36+
import Data.Maybe(listToMaybe)
37+
import Text.Regex.TDFA.NewDFA.Uncons(Uncons(uncons))
38+
import qualified Text.Regex.TDFA.NewDFA.Engine as Engine(execMatch)
39+
import qualified Text.Regex.TDFA.NewDFA.Tester as Tester(matchTest)
40+
41+
instance Extract T.Text where
42+
before = T.take; after = T.drop; empty = T.empty
43+
44+
instance Uncons T.Text where
45+
{- INLINE uncons #-}
46+
uncons = T.uncons
47+
48+
instance RegexContext Regex T.Text T.Text where
49+
match = polymatch
50+
matchM = polymatchM
51+
52+
instance RegexMaker Regex CompOption ExecOption T.Text where
53+
makeRegexOptsM c e source = makeRegexOptsM c e (T.unpack source)
54+
55+
{-# SPECIALIZE execMatch :: Regex -> Position -> Char -> T.Text -> [MatchArray] #-}
56+
execMatch :: Uncons text => Regex -> Position -> Char -> text -> [MatchArray]
57+
execMatch = Engine.execMatch
58+
59+
{-# SPECIALIZE myMatchTest :: Regex -> T.Text -> Bool #-}
60+
myMatchTest :: Uncons text => Regex -> text -> Bool
61+
myMatchTest = Tester.matchTest
62+
63+
instance RegexLike Regex T.Text where
64+
matchOnce r s = listToMaybe (matchAll r s)
65+
matchAll r s = execMatch r 0 '\n' s
66+
matchCount r s = length (matchAll r' s)
67+
where r' = r { regex_execOptions = (regex_execOptions r) {captureGroups = False} }
68+
matchTest = myMatchTest
69+
matchOnceText regex source =
70+
fmap (\ma -> let (o,l) = ma!0
71+
in (before o source
72+
,fmap (\ol -> (extract ol source,ol)) ma
73+
,after (o+l) source))
74+
(matchOnce regex source)
75+
matchAllText regex source =
76+
map (fmap (\ol -> (extract ol source,ol)))
77+
(matchAll regex source)
78+
79+
compile :: CompOption -- ^ Flags (summed together)
80+
-> ExecOption -- ^ Flags (summed together)
81+
-> T.Text -- ^ The regular expression to compile
82+
-> Either String Regex -- ^ Returns: the compiled regular expression
83+
compile compOpt execOpt txt =
84+
case parseRegex (T.unpack txt) of
85+
Left err -> Left ("parseRegex for Text.Regex.TDFA.Text failed:"++show err)
86+
Right pattern -> Right (patternToRegex pattern compOpt execOpt)
87+
88+
execute :: Regex -- ^ Compiled regular expression
89+
-> T.Text -- ^ Text to match against
90+
-> Either String (Maybe MatchArray)
91+
execute r txt = Right (matchOnce r txt)
92+
93+
regexec :: Regex -- ^ Compiled regular expression
94+
-> T.Text -- ^ Text to match against
95+
-> Either String (Maybe (T.Text, T.Text, T.Text, [T.Text]))
96+
regexec r txt =
97+
case matchOnceText r txt of
98+
Nothing -> Right (Nothing)
99+
Just (pre,mt,post) ->
100+
let main = fst (mt!0)
101+
rest = map fst (tail (elems mt)) -- will be []
102+
in Right (Just (pre,main,post,rest))

lib/Text/Regex/TDFA/Text/Lazy.hs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{-|
2+
Module : Text.Regex.TDFA.Text.Lazy
3+
Copyright : Chris Kuklewicz 2007-2009, shelarcy 2012
4+
License : BSD-style (see the file LICENSE)
5+
6+
Maintainer : shelarcy <shelarcy@gmail.com>
7+
Stability : experimental
8+
Portability : GHC (uses text)
9+
10+
This modules provides 'RegexMaker' and 'RegexLike' instances for using
11+
'Text' with the TDFA backend ("Text.Regex.TDFA.NewDFA.Engine" and
12+
"Text.Regex.TDFA.NewDFA.Tester").
13+
14+
This exports instances of the high level API and the medium level
15+
API of 'compile','execute', and 'regexec'.
16+
-}
17+
module Text.Regex.TDFA.Text.Lazy(
18+
Regex
19+
,CompOption
20+
,ExecOption
21+
,compile
22+
,execute
23+
,regexec
24+
) where
25+
26+
import Data.Array.IArray(Array,(!),elems,amap)
27+
import qualified Data.Text.Lazy as L(Text,empty,take,drop,uncons,unpack)
28+
29+
import Text.Regex.Base(MatchArray,RegexContext(..),Extract(..),RegexMaker(..),RegexLike(..))
30+
import Text.Regex.Base.Impl(polymatch,polymatchM)
31+
import Text.Regex.TDFA.ReadRegex(parseRegex)
32+
import Text.Regex.TDFA.String() -- piggyback on RegexMaker for String
33+
import Text.Regex.TDFA.TDFA(patternToRegex)
34+
import Text.Regex.TDFA.Common(Regex(..),CompOption,ExecOption(captureGroups),Position)
35+
36+
import Data.Maybe(listToMaybe)
37+
import Text.Regex.TDFA.NewDFA.Uncons(Uncons(uncons))
38+
import qualified Text.Regex.TDFA.NewDFA.Engine as Engine(execMatch)
39+
import qualified Text.Regex.TDFA.NewDFA.Tester as Tester(matchTest)
40+
41+
instance Extract L.Text where
42+
before = L.take . toEnum; after = L.drop . toEnum; empty = L.empty
43+
44+
instance RegexContext Regex L.Text L.Text where
45+
match = polymatch
46+
matchM = polymatchM
47+
48+
instance Uncons L.Text where
49+
{- INLINE uncons #-}
50+
uncons = L.uncons
51+
52+
instance RegexMaker Regex CompOption ExecOption L.Text where
53+
makeRegexOptsM c e source = makeRegexOptsM c e (L.unpack source)
54+
55+
{-# SPECIALIZE execMatch :: Regex -> Position -> Char -> L.Text -> [MatchArray] #-}
56+
execMatch :: Uncons text => Regex -> Position -> Char -> text -> [MatchArray]
57+
execMatch = Engine.execMatch
58+
59+
{-# SPECIALIZE myMatchTest :: Regex -> L.Text -> Bool #-}
60+
myMatchTest :: Uncons text => Regex -> text -> Bool
61+
myMatchTest = Tester.matchTest
62+
63+
instance RegexLike Regex L.Text where
64+
matchOnce r s = listToMaybe (matchAll r s)
65+
matchAll r s = execMatch r 0 '\n' s
66+
matchCount r s = length (matchAll r' s)
67+
where r' = r { regex_execOptions = (regex_execOptions r) {captureGroups = False} }
68+
matchTest = myMatchTest
69+
matchOnceText regex source =
70+
fmap (\ ma ->
71+
let (o,l) = ma!0
72+
in (before o source
73+
,fmap (\ ol -> (extract ol source,ol)) ma
74+
,after (o+l) source))
75+
(matchOnce regex source)
76+
matchAllText regex source =
77+
let go :: Int -> L.Text -> [Array Int (Int, Int)] -> [Array Int (L.Text, (Int, Int))]
78+
go i _ _ | i `seq` False = undefined
79+
go _i _t [] = []
80+
go i t (x:xs) =
81+
let (off0,len0) = x!0
82+
trans pair@(off,len) = (extract (off-i,len) t,pair)
83+
t' = after (off0+(len0-i)) t
84+
in fmap trans x : seq t' (go (off0+len0) t' xs)
85+
in go 0 source (matchAll regex source)
86+
87+
compile :: CompOption -- ^ Flags (summed together)
88+
-> ExecOption -- ^ Flags (summed together)
89+
-> L.Text -- ^ The regular expression to compile
90+
-> Either String Regex -- ^ Returns: the compiled regular expression
91+
compile compOpt execOpt txt =
92+
case parseRegex (L.unpack txt) of
93+
Left err -> Left ("parseRegex for Text.Regex.TDFA.Text.Lazy failed:"++show err)
94+
Right pattern -> Right (patternToRegex pattern compOpt execOpt)
95+
96+
execute :: Regex -- ^ Compiled regular expression
97+
-> L.Text -- ^ Text to match against
98+
-> Either String (Maybe MatchArray)
99+
execute r txt = Right (matchOnce r txt)
100+
101+
regexec :: Regex -- ^ Compiled regular expression
102+
-> L.Text -- ^ Text to match against
103+
-> Either String (Maybe (L.Text, L.Text, L.Text, [L.Text]))
104+
regexec r txt =
105+
case matchOnceText r txt of
106+
Nothing -> Right (Nothing)
107+
Just (pre,mt,post) ->
108+
let main = fst (mt!0)
109+
rest = map fst (tail (elems mt)) -- will be []
110+
in Right (Just (pre,main,post,rest))

regex-tdfa.cabal

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Name: regex-tdfa
2-
Version: 1.3.0
2+
Version: 1.3.1.0
33
License: BSD3
44
License-File: LICENSE
55
Copyright: Copyright (c) 2007, Christopher Kuklewicz
@@ -44,6 +44,7 @@ library
4444
, mtl == 2.*
4545
, parsec == 3.*
4646
, regex-base >= 0.93.1 && < 0.95
47+
, text >= 1.2.3 && < 1.3
4748

4849
-- Support Semigroup instances uniformly
4950
--
@@ -80,9 +81,12 @@ library
8081
Text.Regex.TDFA.String
8182
Text.Regex.TDFA.TDFA
8283
Text.Regex.TDFA.TNFA
84+
Text.Regex.TDFA.Text
85+
Text.Regex.TDFA.Text.Lazy
86+
8387
Buildable: True
8488
Extensions: MultiParamTypeClasses, FunctionalDependencies, BangPatterns, MagicHash, RecursiveDo, NoMonoPatBinds, ForeignFunctionInterface, UnboxedTuples, TypeOperators, FlexibleContexts, ExistentialQuantification, UnliftedFFITypes, TypeSynonymInstances, FlexibleInstances
85-
GHC-Options: -Wall -funbox-strict-fields -fspec-constr-count=10 -O2 -fno-warn-orphans
89+
GHC-Options: -Wall -funbox-strict-fields -fspec-constr-count=10 -fno-warn-orphans
8690
if flag(devel)
8791
ghc-prof-options: -auto-all
8892

@@ -92,7 +96,7 @@ test-suite regex-tdfa-unittest
9296
hs-source-dirs: test
9397
main-is: Main.hs
9498
extensions: FlexibleInstances, FlexibleContexts,Rank2Types
95-
GHC-Options: -Wall -O2 -funbox-strict-fields
99+
GHC-Options: -Wall -funbox-strict-fields
96100
if flag(devel)
97101
ghc-prof-options: -auto-all
98102
if !impl(ghc >= 8.0)

0 commit comments

Comments
 (0)