{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
module Kleene.Classes where
import Prelude ()
import Prelude.Compat
import Data.Char (ord)
import Data.Foldable (toList)
import Data.Function.Step.Discrete.Closed (SF)
import Data.Map (Map)
import Data.Maybe (mapMaybe)
import Data.RangeSet.Map (RSet)
import Data.Word (Word8)
import qualified Data.ByteString as BS
import qualified Data.RangeSet.Map as RSet
import Kleene.Internal.Sets (dotRSet)
class Kleene k where
empty :: k
eps :: k
appends :: [k] -> k
unions :: [k] -> k
star :: k -> k
class Kleene k => CharKleene c k | k -> c where
char :: c -> k
string :: [c] -> k
string = appends . map char
oneof :: (CharKleene c k, Foldable f) => f c -> k
oneof = unions . map char . toList
class CharKleene c k => FiniteKleene c k | k -> c where
everything :: k
everything = star anyChar
charRange :: c -> c -> k
fromRSet :: RSet c -> k
dot :: c ~ Char => k
dot = fromRSet dotRSet
anyChar :: k
notChar :: c -> k
default notChar :: (Ord c, Enum c, Bounded c) => c -> k
notChar = fromRSet . RSet.complement . RSet.singleton
class Derivate c k | k -> c where
nullable :: k -> Bool
derivate :: c -> k -> k
class Match c k | k -> c where
match :: k -> [c] -> Bool
match8 :: c ~ Word8 => k -> BS.ByteString -> Bool
match8 k = match k . BS.unpack
class Match c k => Equivalent c k | k -> c where
equivalent :: k -> k -> Bool
class Derivate c k => TransitionMap c k | k -> c where
transitionMap :: k -> Map k (SF c k)
class Complement c k | k -> c where
complement :: k -> k
class ToLatin1 k where
toLatin1 :: k Char -> k Word8
instance ToLatin1 RSet where
toLatin1 = RSet.fromRangeList . mapMaybe f . RSet.toRangeList where
f :: (Char, Char) -> Maybe (Word8, Word8)
f (a, b)
| ord a >= 256 = Nothing
| otherwise = Just (fromIntegral (ord a), fromIntegral (min 255 (ord b)))