{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
module Text.Regex.TDFA.Pattern
    (Pattern(..)
    ,PatternSet(..)
    ,PatternSetCharacterClass(..)
    ,PatternSetCollatingElement(..)
    ,PatternSetEquivalenceClass(..)
    ,GroupIndex
    ,DoPa(..)
    ,decodeCharacterClass, decodePatternSet
    ,showPattern
    ,starTrans
    ,starTrans',simplify',dfsPattern
    ) where
import Data.List(intersperse,partition)
import qualified Data.Set as Set
import Data.Set (Set)
import Text.Regex.TDFA.Common(DoPa(..),GroupIndex,common_error)
err :: String -> a
err :: forall a. String -> a
err = forall a. String -> String -> a
common_error String
"Text.Regex.TDFA.Pattern"
data Pattern
  = PEmpty
      
  | PGroup  (Maybe GroupIndex) Pattern
      
      
  | POr     [Pattern]
      
  | PConcat [Pattern]
      
  | PQuest  Pattern
      
  | PPlus   Pattern
      
  | PStar   Bool Pattern
      
      
  | PBound  Int (Maybe Int) Pattern
      
      
  
  | PCarat  { Pattern -> DoPa
getDoPa :: DoPa }
      
  | PDollar { getDoPa :: DoPa }
      
  
  | PDot    { getDoPa :: DoPa }
      
  | PAny    { getDoPa :: DoPa, Pattern -> PatternSet
getPatternSet :: PatternSet }
      
  | PAnyNot { getDoPa :: DoPa, getPatternSet :: PatternSet }
      
  | PEscape { getDoPa :: DoPa, Pattern -> Char
getPatternChar :: Char }
      
  | PChar   { getDoPa :: DoPa, getPatternChar :: Char }
      
  
  | PNonCapture Pattern
     
  | PNonEmpty Pattern
     
  deriving (Pattern -> Pattern -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Pattern -> Pattern -> Bool
$c/= :: Pattern -> Pattern -> Bool
== :: Pattern -> Pattern -> Bool
$c== :: Pattern -> Pattern -> Bool
Eq, Int -> Pattern -> ShowS
[Pattern] -> ShowS
Pattern -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Pattern] -> ShowS
$cshowList :: [Pattern] -> ShowS
show :: Pattern -> String
$cshow :: Pattern -> String
showsPrec :: Int -> Pattern -> ShowS
$cshowsPrec :: Int -> Pattern -> ShowS
Show)
showPattern :: Pattern -> String
showPattern :: Pattern -> String
showPattern Pattern
pIn =
  case Pattern
pIn of
    Pattern
PEmpty -> String
"()"
    PGroup Maybe Int
_ Pattern
p -> ShowS
paren (Pattern -> String
showPattern Pattern
p)
    POr [Pattern]
ps -> forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall a b. (a -> b) -> a -> b
$ forall a. a -> [a] -> [a]
intersperse String
"|" (forall a b. (a -> b) -> [a] -> [b]
map Pattern -> String
showPattern [Pattern]
ps)
    PConcat [Pattern]
ps -> forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Pattern -> String
showPattern [Pattern]
ps
    PQuest Pattern
p -> (Pattern -> String
showPattern Pattern
p)forall a. [a] -> [a] -> [a]
++String
"?"
    PPlus Pattern
p -> (Pattern -> String
showPattern Pattern
p)forall a. [a] -> [a] -> [a]
++String
"+"
    
    PStar Bool
_ Pattern
p -> (Pattern -> String
showPattern Pattern
p)forall a. [a] -> [a] -> [a]
++String
"*"
    PBound Int
i (Just Int
j) Pattern
p | Int
iforall a. Eq a => a -> a -> Bool
==Int
j -> Pattern -> String
showPattern Pattern
p forall a. [a] -> [a] -> [a]
++ (Char
'{'forall a. a -> [a] -> [a]
:forall a. Show a => a -> String
show Int
i)forall a. [a] -> [a] -> [a]
++String
"}"
    PBound Int
