module DFA(scanner2dfa) where
import AbsSyn
import qualified Map
import qualified Data.IntMap as IntMap
import NFA
import Sort ( msort, nub' )
import CharSet
import Data.Array ( (!) )
import Data.Maybe ( fromJust )
scanner2dfa:: Encoding -> Scanner -> [StartCode] -> DFA SNum Code
scanner2dfa :: Encoding -> Scanner -> [StartCode] -> DFA StartCode Code
scanner2dfa Encoding
enc Scanner
scanner [StartCode]
scs = [StartCode] -> NFA -> DFA StartCode Code
nfa2dfa [StartCode]
scs (Encoding -> Scanner -> [StartCode] -> NFA
scanner2nfa Encoding
enc Scanner
scanner [StartCode]
scs)
nfa2dfa:: [StartCode] -> NFA -> DFA SNum Code
nfa2dfa :: [StartCode] -> NFA -> DFA StartCode Code
nfa2dfa [StartCode]
scs NFA
nfa = NFA -> DFA [StartCode] Code -> DFA StartCode Code
forall a. NFA -> DFA [StartCode] a -> DFA StartCode a
mk_int_dfa NFA
nfa (NFA
-> DFA [StartCode] Code -> [[StartCode]] -> DFA [StartCode] Code
nfa2pdfa NFA
nfa DFA [StartCode] Code
forall a. DFA [StartCode] a
pdfa (DFA [StartCode] Any -> [[StartCode]]
forall s a. DFA s a -> [s]
dfa_start_states DFA [StartCode] Any
forall a. DFA [StartCode] a
pdfa))
where
pdfa :: DFA [StartCode] a
pdfa = StartCode -> NFA -> DFA [StartCode] a
forall a. StartCode -> NFA -> DFA [StartCode] a
new_pdfa StartCode
n_starts NFA
nfa
n_starts :: StartCode
n_starts = [StartCode] -> StartCode
forall (t :: * -> *) a. Foldable t => t a -> StartCode
length [StartCode]
scs
nfa2pdfa:: NFA -> DFA StateSet Code -> [StateSet] -> DFA StateSet Code
nfa2pdfa :: NFA
-> DFA [StartCode] Code -> [[StartCode]] -> DFA [StartCode] Code
nfa2pdfa NFA
_ DFA [StartCode] Code
pdfa [] = DFA [StartCode] Code
pdfa
nfa2pdfa NFA
nfa DFA [StartCode] Code
pdfa ([StartCode]
ss:[[StartCode]]
umkd)
| [StartCode]
ss [StartCode] -> DFA [StartCode] Code -> Bool
forall a. [StartCode] -> DFA [StartCode] a -> Bool
`in_pdfa` DFA [StartCode] Code
pdfa = NFA
-> DFA [StartCode] Code -> [[StartCode]] -> DFA [StartCode] Code
nfa2pdfa NFA
nfa DFA [StartCode] Code
pdfa [[StartCode]]
umkd
| Bool
otherwise = NFA
-> DFA [StartCode] Code -> [[StartCode]] -> DFA [StartCode] Code
nfa2pdfa NFA
nfa DFA [StartCode] Code
pdfa' [[StartCode]]
umkd'
where
pdfa' :: DFA [StartCode] Code
pdfa' = [StartCode]
-> State [StartCode] Code
-> DFA [StartCode] Code
-> DFA [StartCode] Code
forall a.
[StartCode]
-> State [StartCode] a -> DFA [StartCode] a -> DFA [StartCode] a
add_pdfa [StartCode]
ss ([Accept Code] -> IntMap [StartCode] -> State [StartCode] Code
forall s a. [Accept a] -> IntMap s -> State s a
State [Accept Code]
accs ([(StartCode, [StartCode])] -> IntMap [StartCode]
forall a. [(StartCode, a)] -> IntMap a
IntMap.fromList [(StartCode, [StartCode])]
ss_outs)) DFA [StartCode] Code
pdfa
umkd' :: [[StartCode]]
umkd' = [[StartCode]]
rctx_sss [[StartCode]] -> [[StartCode]] -> [[StartCode]]
forall a. [a] -> [a] -> [a]
++ ((StartCode, [StartCode]) -> [StartCode])
-> [(StartCode, [StartCode])] -> [[StartCode]]
forall a b. (a -> b) -> [a] -> [b]
map (StartCode, [StartCode]) -> [StartCode]
forall a b. (a, b) -> b
snd [(StartCode, [StartCode])]
ss_outs [[StartCode]] -> [[StartCode]] -> [[StartCode]]
forall a. [a] -> [a] -> [a]
++ [[StartCode]]
umkd
ss_outs :: [(Int, StateSet)]
ss_outs :: [(StartCode, [StartCode])]
ss_outs = [ (Byte -> StartCode
forall a b. (Integral a, Num b) => a -> b
fromIntegral Byte
ch, NFA -> [StartCode] -> [StartCode]
mk_ss NFA
nfa [StartCode]
ss')
| Byte
ch <- ByteSet -> [Byte]
byteSetElems (ByteSet -> [Byte]) -> ByteSet -> [Byte]
forall a b. (a -> b) -> a -> b
$ [ByteSet] -> ByteSet
forall a. DiscreteOrdered a => [RSet a] -> RSet a
setUnions [ByteSet
p | (ByteSet
p,StartCode
_) <- [(ByteSet, StartCode)]
outs],
let ss' :: [StartCode]
ss' = [ StartCode
s' | (ByteSet
p,StartCode
s') <- [(ByteSet, StartCode)]
outs, ByteSet -> Byte -> Bool
byteSetElem ByteSet
p Byte
ch ],
Bool -> Bool
not ([StartCode] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [StartCode]
ss')
]
rctx_sss :: [[StartCode]]
rctx_sss = [ NFA -> [StartCode] -> [StartCode]
mk_ss NFA
nfa [StartCode
s]
| Acc StartCode
_ Maybe Code
_ Maybe CharSet
_ (RightContextRExp StartCode
s) <- [Accept Code]
accs ]
outs :: [(ByteSet,SNum)]
outs :: [(ByteSet, StartCode)]
outs = [ (ByteSet, StartCode)
out | StartCode
s <- [StartCode]
ss, (ByteSet, StartCode)
out <- NState -> [(ByteSet, StartCode)]
nst_outs (NFA
nfaNFA -> StartCode -> NState
forall i e. Ix i => Array i e -> i -> e
!StartCode
s) ]
accs :: [Accept Code]
accs = [Accept Code] -> [Accept Code]
forall a. [Accept a] -> [Accept a]
sort_accs [Accept Code
acc| StartCode
s<-[StartCode]
ss, Accept Code
acc<-NState -> [Accept Code]
nst_accs (NFA
nfaNFA -> StartCode -> NState
forall i e. Ix i => Array i e -> i -> e
!StartCode
s)]
sort_accs:: [Accept a] -> [Accept a]
sort_accs :: [Accept a] -> [Accept a]
sort_accs [Accept a]
accs = (Accept a -> [Accept a] -> [Accept a])
-> [Accept a] -> [Accept a] -> [Accept a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Accept a -> [Accept a] -> [Accept a]
forall a. Accept a -> [Accept a] -> [Accept a]
chk [] ((Accept a -> Accept a -> Bool) -> [Accept a] -> [Accept a]
forall a. (a -> a -> Bool) -> [a] -> [a]
msort Accept a -> Accept a -> Bool
forall a a. Accept a -> Accept a -> Bool
le [Accept a]
accs)
where
chk :: Accept a -> [Accept a] -> [Accept a]
chk acc :: Accept a
acc@(Acc StartCode
_ Maybe a
_ Maybe CharSet
Nothing RightContext StartCode
NoRightContext) [Accept a]
_ = [Accept a
acc]
chk Accept a
acc [Accept a]
rst = Accept a
accAccept a -> [Accept a] -> [Accept a]
forall a. a -> [a] -> [a]
:[Accept a]
rst
le :: Accept a -> Accept a -> Bool
le (Acc{accPrio :: forall a. Accept a -> StartCode
accPrio = StartCode
n}) (Acc{accPrio :: forall a. Accept a -> StartCode
accPrio=StartCode
n'}) = StartCode
nStartCode -> StartCode -> Bool
forall a. Ord a => a -> a -> Bool
<=StartCode
n'
type StateSet = [SNum]
new_pdfa:: Int -> NFA -> DFA StateSet a
new_pdfa :: StartCode -> NFA -> DFA [StartCode] a
new_pdfa StartCode
starts NFA
nfa
= DFA :: forall s a. [s] -> Map s (State s a) -> DFA s a
DFA { dfa_start_states :: [[StartCode]]
dfa_start_states = [[StartCode]]
start_ss,
dfa_states :: Map [StartCode] (State [StartCode] a)
dfa_states = Map [StartCode] (State [StartCode] a)
forall k a. Map k a
Map.empty
}
where
start_ss :: [[StartCode]]
start_ss = [ (StartCode -> StartCode -> Bool) -> [StartCode] -> [StartCode]
forall a. (a -> a -> Bool) -> [a] -> [a]
msort StartCode -> StartCode -> Bool
forall a. Ord a => a -> a -> Bool
(<=) (NState -> [StartCode]
nst_cl(NFA
nfaNFA -> StartCode -> NState
forall i e. Ix i => Array i e -> i -> e
!StartCode
n)) | StartCode
n <- [StartCode
0..(StartCode
startsStartCode -> StartCode -> StartCode
forall a. Num a => a -> a -> a
-StartCode
1)]]
mk_ss:: NFA -> [SNum] -> StateSet
mk_ss :: NFA -> [StartCode] -> [StartCode]
mk_ss NFA
nfa [StartCode]
l = (StartCode -> StartCode -> Bool) -> [StartCode] -> [StartCode]
forall a. (a -> a -> Bool) -> [a] -> [a]
nub' StartCode -> StartCode -> Bool
forall a. Ord a => a -> a -> Bool
(<=) [StartCode
s'| StartCode
s<-[StartCode]
l, StartCode
s'<-NState -> [StartCode]
nst_cl(NFA
nfaNFA -> StartCode -> NState
forall i e. Ix i => Array i e -> i -> e
!StartCode
s)]
add_pdfa:: StateSet -> State StateSet a -> DFA StateSet a -> DFA StateSet a
add_pdfa :: [StartCode]
-> State [StartCode] a -> DFA [StartCode] a -> DFA [StartCode] a
add_pdfa [StartCode]
ss State [StartCode] a
pst (DFA [[StartCode]]
st Map [StartCode] (State [StartCode] a)
mp) = [[StartCode]]
-> Map [StartCode] (State [StartCode] a) -> DFA [StartCode] a
forall s a. [s] -> Map s (State s a) -> DFA s a
DFA [[StartCode]]
st ([StartCode]
-> State [StartCode] a
-> Map [StartCode] (State [StartCode] a)
-> Map [StartCode] (State [StartCode] a)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert [StartCode]
ss State [StartCode] a
pst Map [StartCode] (State [StartCode] a)
mp)
in_pdfa:: StateSet -> DFA StateSet a -> Bool
in_pdfa :: [StartCode] -> DFA [StartCode] a -> Bool
in_pdfa [StartCode]
ss (DFA [[StartCode]]
_ Map [StartCode] (State [StartCode] a)
mp) = [StartCode]
ss [StartCode] -> Map [StartCode] (State [StartCode] a) -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map [StartCode] (State [StartCode] a)
mp
mk_int_dfa:: NFA -> DFA StateSet a -> DFA SNum a
mk_int_dfa :: NFA -> DFA [StartCode] a -> DFA StartCode a
mk_int_dfa NFA
nfa (DFA [[StartCode]]
start_states Map [StartCode] (State [StartCode] a)
mp)
= [StartCode] -> Map StartCode (State StartCode a) -> DFA StartCode a
forall s a. [s] -> Map s (State s a) -> DFA s a
DFA [StartCode
0 .. [[StartCode]] -> StartCode
forall (t :: * -> *) a. Foldable t => t a -> StartCode
length [[StartCode]]
start_statesStartCode -> StartCode -> StartCode
forall a. Num a => a -> a -> a
-StartCode
1]
([(StartCode, State StartCode a)]
-> Map StartCode (State StartCode a)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [ ([StartCode] -> StartCode
lookup' [StartCode]
st, State [StartCode] a -> State StartCode a
forall a. State [StartCode] a -> State StartCode a
cnv State [StartCode] a
pds) | ([StartCode]
st, State [StartCode] a
pds) <- Map [StartCode] (State [StartCode] a)
-> [([StartCode], State [StartCode] a)]
forall k a. Map k a -> [(k, a)]
Map.toAscList Map [StartCode] (State [StartCode] a)
mp ])
where
mp' :: Map [StartCode] StartCode
mp' = [([StartCode], StartCode)] -> Map [StartCode] StartCode
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([[StartCode]] -> [StartCode] -> [([StartCode], StartCode)]
forall a b. [a] -> [b] -> [(a, b)]
zip ([[StartCode]]
start_states [[StartCode]] -> [[StartCode]] -> [[StartCode]]
forall a. [a] -> [a] -> [a]
++
((([StartCode], State [StartCode] a) -> [StartCode])
-> [([StartCode], State [StartCode] a)] -> [[StartCode]]
forall a b. (a -> b) -> [a] -> [b]
map ([StartCode], State [StartCode] a) -> [StartCode]
forall a b. (a, b) -> a
fst ([([StartCode], State [StartCode] a)] -> [[StartCode]])
-> (Map [StartCode] (State [StartCode] a)
-> [([StartCode], State [StartCode] a)])
-> Map [StartCode] (State [StartCode] a)
-> [[StartCode]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map [StartCode] (State [StartCode] a)
-> [([StartCode], State [StartCode] a)]
forall k a. Map k a -> [(k, a)]
Map.toAscList) (([StartCode]
-> Map [StartCode] (State [StartCode] a)
-> Map [StartCode] (State [StartCode] a))
-> Map [StartCode] (State [StartCode] a)
-> [[StartCode]]
-> Map [StartCode] (State [StartCode] a)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr [StartCode]
-> Map [StartCode] (State [StartCode] a)
-> Map [StartCode] (State [StartCode] a)
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete Map [StartCode] (State [StartCode] a)
mp [[StartCode]]
start_states)) [StartCode
0..])
lookup' :: [StartCode] -> StartCode
lookup' = Maybe StartCode -> StartCode
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe StartCode -> StartCode)
-> ([StartCode] -> Maybe StartCode) -> [StartCode] -> StartCode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([StartCode] -> Map [StartCode] StartCode -> Maybe StartCode)
-> Map [StartCode] StartCode -> [StartCode] -> Maybe StartCode
forall a b c. (a -> b -> c) -> b -> a -> c
flip [StartCode] -> Map [StartCode] StartCode -> Maybe StartCode
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Map [StartCode] StartCode
mp'
cnv :: State StateSet a -> State SNum a
cnv :: State [StartCode] a -> State StartCode a
cnv (State [Accept a]
accs IntMap [StartCode]
as) = [Accept a] -> IntMap StartCode -> State StartCode a
forall s a. [Accept a] -> IntMap s -> State s a
State [Accept a]
accs' IntMap StartCode
as'
where
as' :: IntMap StartCode
as' = (StartCode -> [StartCode] -> StartCode)
-> IntMap [StartCode] -> IntMap StartCode
forall a b. (StartCode -> a -> b) -> IntMap a -> IntMap b
IntMap.mapWithKey (\StartCode
_ch [StartCode]
s -> [StartCode] -> StartCode
lookup' [StartCode]
s) IntMap [StartCode]
as
accs' :: [Accept a]
accs' = (Accept a -> Accept a) -> [Accept a] -> [Accept a]
forall a b. (a -> b) -> [a] -> [b]
map Accept a -> Accept a
forall a. Accept a -> Accept a
cnv_acc [Accept a]
accs
cnv_acc :: Accept a -> Accept a
cnv_acc (Acc StartCode
p Maybe a
a Maybe CharSet
lctx RightContext StartCode
rctx) = StartCode
-> Maybe a -> Maybe CharSet -> RightContext StartCode -> Accept a
forall a.
StartCode
-> Maybe a -> Maybe CharSet -> RightContext StartCode -> Accept a
Acc StartCode
p Maybe a
a Maybe CharSet
lctx RightContext StartCode
rctx'
where rctx' :: RightContext StartCode
rctx' =
case RightContext StartCode
rctx of
RightContextRExp StartCode
s ->
StartCode -> RightContext StartCode
forall r. r -> RightContext r
RightContextRExp ([StartCode] -> StartCode
lookup' (NFA -> [StartCode] -> [StartCode]
mk_ss NFA
nfa [StartCode
s]))
RightContext StartCode
other -> RightContext StartCode
other