module Algebra.Parser.Regex (regex,runRegex) where
import Algebra.Parser
runRegex :: String -> String -> [([(String,String)],String)]
runRegex re = join (pure re >*> regex)^..parser <&> map snd
regex :: Parser String (Parser String ([(String,String)],String))
regex = _union
where _union = (adjacent`sepBy`single '|') <&> sum
adjacent = many postfixed <&> map concat.sequence
atom = dot <+> range <+> otherChar <+> between (single '(') (single ')') _union
postfixed = comp<$>atom<*>many postfun
where postfun = satisfy (`elem`"*+?") <&> \c -> case c of
'*' -> map sum.many
'+' -> map sum.many1
'?' -> (+ pure ([],""))
_ -> undefined
comp a fs = compose fs a
dot = shallow token <$ single '.'
otherChar = shallow.char<$>noneOf "()[*?|+"
range = between (single '[') (single ']') ranges
where ranges = sum <$> many subRange
subRange = mkRange<$>subChar<*single '-' <*>subChar
<+> shallow.char<$>subChar
mkRange a b = shallow $ satisfy (\c -> c>=a && c<=b)
subChar = noneOf "]"
shallow = (([],).pure<$>)
char c = c<$single c