i Maybe Int
mj Pattern
p -> Pattern -> String
showPattern Pattern
p forall a. [a] -> [a] -> [a]
++ (Char
'{'forall a. a -> [a] -> [a]
:forall a. Show a => a -> String
show Int
i) forall a. [a] -> [a] -> [a]
++ forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
",}" (\Int
j -> Char
','forall a. a -> [a] -> [a]
:forall a. Show a => a -> String
show Int
jforall a. [a] -> [a] -> [a]
++String
"}") Maybe Int
mj
    
    PCarat DoPa
_ -> String
"^"
    PDollar DoPa
_ -> String
"$"
    PDot DoPa
_ -> String
"."
    PAny DoPa
_ PatternSet
ps -> (Char
'['forall a. a -> [a] -> [a]
:forall a. Show a => a -> String
show PatternSet
ps)forall a. [a] -> [a] -> [a]
++String
"]"
    PAnyNot DoPa
_ PatternSet
ps ->  (Char
'['forall a. a -> [a] -> [a]
:Char
'^'forall a. a -> [a] -> [a]
:forall a. Show a => a -> String
show PatternSet
ps)forall a. [a] -> [a] -> [a]
++String
"]"
    PEscape DoPa
_ Char
c -> Char
'\\'forall a. a -> [a] -> [a]
:Char
cforall a. a -> [a] -> [a]
:[]
    PChar DoPa
_ Char
c -> [Char
c]
    
    PNonCapture Pattern
p -> Pattern -> String
showPattern Pattern
p
    PNonEmpty Pattern
p -> Pattern -> String
showPattern Pattern
p
  where 
        paren :: ShowS
paren String
s = (Char
'('forall a. a -> [a] -> [a]
:String
s)forall a. [a] -> [a] -> [a]
++String
")"
data PatternSet = PatternSet (Maybe (Set Char))
                             (Maybe (Set PatternSetCharacterClass))
                             (Maybe (Set PatternSetCollatingElement))
                             (Maybe (Set PatternSetEquivalenceClass))
                             deriving (PatternSet -> PatternSet -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PatternSet -> PatternSet -> Bool
$c/= :: PatternSet -> PatternSet -> Bool
== :: PatternSet -> PatternSet -> Bool
$c== :: PatternSet -> PatternSet -> Bool
Eq)
instance Show PatternSet where
  showsPrec :: Int -> PatternSet -> ShowS
showsPrec Int
i (PatternSet Maybe (Set Char)
s Maybe (Set PatternSetCharacterClass)
scc Maybe (Set PatternSetCollatingElement)
sce Maybe (Set PatternSetEquivalenceClass)
sec) =
    let (String
special,String
normal) = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String
"",String
"") ((forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"]-")) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
Set.toAscList) Maybe (Set Char)
s
        charSpec :: String
charSpec = (if Char
']' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
special then (Char
']'forall a. a -> [a] -> [a]
:) else forall a. a -> a
id) (ShowS
byRange String
normal)
        scc' :: String
scc' = forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" ((forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a. Show a => a -> String
show) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
Set.toList) Maybe (Set PatternSetCharacterClass)
scc
        sce' :: String
sce' = forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" ((forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a. Show a => a -> String
show) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
Set.toList) Maybe (Set PatternSetCollatingElement)
sce
        sec' :: String
sec' = forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" ((forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall a. Show a => a -> String
show) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
Set.toList) Maybe (Set PatternSetEquivalenceClass)
sec
    in forall a. Show a => a -> ShowS
shows String
charSpec
       forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
i String
scc' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
i String
sce' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
i String
sec'
       forall b c a. (b -> c) -> (a -> b) -> a -> c
. if Char
'-' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
special then Char -> ShowS
showChar Char
'-' else forall a. a -> a
id
    where byRange :: ShowS
byRange xAll :: String
xAll@(~(Char
x:String
xs))
            | forall (t :: * -> *) a. Foldable t => t a -> Int
length String
xAll forall a. Ord a => a -> a -> Bool
<=Int
3 = String
xAll
            | Bool
