diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-09-11 19:55:32 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-09-11 19:55:32 -0700 |
commit | fc5935a9fe816d64291e66b1ca5133a27f5f0230 (patch) | |
tree | ffd7371d6ee3817aedf45d63e6606f072a16ac83 /regex.c | |
parent | 6417918274d7d7d8d5b7bb675906f8e38d25c073 (diff) | |
download | txr-fc5935a9fe816d64291e66b1ca5133a27f5f0230.tar.gz txr-fc5935a9fe816d64291e66b1ca5133a27f5f0230.tar.bz2 txr-fc5935a9fe816d64291e66b1ca5133a27f5f0230.zip |
regex: new function, regex-prefix-match.
This new function allows a program to determine whether a
given string is the prefix of any of the strings denoted by a
regular expression; or, in alternative words, whether a given
string is the prefix of a possibly longer string which matches
a regular expression.
* regex.c (regex_machine_infer_init_state): New static
function.
(regex_prefix_match): New function.
(regex_init): regex-prefix-match intrinsic registered.
regex.h (regex_prefix_match): Declared.
* txr.1: Documented.
Diffstat (limited to 'regex.c')
-rw-r--r-- | regex.c | 48 |
1 files changed, 48 insertions, 0 deletions
@@ -2398,6 +2398,14 @@ static void regex_machine_cleanup(regex_machine_t *regm) } } +static regm_result_t regex_machine_infer_init_state(regex_machine_t *regm) +{ + if (regm->n.is_nfa) + return (regm->n.nclos != 0) ? REGM_INCOMPLETE : REGM_FAIL; + else + return (regm->d.deriv != t) ? REGM_INCOMPLETE : REGM_FAIL; +} + static regm_result_t regex_machine_feed(regex_machine_t *regm, wchar_t ch) { int accept = 0; @@ -2694,6 +2702,44 @@ val match_regex_right(val str, val regex, val end) return nil; } +val regex_prefix_match(val reg, val str, val pos) +{ + regex_machine_t regm; + val i; + regm_result_t last_res; + + if (null_or_missing_p(pos)) { + pos = zero; + } else if (lt(pos, zero)) { + pos = plus(pos, length_str(str)); + if (lt(pos, zero)) + return nil; + } else if (length_str_lt(str, pos)) { + return nil; + } + + regex_machine_init(®m, reg); + + last_res = regex_machine_infer_init_state(®m); + + for (i = pos; length_str_gt(str, i); i = plus(i, one)) { + last_res = regex_machine_feed(®m, c_chr(chr_str(str, i))); + if (last_res == REGM_FAIL) + break; + } + + regex_machine_cleanup(®m); + + switch (last_res) { + case REGM_INCOMPLETE: + case REGM_MATCH: + return t; + default: + case REGM_FAIL: + return nil; + } +} + val regsub(val regex, val repl, val str) { val isfunc = functionp(repl); @@ -3124,6 +3170,8 @@ void regex_init(void) reg_fun(intern(lit("match-regst-right"), user_package), func_n3o((opt_compat && opt_compat <= 150) ? match_regst_right_old : match_regst_right, 2)); + reg_fun(intern(lit("regex-prefix-match"), user_package), + func_n3o(regex_prefix_match, 2)); reg_fun(intern(lit("regsub"), user_package), func_n3(regsub)); reg_fun(intern(lit("regex-parse"), user_package), func_n2o(regex_parse, 1)); |