[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/xr 3af4048 4/9: Suppress false positives in repetition
From: |
Mattias Engdegård |
Subject: |
[elpa] externals/xr 3af4048 4/9: Suppress false positives in repetition subsumption check (bug #2) |
Date: |
Sat, 29 Feb 2020 17:22:12 -0500 (EST) |
branch: externals/xr
commit 3af4048e36e21f172ba7ade31d6fae9e30546c09
Author: Mattias Engdegård <address@hidden>
Commit: Mattias Engdegård <address@hidden>
Suppress false positives in repetition subsumption check (bug #2)
The sequence (Rx X) (Ry y) is not equivalent to (Rx X) if
Rx is non-greedy and Ry is greedy.
For example, "[ab]+?a*" should not elicit a repetition subsumption
complaint; it is not equivalent to "[ab]+?".
This fixes bug #2, reported by Hirofumi Ogawa.
---
xr-test.el | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
xr.el | 43 ++++++++++++++++++++-------------
2 files changed, 103 insertions(+), 21 deletions(-)
diff --git a/xr-test.el b/xr-test.el
index e0d00b9..a0b5402 100644
--- a/xr-test.el
+++ b/xr-test.el
@@ -442,17 +442,88 @@
'((4 . "Branch matches superset of a previous branch"))))
(should (equal (xr-lint "abc\\|abcd*e?")
'((5 . "Branch matches superset of a previous branch"))))
- (should (equal (xr-lint "[ab]+a?,a?[ab]+,[ab]*a*,a*[ab]*")
+ ))
+
+(ert-deftest xr-lint-subsumed-repetition ()
+ (let ((text-quoting-style 'grave))
+ (should (equal (xr-lint "\\(?:a.c\\|def\\)+\\(?:abc\\)*")
+ '((24 . "Repetition subsumed by preceding repetition"))))
+
+ ;; Exhaustive test of all possible combinations.
+ (should (equal (xr-lint "[ab]+a?,a?[ab]+,[ab]+a*,a*[ab]+")
+ '((6 . "Repetition subsumed by preceding repetition")
+ (14 . "Repetition subsumes preceding repetition")
+ (22 . "Repetition subsumed by preceding repetition")
+ (30 . "Repetition subsumes preceding repetition"))))
+
+ (should (equal (xr-lint "[ab]*a?,a?[ab]*,[ab]*a*,a*[ab]*")
'((6 . "Repetition subsumed by preceding repetition")
(14 . "Repetition subsumes preceding repetition")
(22 . "Repetition subsumed by preceding repetition")
(30 . "Repetition subsumes preceding repetition"))))
- (should (equal (xr-lint "[^a]+b*,a?.*,a*a*,a*a+")
+
+ (should (equal (xr-lint "a+a?,a?a+,a+a*,a*a+,a*a?,a?a*,a*a*")
+ '((3 . "Repetition subsumed by preceding repetition")
+ (8 . "Repetition subsumes preceding repetition")
+ (13 . "Repetition subsumed by preceding repetition")
+ (18 . "Repetition subsumes preceding repetition")
+ (23 . "Repetition subsumed by preceding repetition")
+ (28 . "Repetition subsumes preceding repetition")
+ (33 . "Repetition subsumed by preceding repetition"))))
+
+ (should (equal (xr-lint "[ab]+a??,a??[ab]+,[ab]+a*?,a*?[ab]+")
+ '((6 . "Repetition subsumed by preceding repetition")
+ (16 . "Repetition subsumes preceding repetition")
+ (24 . "Repetition subsumed by preceding repetition")
+ (34 . "Repetition subsumes preceding repetition"))))
+
+ (should (equal (xr-lint "[ab]*a??,a??[ab]*,[ab]*a*?,a*?[ab]*")
'((6 . "Repetition subsumed by preceding repetition")
+ (16 . "Repetition subsumes preceding repetition")
+ (24 . "Repetition subsumed by preceding repetition")
+ (34 . "Repetition subsumes preceding repetition"))))
+
+ (should (equal (xr-lint "a+a??,a??a+,a+a*?,a*?a+,a*a??,a??a*,a*a*?,a*?a*")
+ '((3 . "Repetition subsumed by preceding repetition")
+ (10 . "Repetition subsumes preceding repetition")
+ (15 . "Repetition subsumed by preceding repetition")
+ (22 . "Repetition subsumes preceding repetition")
+ (27 . "Repetition subsumed by preceding repetition")
+ (34 . "Repetition subsumes preceding repetition")
+ (39 . "Repetition subsumed by preceding repetition")
+ (46 . "Repetition subsumes preceding repetition"))))
+
+ (should (equal (xr-lint "[ab]+?a?,a?[ab]+?,[ab]+?a*,a*[ab]+?")
+ nil))
+
+ (should (equal (xr-lint "[ab]*?a?,a?[ab]*?,[ab]*?a*,a*[ab]*?")
+ nil))
+
+ (should (equal (xr-lint "a+?a?,a?a+?,a+?a*,a*a+?,a*?a?,a?a*?,a*?a*,a*a*?")
+ '((40 . "Repetition subsumes preceding repetition")
+ (45 . "Repetition subsumed by preceding repetition"))))
+
+ (should (equal (xr-lint "[ab]+?a??,a??[ab]+?,[ab]+?a*?,a*?[ab]+?")
+ '((7 . "Repetition subsumed by preceding repetition")
+ (17 . "Repetition subsumes preceding repetition")
+ (27 . "Repetition subsumed by preceding repetition")
+ (37 . "Repetition subsumes preceding repetition"))))
+
+ (should (equal (xr-lint "[ab]*?a??,a??[ab]*?,[ab]*?a*?,a*?[ab]*?")
+ '((7 . "Repetition subsumed by preceding repetition")
+ (17 . "Repetition subsumes preceding repetition")
+ (27 . "Repetition subsumed by preceding repetition")
+ (37 . "Repetition subsumes preceding repetition"))))
+
+ (should (equal (xr-lint "a+?a??,a??a+?,a+?a*?,a*?a+?,a*?a??,a??a*?,a*?a*?")
+ '((4 . "Repetition subsumed by preceding repetition")
(11 . "Repetition subsumes preceding repetition")
- (16 . "Repetition subsumed by preceding repetition")
- (21 . "Repetition subsumes preceding repetition"))))
- ))
+ (18 . "Repetition subsumed by preceding repetition")
+ (25 . "Repetition subsumes preceding repetition")
+ (32 . "Repetition subsumed by preceding repetition")
+ (39 . "Repetition subsumes preceding repetition")
+ (46 . "Repetition subsumed by preceding repetition"))))
+ ))
(ert-deftest xr-skip-set ()
(should (equal (xr-skip-set "0-9a-fA-F+*")
diff --git a/xr.el b/xr.el
index 6409554..fc5c7f7 100644
--- a/xr.el
+++ b/xr.el
@@ -713,9 +713,13 @@ UPPER may be nil, meaning infinity."
(when (and warnings (cdr sequence))
;; Check for subsuming repetitions in sequence: (Rx X) (Ry Y)
;; where Rx and Ry are repetition operators, and X and Y are
operands.
- ;; We conclude that (Rx X) subsumes (Ry Y) if Rx can match
- ;; infinitely many times, Ry can match zero times,
- ;; and X matches a superset of Y. Example: [ab]+a?
+ ;; We conclude that (Rx X) subsumes (Ry Y), in the sense that the
+ ;; sequence is equivalent to just (Rx X), if:
+ ;; X matches a superset of Y
+ ;; and Rx can match infinitely many times
+ ;; and Ry can match zero times
+ ;; and Ry is non-greedy if Rx is non-greedy.
+ ;; Example: [ab]+a?
(let* ((item (car sequence))
(expr (and (consp item)
(memq (car item)
@@ -729,19 +733,26 @@ UPPER may be nil, meaning infinity."
'(zero-or-more one-or-more opt *? +? ??))
(xr--make-seq (cdr prev-item)))))
(when prev-expr
- (cond
- ((and (memq (car item) '(zero-or-more opt *? ??))
- (memq (car prev-item)
- '(zero-or-more one-or-more *? +?))
- (xr--superset-p prev-expr expr))
- (xr--report warnings item-start
- "Repetition subsumed by preceding repetition"))
- ((and (memq (car prev-item) '(zero-or-more opt *? ??))
- (memq (car item) '(zero-or-more one-or-more *? +?))
- (xr--superset-p expr prev-expr))
- (xr--report
- warnings item-start
- "Repetition subsumes preceding repetition"))))))))))
+ (let ((op (car item))
+ (prev-op (car prev-item)))
+ ;; Test the same condition twice, but mirrored.
+ (cond
+ ((and (memq op '(zero-or-more opt *? ??))
+ (memq prev-op '(zero-or-more one-or-more *? +?))
+ (not (and (memq prev-op '(*? +?))
+ (memq op '(zero-or-more opt))))
+ (xr--superset-p prev-expr expr))
+ (xr--report
+ warnings item-start
+ "Repetition subsumed by preceding repetition"))
+ ((and (memq prev-op '(zero-or-more opt *? ??))
+ (memq op '(zero-or-more one-or-more *? +?))
+ (not (and (memq op '(*? +?))
+ (memq prev-op '(zero-or-more opt))))
+ (xr--superset-p expr prev-expr))
+ (xr--report
+ warnings item-start
+ "Repetition subsumes preceding repetition")))))))))))
(let ((item-seq (xr--rev-join-seq sequence)))
(cond ((null item-seq)
- [elpa] externals/xr updated (b5ae891 -> dcf5240), Mattias Engdegård, 2020/02/29
- [elpa] externals/xr 9a8bf08 2/9: Update copyright year to 2020, Mattias Engdegård, 2020/02/29
- [elpa] externals/xr 0fb29c8 1/9: Update copyright year to 2020, Mattias Engdegård, 2020/02/29
- [elpa] externals/xr 9d9debd 5/9: Remove package description in xr.el, Mattias Engdegård, 2020/02/29
- [elpa] externals/xr 3af4048 4/9: Suppress false positives in repetition subsumption check (bug #2),
Mattias Engdegård <=
- [elpa] externals/xr 1932e3d 7/9: Avoid ambiguous regexp (relint/xr complaint), Mattias Engdegård, 2020/02/29
- [elpa] externals/xr d7a6480 8/9: Translate [^\n] into nonl, Mattias Engdegård, 2020/02/29
- [elpa] externals/xr dcf5240 9/9: Increment version to 1.16, Mattias Engdegård, 2020/02/29
- [elpa] externals/xr e82efe8 6/9: Improved character class set relations, Mattias Engdegård, 2020/02/29
- [elpa] externals/xr c88fb0e 3/9: Use text quoting for all messages, Mattias Engdegård, 2020/02/29