diff --git a/src/Rextra/Dfa.hs b/src/Rextra/Dfa.hs index b231f6d..6196d22 100644 --- a/src/Rextra/Dfa.hs +++ b/src/Rextra/Dfa.hs @@ -5,9 +5,11 @@ module Rextra.Dfa , stateMap , entryState , transition + , execute , State(..) ) where +import Data.List import qualified Data.Map.Strict as Map import qualified Data.Set as Set @@ -15,12 +17,12 @@ data State s t = State { transitions :: Map.Map t s , defaultTransition :: s , accepting :: Bool - } + } deriving (Show) data Dfa s t = Dfa { stateMap :: Map.Map s (State s t) , entryState :: s - } + } deriving (Show) {- - Constructing a DFA @@ -55,3 +57,8 @@ transition dfa s t = in case transitions state Map.!? t of (Just nextState) -> nextState Nothing -> defaultTransition state + +execute :: (Ord s, Ord t) => Dfa s t -> [t] -> Bool +execute dfa tokens = + let finalState = foldl' (transition dfa) (entryState dfa) tokens + in accepting $ getState dfa finalState diff --git a/src/Rextra/Nfa.hs b/src/Rextra/Nfa.hs index faea5c6..4a2638e 100644 --- a/src/Rextra/Nfa.hs +++ b/src/Rextra/Nfa.hs @@ -10,12 +10,14 @@ module Rextra.Nfa ( , entryState , exitStates , transition + , execute -- ** Transitions - , TransitionCondition + , TransitionCondition(..) , specialStates , accepts ) where +import Data.List import qualified Data.Map.Strict as Map import qualified Data.Set as Set @@ -28,6 +30,7 @@ import qualified Data.Set as Set data TransitionCondition t = Only (Set.Set t) | AllExcept (Set.Set t) + deriving (Show) -- | The states which are treated differently from the default by the -- 'TransitionCondition'. @@ -52,7 +55,7 @@ data Nfa s t = Nfa { stateMap :: Map.Map s (State s t) , entryState :: s , exitStates :: Set.Set s - } + } deriving (Show) {- - Constructing a NFA @@ -108,3 +111,9 @@ nextStates state t = Set.fromList . map snd . filter (\(cond, _) -> cond `accept -- is used. transition :: (Ord s, Ord t) => Nfa s t -> Set.Set s -> t -> Set.Set s transition nfa ss t = foldMap (\s -> nextStates (getState nfa s) t) ss + +execute :: (Ord s, Ord t) => Nfa s t -> [t] -> Bool +execute nfa tokens = + let entryStates = Set.singleton $ entryState nfa + finalStates = foldl' (transition nfa) entryStates tokens + in not $ Set.disjoint finalStates (exitStates nfa)