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:
@@ -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 =
|
||||||
|
|||||||
Reference in New Issue
Block a user