From 2fea7e5998e4e757d62146e67491ee09f6d1738b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 15 Sep 2016 21:37:26 -0700 Subject: 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! --- regex.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'regex.c') 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); -- cgit v1.2.3