otherwise       = Char -> Int -> ShowS
groupRange Char
x Int
1 String
xs
          groupRange :: Char -> Int -> ShowS
groupRange Char
x Int
n (Char
y:String
ys) = if (forall a. Enum a => a -> Int
fromEnum Char
y)forall a. Num a => a -> a -> a
-(forall a. Enum a => a -> Int
fromEnum Char
x) forall a. Eq a => a -> a -> Bool
== Int
n then Char -> Int -> ShowS
groupRange Char
x (forall a. Enum a => a -> a
succ Int
n) String
ys
                                  else (if Int
n forall a. Ord a => a -> a -> Bool
<=Int
3 then forall a. Int -> [a] -> [a]
take Int
n [Char
x..]
                                        else Char
xforall a. a -> [a] -> [a]
:Char
'-'forall a. a -> [a] -> [a]
:(forall a. Enum a => Int -> a
toEnum (forall a. Enum a => a -> a
pred Int
nforall a. Num a => a -> a -> a
+forall a. Enum a => a -> Int
fromEnum Char
x))forall a. a -> [a] -> [a]
:[]) forall a. [a] -> [a] -> [a]
++ Char -> Int -> ShowS
groupRange Char
y Int
1 String
ys
          groupRange Char
x Int
n [] = if Int
n forall a. Ord a => a -> a -> Bool
<=Int
3 then forall a. Int -> [a] -> [a]
take Int
n [Char
x..]
                              else Char
xforall a. a -> [a] -> [a]
:Char
'-'forall a. a -> [a] -> [a]
:(forall a. Enum a => Int -> a
toEnum (forall a. Enum a => a -> a
pred Int
nforall a. Num a => a -> a -> a
+forall a. Enum a => a -> Int
fromEnum Char
x))forall a. a -> [a] -> [a]
:[]
newtype PatternSetCharacterClass   = PatternSetCharacterClass   {PatternSetCharacterClass -> String
unSCC::String}
  deriving (PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
$c/= :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
== :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
$c== :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
Eq,Eq PatternSetCharacterClass
PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
PatternSetCharacterClass -> PatternSetCharacterClass -> Ordering
PatternSetCharacterClass
-> PatternSetCharacterClass -> PatternSetCharacterClass
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PatternSetCharacterClass
-> PatternSetCharacterClass -> PatternSetCharacterClass
$cmin :: PatternSetCharacterClass
-> PatternSetCharacterClass -> PatternSetCharacterClass
max :: PatternSetCharacterClass
-> PatternSetCharacterClass -> PatternSetCharacterClass
$cmax :: PatternSetCharacterClass
-> PatternSetCharacterClass -> PatternSetCharacterClass
>= :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
$c>= :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
> :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
$c> :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
<= :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
$c<= :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
< :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
$c< :: PatternSetCharacterClass -> PatternSetCharacterClass -> Bool
compare :: PatternSetCharacterClass -> PatternSetCharacterClass -> Ordering
$ccompare :: PatternSetCharacterClass -> PatternSetCharacterClass -> Ordering
Ord)
newtype PatternSetCollatingElement = PatternSetCollatingElement {PatternSetCollatingElement -> String
unSCE::String}
  deriving (PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
$c/= :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
== :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
$c== :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
Eq,Eq PatternSetCollatingElement
PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
PatternSetCollatingElement
-> PatternSetCollatingElement -> Ordering
PatternSetCollatingElement
-> PatternSetCollatingElement -> PatternSetCollatingElement
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PatternSetCollatingElement
-> PatternSetCollatingElement -> PatternSetCollatingElement
$cmin :: PatternSetCollatingElement
-> PatternSetCollatingElement -> PatternSetCollatingElement
max :: PatternSetCollatingElement
-> PatternSetCollatingElement -> PatternSetCollatingElement
$cmax :: PatternSetCollatingElement
-> PatternSetCollatingElement -> PatternSetCollatingElement
>= :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
$c>= :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
> :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
$c> :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
<= :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
$c<= :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
< :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
$c< :: PatternSetCollatingElement -> PatternSetCollatingElement -> Bool
compare :: PatternSetCollatingElement
-> PatternSetCollatingElement -> Ordering
$ccompare :: PatternSetCollatingElement
-> PatternSetCollatingElement -> Ordering
Ord)
newtype PatternSetEquivalenceClass = PatternSetEquivalenceClass {PatternSetEquivalenceClass -> String
unSEC::String}
  deriving (PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
$c/= :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
== :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
$c== :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
Eq,Eq PatternSetEquivalenceClass
PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
PatternSetEquivalenceClass
-> PatternSetEquivalenceClass -> Ordering
PatternSetEquivalenceClass
-> PatternSetEquivalenceClass -> PatternSetEquivalenceClass
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PatternSetEquivalenceClass
-> PatternSetEquivalenceClass -> PatternSetEquivalenceClass
$cmin :: PatternSetEquivalenceClass
-> PatternSetEquivalenceClass -> PatternSetEquivalenceClass
max :: PatternSetEquivalenceClass
-> PatternSetEquivalenceClass -> PatternSetEquivalenceClass
$cmax :: PatternSetEquivalenceClass
-> PatternSetEquivalenceClass -> PatternSetEquivalenceClass
>= :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
$c>= :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
> :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
$c> :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
<= :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
$c<= :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
< :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
$c< :: PatternSetEquivalenceClass -> PatternSetEquivalenceClass -> Bool
compare :: PatternSetEquivalenceClass
-> PatternSetEquivalenceClass -> Ordering
$ccompare :: PatternSetEquivalenceClass
-> PatternSetEquivalenceClass -> Ordering
Ord)
instance Show PatternSetCharacterClass where
  showsPrec :: Int -> PatternSetCharacterClass -> ShowS
