make 'dstates' in 'Nfa.ToDfa.convert' function a vector, rather than a list, and make sure we append to the end each time we add
This commit is contained in:
BIN
fcore/search-list/nfa
Executable file
BIN
fcore/search-list/nfa
Executable file
Binary file not shown.
@@ -397,39 +397,41 @@ struct
|
|||||||
| WILDCARD _ => acc
|
| WILDCARD _ => acc
|
||||||
| GROUP r => getConcatAndLoopsToPos (r, pos, acc, char)
|
| GROUP r => getConcatAndLoopsToPos (r, pos, acc, char)
|
||||||
|
|
||||||
fun statesInList (lst, newStates) =
|
fun ifStatesInVec (pos, dstates, newStates) =
|
||||||
case lst of
|
if pos = Vector.length dstates then
|
||||||
{marked = _, transitions} :: tl =>
|
false
|
||||||
newStates = transitions orelse statesInList (tl, newStates)
|
else
|
||||||
| [] => false
|
let
|
||||||
|
val {transitions, marked = _} = Vector.sub (dstates, pos)
|
||||||
|
in
|
||||||
|
transitions = newStates
|
||||||
|
orelse ifStatesInVec (pos + 1, dstates, newStates)
|
||||||
|
end
|
||||||
|
|
||||||
fun getUnmarkedTransitionsIfExists lst =
|
fun getUnmarkedTransitionsIfExists (pos, dstates) =
|
||||||
case lst of
|
if pos = Vector.length dstates then
|
||||||
{marked, transitions} :: tl =>
|
NONE
|
||||||
if marked then getUnmarkedTransitionsIfExists tl else SOME transitions
|
else
|
||||||
| [] => NONE
|
let
|
||||||
|
val record = Vector.sub (dstates, pos)
|
||||||
fun addListToAcc (lst, acc) =
|
in
|
||||||
case lst of
|
if #marked record then
|
||||||
hd :: tl => addListToAcc (tl, hd :: acc)
|
getUnmarkedTransitionsIfExists (pos + 1, dstates)
|
||||||
| [] => acc
|
|
||||||
|
|
||||||
fun markTransition (lst, transitionToMark, acc) =
|
|
||||||
case lst of
|
|
||||||
(hd as {marked, transitions}) :: tl =>
|
|
||||||
if transitions = transitionToMark then
|
|
||||||
let val acc = {marked = true, transitions = transitionToMark} :: acc
|
|
||||||
in addListToAcc (tl, acc)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
markTransition (tl, transitionToMark, hd :: acc)
|
SOME (pos, #transitions record)
|
||||||
| [] => {marked = true, transitions = transitionToMark} :: acc
|
end
|
||||||
|
|
||||||
fun convertLoop (regex, dstates) =
|
fun convertLoop (regex, dstates) =
|
||||||
case getUnmarkedTransitionsIfExists dstates of
|
case getUnmarkedTransitionsIfExists (0, dstates) of
|
||||||
SOME unamarkedTransition =>
|
SOME (unmarkedIdx, unamarkedTransition) =>
|
||||||
let
|
let
|
||||||
val dstates = markTransition (dstates, unamarkedTransition, [])
|
(* mark transition *)
|
||||||
|
val dstates =
|
||||||
|
let
|
||||||
|
val newMark = {marked = true, transitions = unamarkedTransition}
|
||||||
|
in
|
||||||
|
Vector.update (dstates, unmarkedIdx, newMark)
|
||||||
|
end
|
||||||
|
|
||||||
(* get follow transitions *)
|
(* get follow transitions *)
|
||||||
val nodes =
|
val nodes =
|
||||||
@@ -458,8 +460,15 @@ struct
|
|||||||
let
|
let
|
||||||
val subtreeStates = Set.toCharsAndPositionsList subtree
|
val subtreeStates = Set.toCharsAndPositionsList subtree
|
||||||
in
|
in
|
||||||
if statesInList (acc, subtreeStates) then acc
|
if ifStatesInVec (0, dstates, subtreeStates) then
|
||||||
else {marked = false, transitions = subtreeStates} :: acc
|
acc
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val record =
|
||||||
|
{marked = false, transitions = subtreeStates}
|
||||||
|
in
|
||||||
|
Vector.concat [acc, Vector.fromList [record]]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
, follows
|
, follows
|
||||||
, dstates
|
, dstates
|
||||||
@@ -472,7 +481,7 @@ struct
|
|||||||
fun convert regex =
|
fun convert regex =
|
||||||
let
|
let
|
||||||
val first = List.rev (firstposWithChar (regex, []))
|
val first = List.rev (firstposWithChar (regex, []))
|
||||||
val dstates = [{transitions = first, marked = false}]
|
val dstates = Vector.fromList [{transitions = first, marked = false}]
|
||||||
in
|
in
|
||||||
convertLoop (regex, dstates)
|
convertLoop (regex, dstates)
|
||||||
end
|
end
|
||||||
@@ -489,4 +498,4 @@ struct
|
|||||||
val test = ToDfa.convert
|
val test = ToDfa.convert
|
||||||
end
|
end
|
||||||
|
|
||||||
val SOME nfa = Nfa.parse "(a|b)*abb"
|
val SOME nfa = Nfa.parse "(a|b)*abb\^@"
|
||||||
|
|||||||
Reference in New Issue
Block a user