Execute DFA and NFA on a list of tokens
This commit is contained in:
parent
edd7a44d02
commit
56bcf2c987
2 changed files with 20 additions and 4 deletions
|
|
@ -5,9 +5,11 @@ module Rextra.Dfa
|
||||||
, stateMap
|
, stateMap
|
||||||
, entryState
|
, entryState
|
||||||
, transition
|
, transition
|
||||||
|
, execute
|
||||||
, State(..)
|
, State(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Data.List
|
||||||
import qualified Data.Map.Strict as Map
|
import qualified Data.Map.Strict as Map
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
|
||||||
|
|
@ -15,12 +17,12 @@ data State s t = State
|
||||||
{ transitions :: Map.Map t s
|
{ transitions :: Map.Map t s
|
||||||
, defaultTransition :: s
|
, defaultTransition :: s
|
||||||
, accepting :: Bool
|
, accepting :: Bool
|
||||||
}
|
} deriving (Show)
|
||||||
|
|
||||||
data Dfa s t = Dfa
|
data Dfa s t = Dfa
|
||||||
{ stateMap :: Map.Map s (State s t)
|
{ stateMap :: Map.Map s (State s t)
|
||||||
, entryState :: s
|
, entryState :: s
|
||||||
}
|
} deriving (Show)
|
||||||
|
|
||||||
{-
|
{-
|
||||||
- Constructing a DFA
|
- Constructing a DFA
|
||||||
|
|
@ -55,3 +57,8 @@ transition dfa s t =
|
||||||
in case transitions state Map.!? t of
|
in case transitions state Map.!? t of
|
||||||
(Just nextState) -> nextState
|
(Just nextState) -> nextState
|
||||||
Nothing -> defaultTransition state
|
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
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,14 @@ module Rextra.Nfa (
|
||||||
, entryState
|
, entryState
|
||||||
, exitStates
|
, exitStates
|
||||||
, transition
|
, transition
|
||||||
|
, execute
|
||||||
-- ** Transitions
|
-- ** Transitions
|
||||||
, TransitionCondition
|
, TransitionCondition(..)
|
||||||
, specialStates
|
, specialStates
|
||||||
, accepts
|
, accepts
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Data.List
|
||||||
import qualified Data.Map.Strict as Map
|
import qualified Data.Map.Strict as Map
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
|
||||||
|
|
@ -28,6 +30,7 @@ import qualified Data.Set as Set
|
||||||
data TransitionCondition t
|
data TransitionCondition t
|
||||||
= Only (Set.Set t)
|
= Only (Set.Set t)
|
||||||
| AllExcept (Set.Set t)
|
| AllExcept (Set.Set t)
|
||||||
|
deriving (Show)
|
||||||
|
|
||||||
-- | The states which are treated differently from the default by the
|
-- | The states which are treated differently from the default by the
|
||||||
-- 'TransitionCondition'.
|
-- 'TransitionCondition'.
|
||||||
|
|
@ -52,7 +55,7 @@ data Nfa s t = Nfa
|
||||||
{ stateMap :: Map.Map s (State s t)
|
{ stateMap :: Map.Map s (State s t)
|
||||||
, entryState :: s
|
, entryState :: s
|
||||||
, exitStates :: Set.Set s
|
, exitStates :: Set.Set s
|
||||||
}
|
} deriving (Show)
|
||||||
|
|
||||||
{-
|
{-
|
||||||
- Constructing a NFA
|
- Constructing a NFA
|
||||||
|
|
@ -108,3 +111,9 @@ nextStates state t = Set.fromList . map snd . filter (\(cond, _) -> cond `accept
|
||||||
-- is used.
|
-- is used.
|
||||||
transition :: (Ord s, Ord t) => Nfa s t -> Set.Set s -> t -> Set.Set s
|
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
|
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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue