branch: externals/xr commit 2c0af48a230a02e4db5439fc9b02c77757f37d03 Author: Mattias Engdegård <matti...@acm.org> Commit: Mattias Engdegård <matti...@acm.org>
Detect repetition-of-repetition with intervening group For example, \(.*\)* -- groups are often used even though capture is not needed. Exception: \(X+\)? does not elicit a warning. --- xr-test.el | 6 ++++++ xr.el | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/xr-test.el b/xr-test.el index 526740d..f995bfa 100644 --- a/xr-test.el +++ b/xr-test.el @@ -363,6 +363,12 @@ '((2 . "Repetition of repetition") (14 . "Repetition of repetition") (25 . "Repetition of repetition")))) + (should (equal (xr-lint "\\(a*\\)*\\(b+\\)*\\(c*\\)?\\(d+\\)?") + '((6 . "Repetition of repetition") + (13 . "Repetition of repetition") + (20 . "Repetition of repetition")))) + (should (equal (xr-lint "\\(e*\\)\\{3\\}") + '((6 . "Repetition of repetition")))) (should (equal (xr-lint "[]-Qa-fz-t]") '((1 . "Reversed range `]-Q' matches nothing") (7 . "Reversed range `z-t' matches nothing")))) diff --git a/xr.el b/xr.el index 1c74527..abe4d75 100644 --- a/xr.el +++ b/xr.el @@ -490,11 +490,27 @@ UPPER may be nil, meaning infinity." (operand (car sequence))) (when warnings (cond + ;; (* (* X)), for any repetitions * ((and (consp operand) (memq (car operand) '(opt zero-or-more one-or-more +? *? ??))) (xr--report warnings (match-beginning 0) "Repetition of repetition")) + ;; (* (group (* X))), for any repetitions * + ((and (consp operand) + (eq (car operand) 'group) + (null (cddr operand)) + (let ((inner (cadr operand))) + (and (consp inner) + (memq (car inner) + '(opt zero-or-more one-or-more +? *? ??)) + ;; Except (? (group (+ X))), since that may + ;; be legitimate. + (not (and (equal operator "?") + (memq (car inner) + '(one-or-more +?))))))) + (xr--report warnings (match-beginning 0) + "Repetition of repetition")) ((memq operand xr--zero-width-assertions) (xr--report warnings (match-beginning 0) "Repetition of zero-width assertion")) @@ -522,11 +538,22 @@ UPPER may be nil, meaning infinity." (let ((operand (car sequence))) (when warnings (cond + ;; (** N M (* X)), for any repetition * ((and (consp operand) (memq (car operand) '(opt zero-or-more one-or-more +? *? ??))) (xr--report warnings (match-beginning 0) "Repetition of repetition")) + ;; (** N M (group (* X))), for any repetition * + ((and (consp operand) + (eq (car operand) 'group) + (null (cddr operand)) + (let ((inner (cadr operand))) + (and (consp inner) + (memq (car inner) + '(opt zero-or-more one-or-more +? *? ??))))) + (xr--report warnings (match-beginning 0) + "Repetition of repetition")) ((memq operand xr--zero-width-assertions) (xr--report warnings (match-beginning 0) "Repetition of zero-width assertion"))