change representation of alternation nodes and concatenation nodes to use tuples instead of lists, as the conventional algorithms use this representation

This commit is contained in:
2025-10-01 12:17:35 +01:00
parent fd0ce5b22a
commit 7347437f17

View File

@@ -2,8 +2,8 @@ structure Nfa =
struct struct
datatype regex = datatype regex =
CHAR_LITERAL of {char: char, position: int} CHAR_LITERAL of {char: char, position: int}
| CONCAT of regex list | CONCAT of regex * regex
| ALTERNATION of regex list | ALTERNATION of regex * regex
| ZERO_OR_ONE of regex | ZERO_OR_ONE of regex
| ZERO_OR_MORE of regex | ZERO_OR_MORE of regex
| ONE_OR_MORE of regex | ONE_OR_MORE of regex
@@ -57,7 +57,7 @@ struct
SOME (rhs, stateNum) => SOME (rhs, stateNum) =>
let let
val rhs = GROUP rhs val rhs = GROUP rhs
val result = CONCAT [lhs, rhs] val result = CONCAT (lhs, rhs)
in in
climb climb
( groupEndIdx + 1 ( groupEndIdx + 1
@@ -81,10 +81,7 @@ struct
case climb (pos + 2, str, chr, altLevel, stateNum + 1) of case climb (pos + 2, str, chr, altLevel, stateNum + 1) of
SOME (pos, rhs, stateNum) => SOME (pos, rhs, stateNum) =>
let let
val result = val result = ALTERNATION (lhs, rhs)
case rhs of
ALTERNATION lst => ALTERNATION (lhs :: lst)
| _ => ALTERNATION [lhs, rhs]
in in
SOME (pos, result, stateNum) SOME (pos, result, stateNum)
end end
@@ -127,10 +124,7 @@ struct
of of
SOME (pos, rhs, stateNum) => SOME (pos, rhs, stateNum) =>
let let
val result = val result = CONCAT (lhs, rhs)
case rhs of
CONCAT lst => CONCAT (lhs :: lst)
| _ => CONCAT [lhs, rhs]
in in
SOME (pos, result, stateNum) SOME (pos, result, stateNum)
end end
@@ -167,34 +161,16 @@ struct
CHAR_LITERAL _ => false CHAR_LITERAL _ => false
| WILDCARD => false | WILDCARD => false
| CONCAT [] => true | CONCAT (r1, r2) => isNullable r1 andalso isNullable r2
| CONCAT concatList => isConcatNullable concatList
| ALTERNATION [] => true | ALTERNATION [] => true
| ALTERNATION altList => isAlternationNullable (altList, true) | ALTERNATION altList => isNullable r1 orelse isNullable r2
| ZERO_OR_ONE _ => true | ZERO_OR_ONE _ => true
| ZERO_OR_MORE _ => true | ZERO_OR_MORE _ => true
| ONE_OR_MORE regex => isNullable regex | ONE_OR_MORE regex => isNullable regex
| GROUP regex => isNullable regex | GROUP regex => isNullable regex
(* if just one node is nullable, then concat node is nullable too *)
and isConcatNullable lst =
case lst of
hd :: tl => isNullable hd orelse isAlternationNullable (tl, false)
| [] => false
(* if all nodes are nullable, then alt node is also nullable *)
and isAlternationNullable (lst, areAllNullableSoFar) =
case lst of
hd :: tl =>
let
val isCurrentNullable = isNullable hd andalso areAllNullableSoFar
in
isAlternationNullable (tl, isCurrentNullable)
end
| [] => areAllNullableSoFar
end end
fun parse str = fun parse str =