summaryrefslogtreecommitdiffstats
path: root/regex.c
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
commit2fea7e5998e4e757d62146e67491ee09f6d1738b (patch)
treecf80f6727085746aa49b0060bf2fe8baf65f3ea1 /regex.c
parent5a09b244c77dbf498a4bdf7a9381d2741ce87055 (diff)
downloadtxr-2fea7e5998e4e757d62146e67491ee09f6d1738b.tar.gz
txr-2fea7e5998e4e757d62146e67491ee09f6d1738b.tar.bz2
txr-2fea7e5998e4e757d62146e67491ee09f6d1738b.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!
Diffstat (limited to 'regex.c')
-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);