packages feed

speculate-0.3.5: eg/Regex.hs

module Regex
  ( RE (..)
  , (=~), (===)
  , match
  , Symbol (..)
  , stringToSymbols
  , compile
  )
where

import qualified Text.Regex.TDFA as O
-- import qualified Text.Regex.Posix as O -- just as slow
-- import qualified Text.Regex.PCRE as O -- fails!

-- | Abstract representation of a Regular Expression.  This is a simple
--   abstraction supporting only the operations in a Kleene's algebra.
data RE a = Empty            -- Empty/"":      one
          | None             -- Unmatchable:   zero
          | Lit a            -- Literals
          | Star (RE a)      -- Star/Asterisk: *
          | (RE a) :+ (RE a) -- Choice/Plus:   +
          | (RE a) :. (RE a) -- Append/Concat: .
  deriving Show

-- | Compile an abstract regular expression to be used by Text.Regex
compile :: (a -> Char) -> RE a -> String
compile f r = "^" ++ c r ++ "$"
  where
  c Empty    = "()"
  c None     = "$u^" -- unmatchable
  c (Star r) = "(" ++ c r ++ ")*"
  c (r :+ s) = "(" ++ c r ++ "|" ++ c s ++ ")"
  c (r :. s) = c r ++ c s
  c (Lit c)  = [f c]

match :: (a -> Char) -> [a] -> RE a -> Bool
match f xs r = map f xs O.=~ compile f r


-- Now with symbols
newtype Symbol = Symbol Char deriving (Eq, Ord, Show)

(=~) :: [Symbol] -> RE Symbol -> Bool
(=~) = match symbolToChar
  where
  symbolToChar (Symbol c) = c

(===) :: RE Symbol -> RE Symbol -> [Symbol] -> Bool
e1 === e2 = \s -> s =~ e1 == s =~ e1

stringToSymbols :: String -> [Symbol]
stringToSymbols = map Symbol