module Language.Lexer.Tlex.Pipeline.Pattern2Nfa ( pattern2Nfa, ) where import Language.Lexer.Tlex.Prelude import qualified Language.Lexer.Tlex.Data.EnumSet as EnumSet import qualified Language.Lexer.Tlex.Data.SymEnumSet as SymEnumSet import qualified Language.Lexer.Tlex.Machine.NFA as NFA import qualified Language.Lexer.Tlex.Machine.Pattern as Pattern import qualified Language.Lexer.Tlex.Machine.State as MState pattern2Nfa :: Enum e => MState.StateNum -> MState.StateNum -> Pattern.Pattern e -> NFA.NFABuilder m () pattern2Nfa :: StateNum -> StateNum -> Pattern e -> NFABuilder m () pattern2Nfa = StateNum -> StateNum -> Pattern e -> NFABuilder m () forall e m. Enum e => StateNum -> StateNum -> Pattern e -> NFABuilder m () go where go :: StateNum -> StateNum -> Pattern e -> NFABuilder m () go StateNum b StateNum e = \case Pattern e Pattern.Epsilon -> StateNum -> StateNum -> NFABuilder m () forall m. StateNum -> StateNum -> NFABuilder m () NFA.epsilonTrans StateNum b StateNum e Pattern.Range SymEnumSet e s -> StateNum -> NFAStateTrans -> NFABuilder m () forall m. StateNum -> NFAStateTrans -> NFABuilder m () NFA.condTrans StateNum b do let (Bool isStraight, EnumSet e es) = SymEnumSet e -> (Bool, EnumSet e) forall a. Enum a => SymEnumSet a -> (Bool, EnumSet a) SymEnumSet.toEnumSet SymEnumSet e s NFAStateTrans :: Bool -> IntSet -> StateNum -> NFAStateTrans NFA.NFAStateTrans { $sel:nstTransIsStraight:NFAStateTrans :: Bool NFA.nstTransIsStraight = Bool isStraight , $sel:nstTransRange:NFAStateTrans :: IntSet NFA.nstTransRange = EnumSet e -> IntSet forall a. Enum a => EnumSet a -> IntSet EnumSet.toIntSet EnumSet e es , $sel:nstTransNextState:NFAStateTrans :: StateNum NFA.nstTransNextState = StateNum e } Pattern e p1 Pattern.:^: Pattern e p2 -> do StateNum s <- NFABuilder m StateNum forall m. NFABuilder m StateNum NFA.newStateNum StateNum -> StateNum -> Pattern e -> NFABuilder m () forall e m. Enum e => StateNum -> StateNum -> Pattern e -> NFABuilder m () pattern2Nfa StateNum b StateNum s Pattern e p1 StateNum -> StateNum -> Pattern e -> NFABuilder m () forall e m. Enum e => StateNum -> StateNum -> Pattern e -> NFABuilder m () pattern2Nfa StateNum s StateNum e Pattern e p2 Pattern e p1 Pattern.:|: Pattern e p2 -> do StateNum -> StateNum -> Pattern e -> NFABuilder m () forall e m. Enum e => StateNum -> StateNum -> Pattern e -> NFABuilder m () pattern2Nfa StateNum b StateNum e Pattern e p1 StateNum -> StateNum -> Pattern e -> NFABuilder m () forall e m. Enum e => StateNum -> StateNum -> Pattern e -> NFABuilder m () pattern2Nfa StateNum b StateNum e Pattern e p2 Pattern.Many Pattern e p -> do StateNum s <- NFABuilder m StateNum forall m. NFABuilder m StateNum NFA.newStateNum StateNum -> StateNum -> NFABuilder m () forall m. StateNum -> StateNum -> NFABuilder m () NFA.epsilonTrans StateNum b StateNum s StateNum -> StateNum -> Pattern e -> NFABuilder m () forall e m. Enum e => StateNum -> StateNum -> Pattern e -> NFABuilder m () pattern2Nfa StateNum s StateNum s Pattern e p StateNum -> StateNum -> NFABuilder m () forall m. StateNum -> StateNum -> NFABuilder m () NFA.epsilonTrans StateNum s StateNum e