    \begin{code}
    {-# LANGUAGE NoImplicitPrelude          #-}

    module Text.RE.ZeInternals.Tools.Lex
      ( alex
      , alex'
      ) where

    import           Prelude.Compat
    import           Text.RE.Replace
    import           Text.RE.ZeInternals.Types.IsRegex
    \end{code}

    \begin{code}
    -- | a simple regex-based scanner interpreter for prototyping
    -- scanners
    alex :: IsRegex re s => [(re,Match s->Maybe t)] -> t -> s -> [t]
    alex :: forall re s t.
    IsRegex re s =>
    [(re, Match s -> Maybe t)] -> t -> s -> [t]
    alex = (re -> s -> Match s) -> [(re, Match s -> Maybe t)] -> t -> s -> [t]
    forall s re t.
    Replace s =>
    (re -> s -> Match s) -> [(re, Match s -> Maybe t)] -> t -> s -> [t]
    alex' re -> s -> Match s
    forall re s. IsRegex re s => re -> s -> Match s
    matchOnce

    -- | a higher order version of 'alex' parameterised over the @matchOnce@
    -- function
    alex' :: Replace s
          => (re->s->Match s)
          -> [(re,Match s->Maybe t)]
          -> t
          -> s
          -> [t]
    alex' :: forall s re t.
    Replace s =>
    (re -> s -> Match s) -> [(re, Match s -> Maybe t)] -> t -> s -> [t]
    alex' re -> s -> Match s
    mo [(re, Match s -> Maybe t)]
    al t
    t_err = s -> [t]
    loop
      where
        loop :: s -> [t]
    loop s
    s = case s -> Int
    forall a. Replace a => a -> Int
    lengthR s
    s Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0 of
          Bool
    True  -> []
          Bool
    False -> [(re, Match s -> Maybe t)] -> s -> [t]
    choose [(re, Match s -> Maybe t)]
    al s
    s

        choose :: [(re, Match s -> Maybe t)] -> s -> [t]
    choose []           s
    _ = [t
    t_err]
        choose ((re
    re,Match s -> Maybe t
    f):[(re, Match s -> Maybe t)]
    al') s
    s = case Maybe (s, t)
    mb_p of
            Just (s
    s',t
    t) -> t
    t t -> [t] -> [t]
    forall a. a -> [a] -> [a]
    : s -> [t]
    loop s
    s'
            Maybe (s, t)
    _           -> [(re, Match s -> Maybe t)] -> s -> [t]
    choose [(re, Match s -> Maybe t)]
    al' s
    s
          where
            mb_p :: Maybe (s, t)
    mb_p = do
              cap <- Match s -> Maybe (Capture s)
    forall a. Match a -> Maybe (Capture a)
    matchCapture Match s
    mtch
              case captureOffset cap == 0 of
                Bool
    True  -> (,) (Capture s -> s
    forall a. Extract a => Capture a -> a
    captureSuffix Capture s
    cap) (t -> (s, t)) -> Maybe t -> Maybe (s, t)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Match s -> Maybe t
    f Match s
    mtch
                Bool
    False -> Maybe (s, t)
    forall a. Maybe a
    Nothing

            mtch :: Match s
    mtch = re -> s -> Match s
    mo re
    re s
    s
    \end{code}