mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-21 09:02:50 -06:00
SLF generation: make sure that there is only one final node, and that it is actually final.
This commit is contained in:
@@ -18,6 +18,7 @@ module GF.Speech.FiniteState (FA, State, NFA, DFA,
|
|||||||
addFinalState,
|
addFinalState,
|
||||||
newState, newTransition,
|
newState, newTransition,
|
||||||
mapStates, mapTransitions,
|
mapStates, mapTransitions,
|
||||||
|
oneFinalState,
|
||||||
moveLabelsToNodes, minimize,
|
moveLabelsToNodes, minimize,
|
||||||
dfa2nfa,
|
dfa2nfa,
|
||||||
prFAGraphviz) where
|
prFAGraphviz) where
|
||||||
@@ -79,6 +80,18 @@ minimize = determinize . reverseNFA . dfa2nfa . determinize . reverseNFA
|
|||||||
onGraph :: (Graph n a b -> Graph n c d) -> FA n a b -> FA n c d
|
onGraph :: (Graph n a b -> Graph n c d) -> FA n a b -> FA n c d
|
||||||
onGraph f (FA g s ss) = FA (f g) s ss
|
onGraph f (FA g s ss) = FA (f g) s ss
|
||||||
|
|
||||||
|
-- | Make the finite automaton have a single final state
|
||||||
|
-- by adding a new final state and adding an edge
|
||||||
|
-- from the old final states to the new state.
|
||||||
|
oneFinalState :: a -- ^ Label to give the new node
|
||||||
|
-> b -- ^ Label to give the new edges
|
||||||
|
-> FA n a b -- ^ The old network
|
||||||
|
-> FA n a b -- ^ The new network
|
||||||
|
oneFinalState nl el fa =
|
||||||
|
let (FA g s fs,nf) = newState nl fa
|
||||||
|
es = [ (f,nf,el) | f <- fs ]
|
||||||
|
in FA (newEdges es g) s [nf]
|
||||||
|
|
||||||
-- | Transform a standard finite automaton with labelled edges
|
-- | Transform a standard finite automaton with labelled edges
|
||||||
-- to one where the labels are on the nodes instead. This can add
|
-- to one where the labels are on the nodes instead. This can add
|
||||||
-- up to one extra node per edge.
|
-- up to one extra node per edge.
|
||||||
|
|||||||
@@ -48,12 +48,16 @@ data SLFEdge = SLFEdge { eId :: Int, eStart :: Int, eEnd :: Int }
|
|||||||
|
|
||||||
slfPrinter :: Ident -- ^ Grammar name
|
slfPrinter :: Ident -- ^ Grammar name
|
||||||
-> Options -> CGrammar -> String
|
-> Options -> CGrammar -> String
|
||||||
slfPrinter name opts cfg = prSLF (automatonToSLF $ moveLabelsToNodes $ dfa2nfa $ cfgToFA name opts cfg) ""
|
slfPrinter name opts cfg = prSLF (automatonToSLF $ mkSLFFA name opts cfg) ""
|
||||||
|
|
||||||
slfGraphvizPrinter :: Ident -- ^ Grammar name
|
slfGraphvizPrinter :: Ident -- ^ Grammar name
|
||||||
-> Options -> CGrammar -> String
|
-> Options -> CGrammar -> String
|
||||||
slfGraphvizPrinter name opts cfg =
|
slfGraphvizPrinter name opts cfg =
|
||||||
prFAGraphviz $ mapStates (fromMaybe "") $ mapTransitions (const "") $ moveLabelsToNodes $ dfa2nfa $ cfgToFA name opts cfg
|
prFAGraphviz $ mapStates (fromMaybe "") $ mapTransitions (const "") $ mkSLFFA name opts cfg
|
||||||
|
|
||||||
|
mkSLFFA :: Ident -- ^ Grammar name
|
||||||
|
-> Options -> CGrammar -> FA State (Maybe String) ()
|
||||||
|
mkSLFFA name opts cfg = oneFinalState Nothing () $ moveLabelsToNodes $ dfa2nfa $ cfgToFA name opts cfg
|
||||||
|
|
||||||
automatonToSLF :: FA State (Maybe String) () -> SLF
|
automatonToSLF :: FA State (Maybe String) () -> SLF
|
||||||
automatonToSLF fa =
|
automatonToSLF fa =
|
||||||
|
|||||||
Reference in New Issue
Block a user