showsPrec Int
_ PatternSetCharacterClass
p = Char -> ShowS
showChar Char
'[' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
':' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (PatternSetCharacterClass -> String
unSCC PatternSetCharacterClass
p) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
':' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
']'
instance Show PatternSetCollatingElement where
  showsPrec :: Int -> PatternSetCollatingElement -> ShowS
showsPrec Int
_ PatternSetCollatingElement
p = Char -> ShowS
showChar Char
'[' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
'.' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (PatternSetCollatingElement -> String
unSCE PatternSetCollatingElement
p) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
'.' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
']'
instance Show PatternSetEquivalenceClass where
  showsPrec :: Int -> PatternSetEquivalenceClass -> ShowS
showsPrec Int
_ PatternSetEquivalenceClass
p = Char -> ShowS
showChar Char
'[' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
'=' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (PatternSetEquivalenceClass -> String
unSEC PatternSetEquivalenceClass
p) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
'=' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
']'
decodePatternSet :: PatternSet -> Set Char
decodePatternSet :: PatternSet -> Set Char
decodePatternSet (PatternSet Maybe (Set Char)
msc Maybe (Set PatternSetCharacterClass)
mscc Maybe (Set PatternSetCollatingElement)
_ Maybe (Set PatternSetEquivalenceClass)
msec) =
  let baseMSC :: Set Char
baseMSC = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Set a
Set.empty forall a. a -> a
id Maybe (Set Char)
msc
      withMSCC :: Set Char
withMSCC = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Ord a => a -> Set a -> Set a
Set.insert) Set Char
baseMSC  (forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap PatternSetCharacterClass -> String
decodeCharacterClass forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
Set.toAscList) Maybe (Set PatternSetCharacterClass)
mscc)
      withMSEC :: Set Char
withMSEC = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Ord a => a -> Set a -> Set a
Set.insert) Set Char
withMSCC (forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap PatternSetEquivalenceClass -> String
unSEC forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
Set.toAscList) Maybe (Set PatternSetEquivalenceClass)
msec)
  in Set Char
withMSEC
decodeCharacterClass :: PatternSetCharacterClass -> String
decodeCharacterClass :: PatternSetCharacterClass -> String
decodeCharacterClass (PatternSetCharacterClass String
s) =
  case String
