summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-09-15 21:37:26 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-09-15 21:37:26 -0700
commitaebb4e6b373b6724d56a32466c163e52a1c3c2a6 (patch)
treecf80f6727085746aa49b0060bf2fe8baf65f3ea1
parent3442f8621d0a1a2e581dfbbe1aa72f8bb4ee03ca (diff)
downloadtxr-aebb4e6b373b6724d56a32466c163e52a1c3c2a6.tar.gz
txr-aebb4e6b373b6724d56a32466c163e52a1c3c2a6.tar.bz2
txr-aebb4e6b373b6724d56a32466c163e52a1c3c2a6.zip
regex: fix broken complement operator.
The form (match-regex "xy" #/~ab/) should return 2 (full match) because "xy" is in the complement of the set { "ab" }. It wrongly returns 1. * regex.c (reg_derivative): Handle the case when the derivative of the complement's constituent expression yields nil. This means that the complemented regex matches the input. In this case, the complement must lapse to the .+ regex: match one or more characters. That is to say, if the input has at least one more character, there is a match, which covers all such characters. Otherwise there is no match: the input matches the complemented regex. In the t case, the return value is also wrong. If the complemented regex hits a brick wall (matches nothing, not even the empty string), the correct complement is "match everything": the .* regex. Not the match empty string regex!
-rw-r--r--regex.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/regex.c b/regex.c
index c5f5e4aa..61416fb0 100644
--- a/regex.c
+++ b/regex.c
@@ -1713,8 +1713,10 @@ static val reg_derivative(val exp, val ch)
val d_arg = reg_derivative(first(args), ch);
if (reg_matches_all(d_arg))
return t;
+ if (d_arg == nil)
+ return cons(oneplus_s, cons(wild_s, nil));
if (d_arg == t)
- return nil;
+ return cons(zeroplus_s, cons(wild_s, nil));
return cons(sym, cons(d_arg, nil));
} else if (sym == or_s) {
val d_arg1 = reg_derivative(first(args), ch);