## regex-match-result.pkg
# Compiled by:
#
src/lib/std/standard.lib# Regex_Match_Results are used to
# represent the results of matching
# regular expressions against strings.
api Regex_Match_Result {
#
# A match tree is used to represent
# the results of a nested grouping
# of regular expressions.
Regex_Match_Result(X)
=
REGEX_MATCH_RESULT (X, List( Regex_Match_Result(X) ));
root: Regex_Match_Result(X) -> X; # Return the root (outermost) match in the tree
nth: ((Regex_Match_Result(X), Int)) -> X; # Return the nth match in the tree; matches are labeled in pre-order
# starting at 0. Raises INDEX_OUT_OF_BOUNDS.
map: (X -> Y) -> Regex_Match_Result(X) -> Regex_Match_Result(Y); # Map a function over the tree (in preorder)
apply: (X -> Void) -> Regex_Match_Result(X) -> Void; # Apply a given function over ever element of the tree (in preorder)
find: (X -> Bool) -> Regex_Match_Result(X) -> Null_Or(X); # Find the first match that satisfies the predicate (or NULL)
match_count: Regex_Match_Result(X) -> Int; # Return the number of submatches included in the match tree
};
package regex_match_result
: Regex_Match_Result
{
Regex_Match_Result(X)
=
REGEX_MATCH_RESULT (X, List( Regex_Match_Result(X) ));
fun match_count m
=
(count_list [m]) - 1
where
fun count_list [] => 0;
count_list ((REGEX_MATCH_RESULT (x, l)) ! ms)
=>
1 + count_list (l) + count_list (ms);
end;
end;
# Return the root (outermost) match in the tree:
#
fun root (REGEX_MATCH_RESULT (x, _))
=
x;
# Return the nth match in the tree;
# matches are labeled in pre-order
# starting at 0.
#
fun nth (t, n)
=
case (walk (n, t))
INR x => x;
INL _ => raise exception INDEX_OUT_OF_BOUNDS;
esac
where
Sum X = INL Int
| INR X;
fun walk (0, REGEX_MATCH_RESULT (x, _)) => INR x;
walk (i, REGEX_MATCH_RESULT (_, children))
=>
{ fun walk_list (i, []) => INL i;
walk_list (i, m ! r)
=>
case (walk (i, m))
INL j => walk_list (j, r);
result => result;
esac;
end;
walk_list (i - 1, children);
};
end;
end;
# Map a function over the tree (in preorder):
#
fun map f
=
mapf
where
fun mapf (REGEX_MATCH_RESULT (x, children))
=
REGEX_MATCH_RESULT (f x, mapl children)
also
fun mapl [] => [];
mapl (x ! rest) => (mapf x) ! (mapl rest);
end;
end;
fun apply f (REGEX_MATCH_RESULT (c, children))
=
{ f c;
list::apply (apply f) children;
};
# Find the first match that satisfies the predicate:
#
fun find prior
=
find_p
where
fun find_p (REGEX_MATCH_RESULT (x, children))
=
if (prior x)
THE x;
else find_list children;
fi
also
fun find_list [] => NULL;
find_list (m ! r)
=>
case (find_p m)
NULL => find_list r;
result => result;
esac;
end;
end;
}; # package regex_match_result