s of
    String
"alnum"  -> [Char
'0'..Char
'9']forall a. [a] -> [a] -> [a]
++[Char
'A'..Char
'Z']forall a. [a] -> [a] -> [a]
++[Char
'a'..Char
'z']
    String
"digit"  -> [Char
'0'..Char
'9']
    String
"punct"  -> [Char
'\33'..Char
'\47']forall a. [a] -> [a] -> [a]
++[Char
'\58'..Char
'\64']forall a. [a] -> [a] -> [a]
++[Char
'\91'..Char
'\96']forall a. [a] -> [a] -> [a]
++[Char
'\123'..Char
'\126']
    String
"alpha"  -> [Char
'A'..Char
'Z']forall a. [a] -> [a] -> [a]
++[Char
'a'..Char
'z']
    String
"graph"  -> [Char
'\41'..Char
'\126']
    String
"space"  -> String
"\t\n\v\f\r "
    String
"blank"  -> String
"\t "
    String
"lower"  -> [Char
'a'..Char
'z']
    String
"upper"  -> [Char
'A'..Char
'Z']
    String
"cntrl"  -> [Char
'\0'..Char
'\31']forall a. [a] -> [a] -> [a]
++String
"\127" 
    String
"print"  -> [Char
'\32'..Char
'\126']
    String
"xdigit" -> [Char
'0'..Char
'9']forall a. [a] -> [a] -> [a]
++[Char
'A'..Char
'F']forall a. [a] -> [a] -> [a]
++[Char
'a'..Char
'f']
    String
"word"   -> [Char
'0'..Char
'9']forall a. [a] -> [a] -> [a]
++[Char
'A'..Char
'Z']forall a. [a] -> [a] -> [a]
++String
"_"forall a. [a] -> [a] -> [a]
++[Char
'a'..Char
'z']
    String
