----------------------------------------------------------------------------- -- | -- Module : Language.HaLex.Fa2RegExp -- Copyright : (c) João Saraiva 2001,2002,2003,2004,2005 -- License : LGPL -- -- Maintainer : jas@di.uminho.pt -- Stability : provisional -- Portability : portable -- -- From Finite Automata into Regular Expressions -- -- Code Included in the Lecture Notes on -- Language Processing (with a functional flavour). -- ----------------------------------------------------------------------------- module Language.HaLex.Fa2RegExp ( dfa2RegExp , regExpFromTo , ndfaregExpFromTo ) where import Data.List import Language.HaLex.Util import Language.HaLex.RegExp import Language.HaLex.Dfa import Language.HaLex.Ndfa -- | Compute a regular expression that defines the transitions from an -- origin to a destination in a 'Dfa'. regExpFromTo :: Eq st => (st -> sy -> st) -- ^ Transition Function -> [sy] -- ^ Vocabulary -> st -- ^ Origin State -> st -- ^ Destination State -> RegExp sy -- ^ Regular Expression regExpFromTo delta v o d = let sys = transitionsFromTo delta v o d in toRegExp sys toRegExp :: [sy] -> RegExp sy toRegExp [] = Empty toRegExp (x:xs) = toRegExp2 (x:xs) toRegExp2 [] = Epsilon toRegExp2 [x] = Literal x toRegExp2 (x:xs) = Or (Literal x) (toRegExp2 xs) -- | Compute a regular expression that defines the transitions from an -- origin to a destination in a 'Ndfa'. ndfaregExpFromTo :: Eq st => (st -> Maybe sy -> [st]) -- ^ Transition Function -> [sy] -- ^ Vocabulary -> st -- ^ Origin State -> st -- ^ Destination State -> RegExp sy -- ^ Regular Expression ndfaregExpFromTo delta v o d = let sys = ndfaTransitionsFromTo delta v o d in toRegExp' sys toRegExp' :: [Maybe sy] -> RegExp sy toRegExp' [] = Empty toRegExp' (x:xs) = toRegExp2' (x:xs) toRegExp2' [] = Epsilon toRegExp2' [x] = case x of Nothing -> Epsilon (Just x ) -> Literal x toRegExp2' (x:xs) = case x of Nothing -> Or Epsilon (toRegExp2' xs) (Just x ) -> Or (Literal x) (toRegExp2' xs) regular :: (Eq st, Num st) => (st -> sy -> st) -> [sy] -> st -> st -> st -> RegExp sy regular d v i j 0 | i==j = (regExpFromTo d v i j) `Or` Epsilon | otherwise = regExpFromTo d v i j -- force to Int !! regular d v i j k = Or (Then (Then (regular d v i k (k-1)) (Star (regular d v k k (k-1)) ) ) (regular d v k j (k-1))) (regular d v i j (k-1)) -- | Compute a regular expression from a 'Dfa'. dfa2RegExp :: Eq sy => Dfa Int sy -- ^ Deterministic Automaton -> RegExp sy -- ^ Equivalent Regular Expression dfa2RegExp dfa@(Dfa v q s z delta) = limit simplifyRegExp (applyD delta v s z (sizeDfa dfa)) applyD :: (Eq st, Num st) => (st -> sy -> st) -> [sy] -> st -> [st] -> st -> RegExp sy applyD d v _ [] _ = Epsilon applyD d v i (z:zs) k = (regular d v i z k) `Or` (applyD d v i zs k)