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:
2025-10-03 05:54:48 +01:00
parent 2de40a09c7
commit 0696d7ed52
2 changed files with 41 additions and 32 deletions

BIN
fcore/search-list/nfa Executable file

Binary file not shown.

View File

@@ -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)
| [] => false
fun getUnmarkedTransitionsIfExists lst =
case lst of
{marked, transitions} :: tl =>
if marked then getUnmarkedTransitionsIfExists tl else SOME transitions
| [] => NONE
fun addListToAcc (lst, acc) =
case lst of
hd :: tl => addListToAcc (tl, hd :: acc)
| [] => 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) let
| [] => {marked = true, transitions = transitionToMark} :: acc val {transitions, marked = _} = Vector.sub (dstates, pos)
in
transitions = newStates
orelse ifStatesInVec (pos + 1, dstates, newStates)
end
fun getUnmarkedTransitionsIfExists (pos, dstates) =
if pos = Vector.length dstates then
NONE
else
let
val record = Vector.sub (dstates, pos)
in
if #marked record then
getUnmarkedTransitionsIfExists (pos + 1, dstates)
else
SOME (pos, #transitions record)
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\^@"