_ -> []
starTrans :: Pattern -> Pattern
starTrans :: Pattern -> Pattern
starTrans = (Pattern -> Pattern) -> Pattern -> Pattern
dfsPattern (Pattern -> Pattern
simplify' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pattern -> Pattern
starTrans')
dfsPattern :: (Pattern -> Pattern)  
           -> Pattern               
           -> Pattern               
dfsPattern :: (Pattern -> Pattern) -> Pattern -> Pattern
dfsPattern Pattern -> Pattern
f = Pattern -> Pattern
dfs
 where unary :: (Pattern -> Pattern) -> Pattern -> Pattern
unary Pattern -> Pattern
c = Pattern -> Pattern
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pattern -> Pattern
c forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pattern -> Pattern
dfs
       dfs :: Pattern -> Pattern
dfs Pattern
pattern = case Pattern
pattern of
                       POr [Pattern]
ps -> Pattern -> Pattern
f ([Pattern] -> Pattern
POr (forall a b. (a -> b) -> [a] -> [b]
map Pattern -> Pattern
dfs [Pattern]
ps))
                       PConcat [Pattern]
ps -> Pattern -> Pattern
f ([Pattern] -> Pattern
PConcat (forall a b. (a -> b) -> [a] -> [b]
map Pattern -> Pattern
dfs [Pattern]
ps))
                       PGroup Maybe Int
i Pattern
p -> (Pattern -> Pattern) -> Pattern -> Pattern
unary (Maybe Int -> Pattern -> Pattern
PGroup Maybe Int
i) Pattern
p
                       PQuest Pattern
p -> (Pattern -> Pattern) -> Pattern -> Pattern
unary Pattern -> Pattern
PQuest Pattern
p
                       PPlus Pattern
p -> (Pattern -> Pattern) -> Pattern -> Pattern
unary Pattern -> Pattern
PPlus Pattern
p
                       PStar Bool
i Pattern
p -> (Pattern -> Pattern) -> Pattern -> Pattern
unary (Bool -> Pattern -> Pattern
PStar Bool
i) Pattern
p
                       PBound Int
i Maybe Int
mi Pattern
p -> (Pattern -> Pattern) -> Pattern -> Pattern
unary (Int -> Maybe Int -> Pattern -> Pattern
PBound Int
i Maybe Int
mi) Pattern
p
                       Pattern
_ -> Pattern -> Pattern
f Pattern
pattern
reGroup :: Pattern -> Pattern
reGroup :: Pattern -> Pattern
reGroup p :: Pattern
p@(PConcat [Pattern]
xs) | Int
2 forall a. Ord a => a -> a -> Bool
<= forall (t :: * -> *) a. Foldable t => t a -> Int
length [Pattern]
xs = Maybe Int -> Pattern -> Pattern
PGroup forall a. Maybe a
Nothing Pattern
p
reGroup p :: Pattern
p@(POr [Pattern]
xs)     | Int
2 forall a. Ord a => a -> a -> Bool
<= forall (t :: * -> *) a. Foldable t => t a -> Int
length [Pattern]
xs = Maybe Int -> Pattern -> Pattern
PGroup forall a. Maybe a
Nothing Pattern
p
reGroup Pattern
p = Pattern
p
starTrans' :: Pattern -> Pattern
starTrans' :: Pattern -> Pattern
starTrans' Pattern
pIn =
  case Pattern
pIn of 
    PQuest Pattern
p -> [Pattern] -> Pattern
POr [Pattern
p,Pattern
PEmpty]
    PPlus Pattern
p | Pattern -> Bool
canOnlyMatchNull Pattern
p -> Pattern
p
            | Bool
otherwise -> Pattern -> Pattern
asGroup forall a b. (a -> b) -> a -> b
$ [Pattern] -> Pattern
PConcat [Pattern -> Pattern
reGroup Pattern
p,Bool -> Pattern -> Pattern
PStar Bool
False Pattern
p]
    PBound Int
i Maybe Int
_        Pattern
_ | Int
iforall a. Ord a => a -> a -> Bool
<Int
0 -> Pattern
PEmpty  
    PBound Int
i (Just Int
j) Pattern
_ | Int
iforall a. Ord a => a -> a -> Bool
>Int
j -> Pattern
PEmpty  
    PBound Int
_ (Just Int
0) Pattern
_ -> Pattern
PEmpty
    PBound Int
0 Maybe Int
Nothing  Pattern
p | Pattern -> Bool
canOnlyMatchNull Pattern
p -> Pattern -> Pattern
quest Pattern
p
                        | Bool
otherwise -> Bool -> Pattern -> Pattern
PStar Bool
True Pattern
p
    PBound Int
0 (Just Int
1) Pattern
p -> Pattern -> Pattern
quest Pattern
p
    PBound Int
i Maybe Int
Nothing  Pattern
p | Pattern -> Bool
canOnlyMatchNull Pattern
p -> Pattern
p
                        | Bool
otherwise -> Pattern -> Pattern
asGroup forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Pattern] -> Pattern
PConcat forall a b. (a -> b) -> a -> b
$ forall {b}. (b -> b) -> Int -> b -> b
apply (Pattern
nc'pforall a. a -> [a] -> [a]
:) (forall a. Enum a => a -> a
pred Int
i) [Pattern -> Pattern
reGroup Pattern
p,Bool -> Pattern -> Pattern
PStar Bool
False Pattern
p]
      where nc'p :: Pattern
nc'p = Pattern -> Pattern
nonCapture' Pattern
p
    PBound Int
0 (Just Int
j) Pattern
p | Pattern -> Bool
canOnlyMatchNull Pattern
p -> Pattern -> Pattern
quest Pattern
p
                        
                        
                        | Bool
otherwise -> Pattern -> Pattern
quest forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pattern -> Pattern -> Pattern
concat' Pattern
p) forall a b. (a -> b) -> a -> b
$
                                        forall {b}. (b -> b) -> Int -> b -> b
apply (Pattern -> Pattern
nonEmpty' forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pattern -> Pattern -> Pattern
concat' Pattern
p)) (Int
jforall a. Num a => a -> a -> a
-Int
2) (Pattern -> Pattern
nonEmpty' Pattern
p)
    PBound Int
i (Just Int
j) Pattern
p | Pattern -> Bool
canOnlyMatchNull Pattern
p -> Pattern
p
                        | Int
i forall a. Eq a => a -> a -> Bool
== Int
j -> Pattern -> Pattern
asGroup forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Pattern] -> Pattern
PConcat forall a b. (a -> b) -> a -> b
$ forall {b}. (b -> b) -> Int -> b -> b
apply (Pattern
nc'pforall a. a -> [a] -> [a]
:) (forall a. Enum a => a -> a
pred Int
i) [Pattern -> Pattern
reGroup Pattern
p]
                        | Bool
otherwise -> Pattern -> Pattern
asGroup forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Pattern] -> Pattern
PConcat forall a b. (a -> b) -> a -> b
$ forall {b}. (b -> b) -> Int -> b -> b
apply (Pattern
nc'pforall a. a -> [a] -> [a]
:) (forall a. Enum a => a -> a
pred Int
i)
                                        [Pattern -> Pattern
reGroup Pattern
p,forall {b}. (b -> b) -> Int -> b -> b
apply (Pattern -> Pattern
nonEmpty' forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pattern -> Pattern -> Pattern
concat' Pattern
p)) (Int
jforall a. Num a => a -> a -> a
-Int
iforall a. Num a => a -> a -> a
-Int
1) (Pattern
ne'p) ]
      where nc'p :: Pattern
nc'p = Pattern -> Pattern
nonCapture' Pattern
p
            ne'p :: Pattern
ne'p = Pattern -> Pattern
nonEmpty' Pattern
p
    PStar Bool
mayFirstBeNull Pattern
p | Pattern -> Bool
canOnlyMatchNull Pattern
p -> if Bool
mayFirstBeNull then Pattern -> Pattern
quest Pattern
p
                                                                    else Pattern
PEmpty
                           | Bool
otherwise -> Pattern
pass
    
    Pattern
PEmpty -> Pattern
pass
    PGroup {} -> Pattern
pass
    POr {} -> Pattern
pass
    PConcat {} -> Pattern
pass
    PCarat {} -> Pattern
pass
    PDollar {} -> Pattern
pass
    PDot {} -> Pattern
pass
    PAny {} -> Pattern
pass
    PAnyNot {} -> Pattern
pass
    PEscape {} -> Pattern
pass
    PChar {} -> Pattern
pass
    PNonCapture {} -> Pattern
pass
    PNonEmpty {} -> Pattern
pass 
  where
    quest :: Pattern -> Pattern
quest = (\ Pattern
p -> [Pattern] -> Pattern
POr [Pattern
p,Pattern
PEmpty])  
    concat' :: Pattern -> Pattern -> Pattern
concat' Pattern
a Pattern
b = Pattern -> Pattern
simplify' forall a b. (a -> b) -> a -> b
$ [Pattern] -> Pattern
PConcat [Pattern -> Pattern
reGroup Pattern
a,Pattern -> Pattern
reGroup Pattern
b]      
    nonEmpty' :: Pattern -> Pattern
nonEmpty' = (\ Pattern
p -> Pattern -> Pattern
simplify' forall a b. (a -> b) -> a -> b
$ [Pattern] -> Pattern
POr [Pattern
PEmpty,Pattern
p]) 
    nonCapture' :: Pattern -> Pattern
nonCapture' = Pattern -> Pattern
PNonCapture
    apply :: (b -> b) -> Int -> b -> b
apply b -> b
f Int
n b
x = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall a b. (a -> b) -> a -> b
($) b
x (forall a. Int -> a -> [a]
replicate Int
n b -> b
f) 
    asGroup :: Pattern -> Pattern
asGroup Pattern
p = Maybe Int -> Pattern -> Pattern
PGroup forall a. Maybe a
Nothing (Pattern -> Pattern
simplify' Pattern
p)
    pass :: Pattern
pass = Pattern
pIn
simplify' :: Pattern -> Pattern
simplify' :: Pattern -> Pattern
simplify' x :: Pattern
x@(POr [Pattern]
_) =
  let ps' :: [Pattern]
ps' = case forall a. (a -> Bool) -> [a] -> ([a], [a])
span Pattern -> Bool
notPEmpty (Pattern -> [Pattern]
flatten Pattern
x) of
              ([Pattern]
notEmpty,[]) -> [Pattern]
notEmpty
              ([Pattern]
notEmpty,Pattern
_:[Pattern]
rest) -> [Pattern]
notEmpty forall a. [a] -> [a] -> [a]
++ (Pattern
PEmptyforall a. a -> [a] -> [a]
:forall a. (a -> Bool) -> [a] -> [a]
filter Pattern -> Bool
notPEmpty [Pattern]
rest) 
  in case [Pattern]
ps' of
       [] -> Pattern
PEmpty
       [Pattern
p] -> Pattern
p
       [Pattern]
_ -> [Pattern] -> Pattern
POr [Pattern]
ps'
simplify' x :: Pattern
x@(PConcat [Pattern]
_) =
  let ps' :: [Pattern]
ps' = forall a. (a -> Bool) -> [a] -> [a]
filter Pattern -> Bool
notPEmpty (Pattern -> [Pattern]
flatten Pattern
x)
  in case [Pattern]
ps' of
       [] -> Pattern
PEmpty
       [Pattern
p] -> Pattern
p
       [Pattern]
_ -> [Pattern] -> Pattern
PConcat [Pattern]
ps' 
simplify' (PStar Bool
_ Pattern
PEmpty) = Pattern
PEmpty
simplify' (PNonCapture Pattern
PEmpty) = Pattern
PEmpty 
simplify' Pattern
other = Pattern
other
flatten :: Pattern -> [Pattern]
flatten :: Pattern -> [Pattern]
flatten (POr [Pattern]
ps) = (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\Pattern
x -> case Pattern
x of
                                       POr [Pattern]
ps' -> [Pattern]
ps'
                                       Pattern
p -> [Pattern
p]) [Pattern]
ps)
flatten (PConcat [Pattern]
ps) = (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\Pattern
x -> case Pattern
x of
                                           PConcat [Pattern]
ps' -> [Pattern]
ps'
                                           Pattern
p -> [Pattern
p]) [Pattern]
ps)
flatten Pattern
_ = forall a. String -> a
err String
"flatten can only be applied to POr or PConcat"
notPEmpty :: Pattern -> Bool
notPEmpty :: Pattern -> Bool
notPEmpty Pattern
PEmpty = Bool
False
notPEmpty Pattern
_      = Bool
True
canOnlyMatchNull :: Pattern -> Bool
canOnlyMatchNull :: Pattern -> Bool
canOnlyMatchNull Pattern
pIn =
  case Pattern
pIn of
    Pattern
PEmpty -> Bool
True
    PGroup Maybe Int
_ Pattern
p -> Pattern -> Bool
canOnlyMatchNull Pattern
p
    POr [Pattern]
ps -> forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Pattern -> Bool
canOnlyMatchNull [Pattern]
ps
    PConcat [Pattern]
ps -> forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Pattern -> Bool
canOnlyMatchNull [Pattern]
ps
    PQuest Pattern
p -> Pattern -> Bool
canOnlyMatchNull Pattern
p
    PPlus Pattern
p -> Pattern -> Bool
canOnlyMatchNull Pattern
p
    PStar Bool
_ Pattern
p -> Pattern -> Bool
canOnlyMatchNull Pattern
p
    PBound Int
_ (Just Int
0) Pattern
_ -> Bool
True
    PBound Int
_ Maybe Int
_ Pattern
p -> Pattern -> Bool
canOnlyMatchNull Pattern
p
    PCarat DoPa
_ -> Bool
True
    PDollar DoPa
_ -> Bool
True
    PNonCapture Pattern
p -> Pattern -> Bool
canOnlyMatchNull Pattern
p
    Pattern
_ ->Bool
False