From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: kevin.legouguec@gmail.com, monnier@iro.umontreal.ca, bug-gnu-emacs@gnu.org Resent-Date: Sat, 15 Jun 2019 23:44:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: 36237@debbugs.gnu.org Cc: =?UTF-8?Q?k=C3=A9vin?= le gouguec , stefan monnier X-Debbugs-Original-To: bug-gnu-emacs@gnu.org X-Debbugs-Original-Xcc: =?UTF-8?Q?k=C3=A9vin?= le gouguec , stefan monnier Received: via spool by submit@debbugs.gnu.org id=B.156064222928390 (code B ref -1); Sat, 15 Jun 2019 23:44:02 +0000 Received: (at submit) by debbugs.gnu.org; 15 Jun 2019 23:43:49 +0000 Received: from localhost ([127.0.0.1]:39407 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcIKq-0007Np-Em for submit@debbugs.gnu.org; Sat, 15 Jun 2019 19:43:49 -0400 Received: from lists.gnu.org ([209.51.188.17]:58015) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcIKn-0007Ne-Kp for submit@debbugs.gnu.org; Sat, 15 Jun 2019 19:43:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40184) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hcIKl-0001C2-2v for bug-gnu-emacs@gnu.org; Sat, 15 Jun 2019 19:43:45 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM, URIBL_BLOCKED autolearn=disabled version=3.3.2 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hcIKi-0005hG-HL for bug-gnu-emacs@gnu.org; Sat, 15 Jun 2019 19:43:43 -0400 Received: from mail-io1-xd2a.google.com ([2607:f8b0:4864:20::d2a]:33633) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hcIKe-0005YC-Hc for bug-gnu-emacs@gnu.org; Sat, 15 Jun 2019 19:43:36 -0400 Received: by mail-io1-xd2a.google.com with SMTP id u13so13800980iop.0 for ; Sat, 15 Jun 2019 16:43:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version; bh=l9BQeYphiuEVtWQl3fLWyXoPkr+U9N8r+V9MdAFSp/o=; b=EiFvtQ2pbRIoqfYz//NMuQIuOdwngnQhomMAwz0rI5RBmvsiJzsG5lrYFQDASd/GZ6 b3VzeXNqH13l/uQLM1IdUUaoSChUtSpFiXD71xz+ukESCxABhzQUmy60GwQxaeUSLMZ7 90rUaoOhpoIDa1fetk3nOTt+EZ4ao0DzmojKnYa12ezBUc9JwVAKJp2xqxTbzmzHk5oH 8nS0ECYiYFE7Bj1CMUskr9Pg4inxjt/VIrjFw/5E7oziAa/Jkr7FrVLcIllFGNJVm2n7 i8dZvlNYJ5Za1PkQGVC3/MAOD7fbTlw4e0uG00rsJnMYwb1/WtnNUlm15CIXnZ+rO4RJ wiFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version; bh=l9BQeYphiuEVtWQl3fLWyXoPkr+U9N8r+V9MdAFSp/o=; b=sMaRvfbJvcVNfjYUmKQJVM9KNcww7YpLbGfIVKKI1/FAQ68NxRse/Rg39e6fx2eDA8 mKTg9rGT9ciCkRjgbqwBh3jBnxh+Wh0+PLNqEDkgH82WJH/lbAvHqmapdi47Qc1zesfk rIAJBjheR8xFssXfiVMGN5G2vtsM8H1u0Vp5Vs7LXBAjKjOPuppVW7DurK4/Al1JiNCE gnNorRVALkueMIm8fxT9qBlII43/w9Zxar5glA6k9Smv6krfLz3HQqgB5zS8QXwj6dVz 0G8WlFWrBHezgMJDi4kJYLS6kWVqmFxZ/E9u6T33oQ3vtxmrmbU2be0aRA+4OKdet2rI k1bg== X-Gm-Message-State: APjAAAV0FdXKLYBJKvfj2P64eP6ikfMS8osuu872pyr/oad/PGrG81jh /S/MZd9FREXzvsm3EV0n78uDkRWN X-Google-Smtp-Source: APXvYqyuDkEXTgNAAzyOrixSWiHmtqk/2NBORdbsLpooJHSzxa+r5PFkfzw4U6YTogZp977LxavggQ== X-Received: by 2002:a02:bb83:: with SMTP id g3mr19471894jan.139.1560642213055; Sat, 15 Jun 2019 16:43:33 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id b6sm5450126iok.71.2019.06.15.16.43.30 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Jun 2019 16:43:31 -0700 (PDT) From: Noam Postavsky Date: Sat, 15 Jun 2019 19:43:30 -0400 Message-ID: <87v9x6xvml.fsf@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::d2a X-Spam-Score: -1.3 (-) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Debbugs-CC: K=C3=A9vin Le Gouguec , Stefan Mon= nier Severity: wishlist Tags: patch Currently, if you want to construct a regexp which includes a runtime values using rx, there are two options: - Use the (eval FORM) subform. But if using using the rx macro, FORM is evaluated at macroexpansion time, which is awkward. If using rx-to-string, then FORM can't access the lexical environment, which is also awkward. - Build a list at runtime and pass to rx-to-string. This requires the whole rx translation infrastructure at runtime, which is sad. The patch below allows the rx macro to generate a concat expression instead of just a plain string. So the example from https://debbugs.gnu.org/35564#53 would become (let ((start (max 0 (1- pos))) (char (string (aref command pos)))) ; need string for `regexp-quo= te'. (and (string-match (rx (or (seq (or bos blank) (group-n 1 (regexp-quote char)) (or eos blank)) (seq ?` (group-n 1 (regexp-quote char)) ?`))) command start) (=3D pos (match-beginning 1)))) The rx call in the above macroexpands into: (concat "\\(?:\\`\\|[[:blank:]]\\)" "\\(?" "1" ":" (regexp-quote char) "\\)" "\\(?:\\'\\|[[:blank:]]\\)" "\\|" "`" "\\(?" "1" ":" (regexp-quote char) "\\)" "`") Which will be optimal once we apply the patch from #14769 "optimize `concat's literals". --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-Support-rx-and-regexp-EXPR-regexp-quote-EXPR.patch Content-Description: patch >From 6b6c6d8997d02236a4e53ccbe1f6a4b362d9b86c Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Fri, 14 Jun 2019 08:43:17 -0400 Subject: [PATCH] Support (rx (and (regexp EXPR) (regexp-quote EXPR))) * lisp/emacs-lisp/rx.el (rx-regexp): Allow non-string forms. (rx-constituents): Add regexp-quote constituent, which is like a plain STRING form, but allows arbitrary lisp expressions. (rx-regexp-quote): New function. (rx-compile-to-lisp): New variable. (rx-subforms): New helper function for handling subforms, including non-constant case. (rx-group-if, rx-and, rx-or, rx-=, rx->=, rx-repeat, rx-submatch) (rx-submatch-n, rx-kleene, rx-atomic-p): Use it to handle non-constant subforms. (rx): Document new form, wrap non-constant forms with concat call. * test/lisp/emacs-lisp/rx-tests.el (rx-tests--match): New macro. (rx-nonstring-expr, rx-nonstring-expr-non-greedy): New tests. * etc/NEWS: Announce changes. --- etc/NEWS | 6 ++ lisp/emacs-lisp/rx.el | 189 +++++++++++++++++++++++++-------------- test/lisp/emacs-lisp/rx-tests.el | 41 +++++++++ 3 files changed, 171 insertions(+), 65 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 723f0a0fb0..bce755a211 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1380,12 +1380,18 @@ when given in a string. Previously, '(any "\x80-\xff")' would match characters U+0080...U+00FF. Now the expression matches raw bytes in the 128...255 range, as expected. +--- *** The rx 'or' and 'seq' forms no longer require any arguments. (or) produces a regexp that never matches anything, while (seq) matches the empty string, each being an identity for the operation. This also works for their aliases: '|' for 'or'; ':', 'and' and 'sequence' for 'seq'. +--- +*** 'regexp' and new 'regexp-quote' accept arbirtray lisp as arguments. +In this case, 'rx' will generate code which produces a regexp string +at runtime, instead of a constant string. + ** Frames +++ diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 8ef78fd69e..0b7765322b 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -47,9 +47,11 @@ ;; Rx translates a sexp notation for regular expressions into the ;; usual string notation. The translation can be done at compile-time -;; by using the `rx' macro. It can be done at run-time by calling -;; function `rx-to-string'. See the documentation of `rx' for a -;; complete description of the sexp notation. +;; by using the `rx' macro. The `regexp' and `regexp-quote' accept +;; non-constant expressions, in which case `rx' will translate to a +;; `concat' expression. Translation can be done fully at run-time by +;; calling function `rx-to-string'. See the documentation of `rx' for +;; a complete description of the sexp notation. ;; ;; Some examples of string regexps and their sexp counterparts: ;; @@ -78,8 +80,8 @@ ;; (+ (? ?\n)) (any " \t")) ;; ;; (concat "^\\(?:" something-else "\\)") -;; (rx (and line-start (eval something-else))), statically or -;; (rx-to-string '(and line-start ,something-else)), dynamically. +;; (rx (and line-start (regexp something-else))), statically or +;; (rx-to-string `(and line-start ,something-else)), dynamically. ;; ;; (regexp-opt '(STRING1 STRING2 ...)) ;; (rx (or STRING1 STRING2 ...)), or in other words, `or' automatically @@ -176,6 +178,7 @@ (defvar rx-constituents ;Not `const' because some modes extend it. (not-syntax . (rx-not-syntax 1 1)) ; sregex (category . (rx-category 1 1 rx-check-category)) (eval . (rx-eval 1 1)) + (regexp-quote . (rx-regexp-quote 1 1 stringp)) (regexp . (rx-regexp 1 1 stringp)) (regex . regexp) ; sregex (digit . "[[:digit:]]") @@ -302,6 +305,10 @@ (defvar rx-greedy-flag t "Non-nil means produce greedy regular expressions for `zero-or-one', `zero-or-more', and `one-or-more'. Dynamically bound.") +(defvar rx-compile-to-lisp nil + "Nil means return a regexp as a string. +Non-nil means we may return a lisp form which produces a +string (used for `rx' macro).") (defun rx-info (op head) "Return parsing/code generation info for OP. @@ -344,7 +351,7 @@ (defun rx-check (form) (> nargs max-args)) (error "rx form `%s' accepts at most %d args" (car form) max-args)) - (when (not (null type-pred)) + (when type-pred (dolist (sub-form (cdr form)) (unless (funcall type-pred sub-form) (error "rx form `%s' requires args satisfying `%s'" @@ -360,19 +367,21 @@ (defun rx-group-if (regexp group) ;; for concatenation ((eq group ':) (if (rx-atomic-p - (if (string-match - "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp) - (substring regexp 0 (match-beginning 0)) - regexp)) - (setq group nil))) + (if (and (stringp regexp) + (string-match + "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp)) + (substring regexp 0 (match-beginning 0)) + regexp)) + (setq group nil))) ;; for OR ((eq group '|) (setq group nil)) ;; do anyway ((eq group t)) ((rx-atomic-p regexp t) (setq group nil))) - (if group - (concat "\\(?:" regexp "\\)") - regexp)) + (cond ((and group (stringp regexp)) + (concat "\\(?:" regexp "\\)")) + (group `("\\(?:" ,@regexp "\\)")) + (t regexp))) (defvar rx-parent) @@ -384,7 +393,7 @@ (defun rx-and (form) FORM is of the form `(and FORM1 ...)'." (rx-check form) (rx-group-if - (mapconcat (lambda (x) (rx-form x ':)) (cdr form) nil) + (rx-subforms (cdr form) ':) (and (memq rx-parent '(* t)) rx-parent))) @@ -396,7 +405,7 @@ (defun rx-or (form) ((null (cdr form)) regexp-unmatchable) ((cl-every #'stringp (cdr form)) (regexp-opt (cdr form) nil t)) - (t (mapconcat (lambda (x) (rx-form x '|)) (cdr form) "\\|"))) + (t (rx-subforms (cdr form) '| "\\|"))) (and (memq rx-parent '(: * t)) rx-parent))) @@ -669,7 +678,10 @@ (defun rx-= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `=' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) (defun rx->= (form) @@ -679,7 +691,10 @@ (defun rx->= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `>=' requires positive integer first arg")) - (format "%s\\{%d,\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d,\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d,\\}" (nth 1 form)))))) (defun rx-** (form) @@ -700,7 +715,10 @@ (defun rx-repeat (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `repeat' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) ((or (not (integerp (nth 2 form))) (< (nth 2 form) 0) (not (integerp (nth 1 form))) @@ -708,30 +726,26 @@ (defun rx-repeat (form) (< (nth 2 form) (nth 1 form))) (error "rx `repeat' range error")) (t - (format "%s\\{%d,%d\\}" (rx-form (nth 3 form) '*) - (nth 1 form) (nth 2 form))))) + (let ((subform (rx-form (nth 3 form) '*))) + (if (stringp subform) + (format "%s\\{%d,%d\\}" subform (nth 1 form) (nth 2 form)) + `(,@subform ,(format "\\{%d,%d\\}" (nth 1 form) (nth 2 form)))))))) (defun rx-submatch (form) "Parse and produce code from FORM, which is `(submatch ...)'." - (concat "\\(" - (if (= 2 (length form)) - ;; Only one sub-form. - (rx-form (cadr form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cdr form) nil)) - "\\)")) + (let ((subforms (rx-subforms (cdr form) ':))) + (if (stringp subforms) + (concat "\\(" subforms "\\)") + `("\\(" ,@subforms "\\)")))) (defun rx-submatch-n (form) "Parse and produce code from FORM, which is `(submatch-n N ...)'." - (let ((n (nth 1 form))) - (concat "\\(?" (number-to-string n) ":" - (if (= 3 (length form)) - ;; Only one sub-form. - (rx-form (nth 2 form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cddr form) nil)) - "\\)"))) + (let ((n (nth 1 form)) + (subforms (rx-subforms (cddr form) ':))) + (if (stringp subforms) + (concat "\\(?" (number-to-string n) ":" subforms "\\)") + `("\\(?" ,(number-to-string n) ":" ,@subforms "\\)")))) (defun rx-backref (form) "Parse and produce code from FORM, which is `(backref N)'." @@ -759,9 +773,12 @@ (defun rx-kleene (form) (t "?"))) (op (cond ((memq (car form) '(* *? 0+ zero-or-more)) "*") ((memq (car form) '(+ +? 1+ one-or-more)) "+") - (t "?")))) + (t "?"))) + (subform (rx-form (cadr form) '*))) (rx-group-if - (concat (rx-form (cadr form) '*) op suffix) + (if (stringp subform) + (concat subform op suffix) + `(,@subform ,(concat op suffix))) (and (memq rx-parent '(t *)) rx-parent)))) @@ -789,15 +806,18 @@ (defun rx-atomic-p (r &optional lax) be detected without much effort. A guarantee of no false negatives would require a theoretic specification of the set of all atomic regexps." - (let ((l (length r))) - (cond - ((<= l 1)) - ((= l 2) (= (aref r 0) ?\\)) - ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) - ((null lax) + (if (and rx-compile-to-lisp + (not (stringp r))) + nil ;; Runtime value, we must assume non-atomic. + (let ((l (length r))) (cond - ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) - ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r))))))) + ((<= l 1)) + ((= l 2) (= (aref r 0) ?\\)) + ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) + ((null lax) + (cond + ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) + ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r)))))))) (defun rx-syntax (form) @@ -853,9 +873,23 @@ (defun rx-greedy (form) (defun rx-regexp (form) "Parse and produce code from FORM, which is `(regexp STRING)'." - (rx-check form) - (rx-group-if (cadr form) rx-parent)) - + (cond ((stringp form) + (rx-group-if (cadr form) rx-parent)) + (rx-compile-to-lisp + ;; Always group non string forms, since we can't be sure they + ;; are atomic. + (rx-group-if (cdr form) t)) + (t (rx-check form)))) + +(defun rx-regexp-quote (form) + "Parse and produce code from FORM, which is `(regexp-quote STRING-EXP)'." + (cond ((stringp form) + ;; This is allowed(?), but makes little sense, you could just + ;; use STRING directly. + (rx-group-if (regexp-quote (cadr form)) rx-parent)) + (rx-compile-to-lisp + (rx-group-if (list form) rx-parent)) + (t (rx-check form)))) (defun rx-form (form &optional parent) "Parse and produce code for regular expression FORM. @@ -886,6 +920,27 @@ (defun rx-form (form &optional parent) (t (error "rx syntax error at `%s'" form))))) +(defun rx-subforms (subforms &optional parent regexp-op) + (let ((listify (lambda (x) + (if (listp x) (copy-sequence x) + (list x)))) + (subregexps (cond ((cdr subforms) + (mapcar (lambda (x) (rx-form x parent)) subforms)) + (subforms + ;; Single form, no need for grouping. + (list (rx-form (car subforms)))) + ;; Zero forms. + (t "")))) + (cond ((or (not rx-compile-to-lisp) + (cl-every #'stringp subregexps)) + (mapconcat #'identity subregexps regexp-op)) + (regexp-op + (nconc (funcall listify (car subregexps)) + (cl-mapcan (lambda (x) + (cons regexp-op (funcall listify x))) + (cdr subregexps)))) + (t (cl-mapcan listify subregexps))))) + ;;;###autoload (defun rx-to-string (form &optional no-group) @@ -901,8 +956,12 @@ (defmacro rx (&rest regexps) REGEXPS is a non-empty sequence of forms of the sort listed below. Note that `rx' is a Lisp macro; when used in a Lisp program being -compiled, the translation is performed by the compiler. -See `rx-to-string' for how to do such a translation at run-time. +compiled, the translation is performed by the compiler. The +`regexp-quote' and `regexp' accept forms that will evaluate to +strings, in addition to constant strings. If REGEXPS include +such forms, then the result is an expression which returns a +regexp string, rather than a regexp string directly. See +`rx-to-string' for performing translation completely at run-time. The following are valid subforms of regular expressions in sexp notation. @@ -910,6 +969,10 @@ (defmacro rx (&rest regexps) STRING matches string STRING literally. +`(regexp-quote STRING)' + matches STRING literally, where STRING is any lisp + expression that evaluates to a string. + CHAR matches character CHAR literally. @@ -1208,12 +1271,16 @@ (defmacro rx (&rest regexps) `(regexp REGEXP)' include REGEXP in string notation in the result." - (cond ((null regexps) - (error "No regexp")) - ((cdr regexps) - (rx-to-string `(and ,@regexps) t)) - (t - (rx-to-string (car regexps) t)))) + (let* ((rx-compile-to-lisp t) + (re (cond ((null regexps) + (error "No regexp")) + ((cdr regexps) + (rx-to-string `(and ,@regexps) t)) + (t + (rx-to-string (car regexps) t))))) + (if (stringp re) + re + `(concat ,@re)))) (pcase-defmacro rx (&rest regexps) @@ -1275,14 +1342,6 @@ (pcase-defmacro rx (&rest regexps) for var in vars collect `(app (match-string ,i) ,var))))) -;; ;; sregex.el replacement - -;; ;;;###autoload (provide 'sregex) -;; ;;;###autoload (autoload 'sregex "rx") -;; (defalias 'sregex 'rx-to-string) -;; ;;;###autoload (autoload 'sregexq "rx" nil nil 'macro) -;; (defalias 'sregexq 'rx) - (provide 'rx) ;;; rx.el ends here diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 6f392d616d..d457f6919d 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -115,5 +115,46 @@ (ert-deftest rx-seq () ;; Test zero-argument `seq'. (should (equal (rx (seq)) ""))) +(defmacro rx-tests--match (regexp string &optional match) + (macroexp-let2 nil strexp string + `(ert-info ((format "Matching %S to %S" ',regexp ,strexp)) + (should (string-match ,regexp ,strexp)) + ,@(when match + `((should (equal (match-string 0 ,strexp) ,match))))))) + +(ert-deftest rx-nonstring-expr () + (let ((bee "b") + (vowel "[aeiou]")) + (rx-tests--match (rx "a" (regexp-quote bee) "c") "abc") + (rx-tests--match (rx "a" (regexp bee) "c") "abc") + (rx-tests--match (rx "a" (or (regexp bee) "xy") "c") "abc") + (rx-tests--match (rx "a" (or "xy" (regexp bee)) "c") "abc") + (should-not (string-match (rx (or (regexp bee) "xy")) "")) + (rx-tests--match (rx "a" (= 3 (regexp bee)) "c") "abbbc") + (rx-tests--match (rx "x" (= 3 (regexp vowel)) "z") "xeoez") + (should-not (string-match (rx "x" (= 3 (regexp vowel)) "z") "xe[]z")) + (rx-tests--match (rx "x" (= 3 (regexp-quote vowel)) "z") + "x[aeiou][aeiou][aeiou]z") + (rx-tests--match (rx "x" (repeat 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xauz") + (rx-tests--match (rx "x" (>= 1 (regexp vowel)) "z") "xaiiz") + (rx-tests--match (rx "x" (** 1 2 (regexp vowel)) "z") "xaiz") + (rx-tests--match (rx "x" (group (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (group-n 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (? (regexp vowel)) "z") "xz"))) + +(ert-deftest rx-nonstring-expr-non-greedy () + "`rx's greediness can't affect runtime regexp parts." + (let ((ad-min "[ad]*?") + (ad-max "[ad]*") + (ad "[ad]")) + (rx-tests--match (rx "c" (regexp ad-min) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (regexp ad-max) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (minimal-match (regexp ad-max)) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (maximal-match (regexp ad-min)) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (minimal-match (0+ (regexp ad))) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (maximal-match (0+ (regexp ad))) "a") "cdaaada" "cdaaada"))) + (provide 'rx-tests) ;; rx-tests.el ends here. -- 2.11.0 --=-=-=-- From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Michael Heerdegen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 00:04:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky Cc: 36237@debbugs.gnu.org, stefan monnier , =?UTF-8?Q?k=C3=A9vin?= le gouguec Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156064344030971 (code B ref 36237); Sun, 16 Jun 2019 00:04:02 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 00:04:00 +0000 Received: from localhost ([127.0.0.1]:39425 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcIeO-00083T-FV for submit@debbugs.gnu.org; Sat, 15 Jun 2019 20:04:00 -0400 Received: from mout.web.de ([212.227.15.14]:45131) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcIeM-00083D-AY for 36237@debbugs.gnu.org; Sat, 15 Jun 2019 20:03:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1560643422; bh=FHi9x/cNU6U76kvcG8e4ml2Fr/0es4mzpue0+OQXqOY=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=IQoEvWZk/+93OxieuHEbwpWkUtLNQxrw+QtTufVcuzuwBjznqOic/3NBkKvM5ERDg zdfVwPDexQywoHFGpFQPp4BngkosElEwxaCP6IhPl2MBEvTpBbGWboTfqw/6XgURLY 08eZ01bUfjR5XLeAORi7z9Dlon8N0owsXrOmUdbY= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([188.98.106.25]) by smtp.web.de (mrweb002 [213.165.67.108]) with ESMTPSA (Nemesis) id 0Md4ZG-1huVzA0Bjm-00IFhQ; Sun, 16 Jun 2019 02:03:42 +0200 From: Michael Heerdegen References: <87v9x6xvml.fsf@gmail.com> Date: Sun, 16 Jun 2019 02:03:40 +0200 In-Reply-To: <87v9x6xvml.fsf@gmail.com> (Noam Postavsky's message of "Sat, 15 Jun 2019 19:43:30 -0400") Message-ID: <87r27u75wj.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Provags-ID: V03:K1:uBQuzrrPqcm6tDB0ZgDPo3yBdUbcbAFQ9YjlkuGhbTpGy+1lY8O oDYYAsSp7Y1PKDNkkFTdO/6SteEX6dh7ju5xvJX5ZJUk7zQrN8o2KSD/1Q+gjxs2vWeqRd5 OjhTpyGLSJ6VjoRnnhafUCUD1zW9xYn3P4KfbeeWE6PmfxZHRPNvnTDyr1ogi0S4/SzsKA4 T+qnbDA+2AfZ2Ibz9yXfA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:i/zFNNOHHZQ=:3rdNnZ9hhUejLDDdqoz6xK PfXCeFFdA7So4o+BzIoZGufwgG16Z6+GJlpJwNTK/+M3gTbrfFnr7isi/9Q9emHs5QW/SXQtc owvdhlDX7FYqvG71hYv03YOOTN74ORgC41qF+yHpHo2qSj78RZHjyD//+OxqJCbjBKE2+JrTO OQLbyU0GEUaH0tmx8Bj4GQEKYi98+KKxLR6A1CTbIuPcuEcbFVGrMJWq80n0n8ndHPY/zzmH3 2OtBWyhToKIskPY9NdvrX0FKwVzgT8OdMWnxgr9uR/sFgOWGB6uhh9jwr0gnZAvLW1EfFs4vT a457bFdPw1ywVISrRNGoowSgpw1J4oTRK+4keaqJMyMz7fyRS+yTI4x8LfF6d7MmVKT8WHAJB iiBq0Y6Xr4Wbwt4WrY4gjqwFZdHxfzt084afa3/R9drNcZWIDd/FOcJCjFhh5zQCYh6mHgSU5 hg/Plp1blLy0kcExPchDVgV1gwcRrV1CtrpWdkCNE6zIic6PqCSy+wRxPABL0Kg+Al40rT834 /P+mb0D7gXR5o68IUsIHtoJYkC4bY2XzAmmCUKvmGb+vffBNOMGkoIf2R7GXrl0dszrUoPO7R Q2ie+ZeIwGg0sVIp2k23vP81sHrVlx/YXjeNRtnkcr74ywMA8kh68w9i++OyQmJsS5KcOp8zr NEp9A2KyXhqaxNC+q2bbd7kEkg4uTj5QKQ0rEqXfixLAD9R9PB2Wbi3HF3sQGnm598Gsi814v 8dWs1ed469VfQgmqRMPnjrIcPehDo1ivDMhYO3Cnyx6dOVl7CyQy0WhRlFjmwdQ2YDdwXyTT/ ZrQgMtUnimr3s1rC+gcODgAKX2EgJIHAjlWeifLHH2VrEx5G6mnwQbYiVtlAH/zLobu+W8uLV owxESstStZgvESQkCiOICt62+py+lMdmWq3+jjTIXiubOmChcAKVevlcv9dhsuQqira5bATWP QXPmrS+ouYPInRrsnvf5/ICoHgjR2N9A7gJMTRljG6VMcQ1YKHdtb X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Noam Postavsky writes: > +--- > +*** 'regexp' and new 'regexp-quote' accept arbirtray lisp as arguments. ^^^^^^^^^ (typo) Cool. I only wondered whether it wouldn't have been better if `eval' would have been upgraded - but that wouldn't be able to regexp-quote when I wanted it, right? Does it make sense to keep `eval'? There are so many rx-form types, would be good if we could make it obsolete (in some sense). Michael. From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 00:29:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Michael Heerdegen Cc: 36237@debbugs.gnu.org, stefan monnier , =?UTF-8?Q?k=C3=A9vin?= le gouguec Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.15606449139782 (code B ref 36237); Sun, 16 Jun 2019 00:29:01 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 00:28:33 +0000 Received: from localhost ([127.0.0.1]:39439 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcJ28-0002Xi-Oj for submit@debbugs.gnu.org; Sat, 15 Jun 2019 20:28:32 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:45702) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcJ27-0002XS-O2 for 36237@debbugs.gnu.org; Sat, 15 Jun 2019 20:28:32 -0400 Received: by mail-io1-f68.google.com with SMTP id e3so13678729ioc.12 for <36237@debbugs.gnu.org>; Sat, 15 Jun 2019 17:28:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=Ita9SJ51+aIlDV1mR1n10ORMDUGdST6uxNNbPBUpd9w=; b=R6LCmroa0FaSTGclqRUd6Y0sqNSsJmiiDjhs1eX6QaktpF7v/2Q69cOmthF0l7vMsO dRpVQlMvJcf6M5q8vv9OuFLRXhtKnBPdumjTSYFsuuKVkrI3fMqL/WpfVt9mBzpg1gif WZqo6tbCySbZoIx+bc25NulOXAOyhJxqv/jK5szsSvJGDZIlXsxinXPqqXw6EjP8bdvy a/yYZF7oUMV+sCo+OzGH8pAZ+9gk2kEYrgxRsI205Hjw3DFkIz4RICaGLlMqKLfZaup7 CznfmUtarcFGYlHTctxaP/u3xQBOXMpSlP9JminR62QxSOFsiOwpNy5kp6mhgy2aVp9I 9Mkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=Ita9SJ51+aIlDV1mR1n10ORMDUGdST6uxNNbPBUpd9w=; b=T0Qp1oFFIz13UtxLc3LliZB2HT1/YgN7Ud1XGSdsfd5qudoEcD3G2mwLr1NtUGZ2k1 SzddR/wPlxzWlgP0YdcnCJVBpTVEcpHBSa5Ytt+QZUsy6Cr3bIBp+JcRu7hvBUqf/huR 05wqcuOCKPI/P5asTqRhsuyLECNO4jTndsGS5NXkWSgtJgkG7Jib8ysUyeVJ5gxcDvJ/ fSgmkGUxjwiW3zOkDkxdSGooUbfhUTvbq/u5O1ycrUrGCJL0uXJjrOKrIxRfITuZFQkJ elrc7S7Mkj73uzHOPaJAMbBfYBhlp/tBklYH0cIbtz+0dLvPRjb6iNASy2t4BmIjOmqo FGvg== X-Gm-Message-State: APjAAAXQJC5Zzqxu6CXtOcbStN/0eqrZvJCCFiQWn9S0fC0CKazO5MZn U7CAlvb6erdsymDJpbPxpNU= X-Google-Smtp-Source: APXvYqyU+bn2Gta39VIxDCAGefqpQyDswkeY9M2Un32N0wJ0IXzEChQLMj9TPEHYfoTO6P9i9NXTRA== X-Received: by 2002:a6b:e315:: with SMTP id u21mr65585588ioc.14.1560644906203; Sat, 15 Jun 2019 17:28:26 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id i3sm9024551ion.9.2019.06.15.17.28.24 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Jun 2019 17:28:25 -0700 (PDT) From: Noam Postavsky References: <87v9x6xvml.fsf@gmail.com> <87r27u75wj.fsf@web.de> Date: Sat, 15 Jun 2019 20:28:24 -0400 In-Reply-To: <87r27u75wj.fsf@web.de> (Michael Heerdegen's message of "Sun, 16 Jun 2019 02:03:40 +0200") Message-ID: <87pnnextjr.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Michael Heerdegen writes: >> +*** 'regexp' and new 'regexp-quote' accept arbirtray lisp as arguments. > ^^^^^^^^^ (typo) Oops. > I only wondered whether it wouldn't have been better if `eval' would > have been upgraded (rx (eval EXPR)) vs (rx (regexp-quote EXPR)) have different semantics with respect to scoping and evaluation time, so I think that would be a problem with respect to backwards compatibility. > Does it make sense to keep `eval'? There are so many rx-form types, > would be good if we could make it obsolete (in some sense). Yeah, I think it would make sense to obsolete `eval'. Also `and': it sounds like it should be the logical-and counterpart to `or', but it's just a synonym for `seq' (which is a much clearer name). I used `and' in the bug title just for punning reasons :) From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) References: <87v9x6xvml.fsf@gmail.com> In-Reply-To: <87v9x6xvml.fsf@gmail.com> Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 10:05:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky , 36237@debbugs.gnu.org Cc: Michael Heerdegen , Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156067944214581 (code B ref 36237); Sun, 16 Jun 2019 10:05:01 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 10:04:02 +0000 Received: from localhost ([127.0.0.1]:39866 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcS13-0003n1-Ri for submit@debbugs.gnu.org; Sun, 16 Jun 2019 06:04:02 -0400 Received: from mail176c50.megamailservers.eu ([91.136.10.186]:56502 helo=mail37c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcS10-0003mc-Tx for 36237@debbugs.gnu.org; Sun, 16 Jun 2019 06:04:00 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1560679437; bh=SvgfuUas5lYwrlmIKRkgQltW8wnGMjCpXeOq48Hm37I=; h=From:Subject:Date:Cc:To:From; b=mYqdFiVKSxG3xJuhCDXJ6iTmyUBnqqlx+MZWpheD+fIJUAmDSZqd8G6hNeo4xZlQ9 VvKujc47jLE/aCwn0G3nFtai135ZyMaE0oNPiOE2aFs5xzeEkZtb6AxID7v1Y4dqce /Za8yHVP3Oo7kh1mizPBTSyG1buvwMPbyeXe9Z3Q= Feedback-ID: mattiase@acm.or Received: from [192.168.1.65] (c-e636e253.032-75-73746f71.bbcust.telenor.se [83.226.54.230]) (authenticated bits=0) by mail37c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x5GA3sqY006985; Sun, 16 Jun 2019 10:03:55 +0000 From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Message-Id: Date: Sun, 16 Jun 2019 12:03:53 +0200 X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0215.5D06140D.0010, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=ItQwjo3g c=1 sm=1 tr=0 a=M+GU/qJco4WXjv8D6jB2IA==:117 a=M+GU/qJco4WXjv8D6jB2IA==:17 a=kj9zAlcOel0A:10 a=6Cy7AnwH0rmqs1zlqdUA:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 0.3 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) Thank you! Definitely agree with the need for something like this, = although I haven't read the patch in detail yet. Some notes: - A more suitable name is needed; `regexp-quote' makes no sense at all = in the context of rx. What about `literal'? For simplicity, I'm = proceeding with that name below. - The docs probably need to be explicit about the differences between = `literal' and `eval' w.r.t. evaluation time and environment. - What is now the correct way of including a compile-time regexp = expression, such as a defconst? (regexp (eval-when-compile EXPR))? Still = a mouthful, but perhaps outside the scope of this bug. - Thanks for mentioning bug#14769; I'll give it a go. - I like rx a lot and use it extensively, but the implementation... = could be improved (as you no doubt noticed). And so I have: I'm sitting = on a full rewrite, code-named `ry'. It's shorter, much cleaner, and = about twice as fast (usually more). The only thing still missing is = compatibility with the old crusty `rx-constituents' extension mechanism. The plan was to replace rx with ry entirely when complete. I'll see what = it would take to add `literal'. From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 11:36:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Noam Postavsky , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.15606849037984 (code B ref 36237); Sun, 16 Jun 2019 11:36:02 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 11:35:03 +0000 Received: from localhost ([127.0.0.1]:39904 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcTR8-00024h-TM for submit@debbugs.gnu.org; Sun, 16 Jun 2019 07:35:03 -0400 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:10045) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcTR6-00024A-NP for 36237@debbugs.gnu.org; Sun, 16 Jun 2019 07:35:01 -0400 Received: from pmg3.iro.umontreal.ca (localhost [127.0.0.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id 363A4443957; Sun, 16 Jun 2019 07:34:54 -0400 (EDT) Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id E05C54401CA; Sun, 16 Jun 2019 07:34:52 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1560684892; bh=sJc4a+4DE5udg+JfmFD+XFHqpV7ViDS8dg37oLY086A=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=IoTRvzDcmOdJSc5nmYU4T+EWGVPua95H9pfOgI2R+68m1Zlv/tNEWWSyDbCTQDevp /ie8/F6xN0DFF388OvNSxgKM1UK2lgoOHLYfEJTJmtJ2cpMQiGhzsH6x7SqRjpYgAX E7qPlmk32IMxE0mjeau8ZAJ2ownD9G6TqeQ6yoFMmToA63BDmvUqO0yBm0t7BsG+J+ Wq/d4knTsRq0A/P0TPlvNWA+Z1NGNfdg9pgWtxHrOe9BwtQkB79QBsAzrCOjgqdd8z fSxaJFjo9MFsk0JWXv3jeGke9MwTFvbo8Pgr9gfK7uICUPIPyjwDchiB43STF9gGXj f1Ffp5/c49SmA== Received: from pastel (unknown [157.52.10.58]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 9E993120C60; Sun, 16 Jun 2019 07:34:52 -0400 (EDT) From: Stefan Monnier Message-ID: References: Date: Sun, 16 Jun 2019 07:34:49 -0400 In-Reply-To: ("Mattias \=\?windows-1252\?Q\?Engdeg\=E5rd\=22's\?\= message of "Sun, 16 Jun 2019 12:03:53 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain X-SPAM-LEVEL: X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) First, thanks Noam, this is a very welcome improvement. [ BTW, please use "--" for rx-compile-to-lisp since I believe it's internal. ] What do regexp and regexp-quote do in rx-to-string? > - A more suitable name is needed; `regexp-quote' makes no sense at all in > the context of rx. What about `literal'? For simplicity, I'm proceeding with > that name below. I'll let others figure that one out. > - What is now the correct way of including a compile-time regexp expression, > such as a defconst? (regexp (eval-when-compile EXPR))? Still a mouthful, but > perhaps outside the scope of this bug. FWIW, I have the impression that in most cases where this could be useful, a better solution would be to provide something like `rx-defmacro` and/or `rx-macrolet`. Stefan From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 12:27:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Stefan Monnier Cc: Michael Heerdegen , Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156068796213103 (code B ref 36237); Sun, 16 Jun 2019 12:27:02 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 12:26:02 +0000 Received: from localhost ([127.0.0.1]:39928 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcUET-0003PD-L9 for submit@debbugs.gnu.org; Sun, 16 Jun 2019 08:26:01 -0400 Received: from mail-io1-f43.google.com ([209.85.166.43]:40301) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcUER-0003Ov-Vc for 36237@debbugs.gnu.org; Sun, 16 Jun 2019 08:26:00 -0400 Received: by mail-io1-f43.google.com with SMTP id n5so15384403ioc.7 for <36237@debbugs.gnu.org>; Sun, 16 Jun 2019 05:25:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=QDkJABNnDIZVKpozS3iLmTxU3BIcq709QMWvspkmk+Y=; b=RkyYrp+NA7Y2OHLS/rjmCNJaegnhq5WIaKFhfkODCykRGiJFby9V1M4nbF3qQgdRBB P0aJAo33vEm9P1p7ATapN8hGSLh/f8s2AVtzBOt2l4/Yzr/Z1Q3wa/S2aizsa6Zmmpmr Ozzc1YTIh5l/3U/EXlNQRvn9qYgo6SbPaJLjZ+Mru2eaWcpuK76oPIXDL1VQosZ36bhj 6xE6OHVDkTwWYozmpM7YfK/jyaEfJByGbOkgQWk6p/h/8U6NqL1iXw9WpZRuzUibv0rE q0BI6+7ySxRYQpAtCAtH3/+7POARmzz2193fSJ0RFd5fOCITon+hcs6LTzYjVJm/pJI1 AGOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=QDkJABNnDIZVKpozS3iLmTxU3BIcq709QMWvspkmk+Y=; b=omeVhHM7YwuJINjnPNn/uAboKdiU//oOtRf0sNYt24v6PrBTK+dZISjECmqFEO8dzO U/jqloG5sTIOvuzPXBxt9UeCEjVUKrOaS+QdmSuKjwbquTbXoT6LQMdDo0rzJzATjIPe 9oILIqQq0WnhbG4+Y83/B2tGLnyLCzzI6TPLswV9bV9kaVDs64aI3ajYDkgDgLz3opeE 4AERlx3NK4ggZWRtB67WzJpdFbO4Bn8+h5ebsNTuRAq++dQddBD2Bop4LU3TqpVV/oFp 59W/LRiIIvtwVTY3/Pladxjip5Dn0EEBFTwYa1PpWzbiD9bTU+w1ZjhwYwNle+X6WaA1 0mOQ== X-Gm-Message-State: APjAAAWs/KhwxAJ/Z72R3wEB2pqwWmLFspN16giXLUksdoQtDppNJVSW sBjWcKNSwJ2TsHcW9Ds6LyM= X-Google-Smtp-Source: APXvYqxsawxXFX2gbpOA6qiGlOEI7mCFoPcFFBY3+4RVCILhDHGPZTIS5WzjC432qV4uTFVZNWIzsA== X-Received: by 2002:a5d:8759:: with SMTP id k25mr16300830iol.307.1560687951224; Sun, 16 Jun 2019 05:25:51 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id a1sm6825535ioo.5.2019.06.16.05.25.47 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 16 Jun 2019 05:25:48 -0700 (PDT) From: Noam Postavsky References: Date: Sun, 16 Jun 2019 08:25:46 -0400 In-Reply-To: (Stefan Monnier's message of "Sun, 16 Jun 2019 07:34:49 -0400") Message-ID: <87fto9yawl.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > [ BTW, please use "--" for rx-compile-to-lisp since I believe it's > internal. ] I'm not sure that it is, e.g., python-rx might bind it too (if it weren't for the fact that python.el needs to maintain backwards compatibility with older Emacs). > What do regexp and regexp-quote do in rx-to-string? regexp does exactly what it did before, i.e., it accepts only a constant string. Likewise regexp-quote accepts only a constant string, which makes it pointless to use in rx-to-string (just use a plain STRING directly), but I didn't disallow it. Hmm, I think I had meant to update rx-to-string's docstring, but forgot about it. >> - A more suitable name is needed; `regexp-quote' makes no sense at all in >> the context of rx. What about `literal'? For simplicity, I'm proceeding with >> that name below. > > I'll let others figure that one out. Probably `literal' makes sense. I originally used regexp-quote, just because I was thinking of it as a short form of (rx (regexp (regexp-quote EXPR))) >> - What is now the correct way of including a compile-time regexp expression, >> such as a defconst? (regexp (eval-when-compile EXPR))? Still a mouthful, but >> perhaps outside the scope of this bug. Oh, hmm. That might be a reason to keep using `eval'. > FWIW, I have the impression that in most cases where this could be > useful, a better solution would be to provide something like > `rx-defmacro` and/or `rx-macrolet`. I guess that could replace the "old crusty" rx-constituents thing too. >> I have: I'm sitting on a full rewrite, code-named `ry'. It's shorter, >> much cleaner, and about twice as fast (usually more). The only thing >> still missing is compatibility with the old crusty `rx-constituents' >> extension mechanism. >> >> The plan was to replace rx with ry entirely when complete. How far away is this? Would it make sense to delay this bug until "ry" comes in? From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 12:36:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky Cc: Michael Heerdegen , Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156068851714037 (code B ref 36237); Sun, 16 Jun 2019 12:36:01 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 12:35:17 +0000 Received: from localhost ([127.0.0.1]:39938 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcUNR-0003eL-0Q for submit@debbugs.gnu.org; Sun, 16 Jun 2019 08:35:17 -0400 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:55355) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcUNK-0003dz-LA for 36237@debbugs.gnu.org; Sun, 16 Jun 2019 08:35:15 -0400 Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id E36E6100C30; Sun, 16 Jun 2019 08:35:04 -0400 (EDT) Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id C881F100A32; Sun, 16 Jun 2019 08:35:03 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1560688503; bh=RgsX4Kkl/mGesuqEjZUOGZsdXHCJFNSpo7rDt36tbj4=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=fPSpIM2Q+8lvI29KPVutGnIR8fNQc1Vin+t0GJ0koo2ZWB7RCHk+8lCzVBK+N6k2F uLCWTs7ig3ca6zJ/ujnGRM9o4uYea3i9Cc/1Q+58DV+mDGs49V7CUzGY0zKnx4HG6k 0XulCigYoxuoyyOGR9DFGLnsQnXya9wCB3OW2lTmK9GdcE8GUMMloSXLRhzWj9Y4yR h7svdQ/l3qfZkcOtH/D2oYCI6GevJ6s+dcb3K6pCw0f2mKaJkspARNbsZcC+T44KvU CV+ew044c/b05nDwMI5PYh23dgsRfVstAwbvJBDE4z9WojmDiyf4G2/YO8dixoI1h0 2dHlFtP3UVY2Q== Received: from pastel (unknown [157.52.10.58]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 89AA812036E; Sun, 16 Jun 2019 08:35:03 -0400 (EDT) From: Stefan Monnier Message-ID: References: <87fto9yawl.fsf@gmail.com> Date: Sun, 16 Jun 2019 08:35:01 -0400 In-Reply-To: <87fto9yawl.fsf@gmail.com> (Noam Postavsky's message of "Sun, 16 Jun 2019 08:25:46 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain X-SPAM-LEVEL: X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > I'm not sure that it is, e.g., python-rx might bind it too (if it > weren't for the fact that python.el needs to maintain backwards > compatibility with older Emacs). I think that would still be "python-rx using internals of rx". And that could be fixed if we can rewrite it with rx-macrolet, right? > regexp does exactly what it did before, i.e., it accepts only a constant > string. Likewise regexp-quote accepts only a constant string, which > makes it pointless to use in rx-to-string (just use a plain STRING > directly), but I didn't disallow it. Good, thanks. >>> - What is now the correct way of including a compile-time regexp expression, >>> such as a defconst? (regexp (eval-when-compile EXPR))? Still a mouthful, but >>> perhaps outside the scope of this bug. > Oh, hmm. That might be a reason to keep using `eval'. It could make people reluctant to change, yes, but that still wouldn't be a valid reason in my book. >> FWIW, I have the impression that in most cases where this could be >> useful, a better solution would be to provide something like >> `rx-defmacro` and/or `rx-macrolet`. > I guess that could replace the "old crusty" rx-constituents thing too. That's the idea, yes. Stefan From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 19:52:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Stefan Monnier Cc: Michael Heerdegen , Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.15607146673763 (code B ref 36237); Sun, 16 Jun 2019 19:52:02 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 19:51:07 +0000 Received: from localhost ([127.0.0.1]:41509 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcbBC-0000yb-RJ for submit@debbugs.gnu.org; Sun, 16 Jun 2019 15:51:07 -0400 Received: from mail-io1-f49.google.com ([209.85.166.49]:34228) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcbBA-0000y1-PR for 36237@debbugs.gnu.org; Sun, 16 Jun 2019 15:51:05 -0400 Received: by mail-io1-f49.google.com with SMTP id k8so16846941iot.1 for <36237@debbugs.gnu.org>; Sun, 16 Jun 2019 12:51:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=VnLXtp6Tj+oNV4GxEZRrTjH7ABJp8x0kikRSVPuT1qY=; b=EW1NjiKjjldJ8NxyKlC43ZsXoYcPERAj3vs5TeWFXUjpjcCsC7XM0xHnH7kk+uhwh1 PFne+EoWdg0uxZvHVVbSlgxvN7IytP4F395cORm1JMuvYWAHXpOtuiKFJ0Q12mEVALfE wT+76GxUkYJVw9DZV6Wwb7NFFvXzVTjbYR1LYEvU21d0ltrggzH3d7nnBZUujvpQglyw vMhU+WiQwgvIqu1RrycR3myESFV0J9WHipjp2gLTma7QBqYqwXgxnkKUSI8utwDzuzME He85fm0edB8wn3VXsvWvAXV9mlKoXpPGPo7q4IwR1dCmFSq1Spxr0y/6jCk787ucnZh3 pLuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=VnLXtp6Tj+oNV4GxEZRrTjH7ABJp8x0kikRSVPuT1qY=; b=B/5FBd2Xxr5DrIMtQSoZ4BuWsXUej0/1vpQBQuh0/CycREjlVqzwhhh1zfoKqlTczJ J2K9CQrvLNvAuZDnX+/cw3Nbf02GaLiPZI19+DsSHvrwzXisshO5bnts2a7Kq5rmgGoA RY2r8N/Qyj97GSWq9FLBZvRQdleF6TyCSdoeeTAoKvv7mk/+xchXBDKmL/Peoj5eJEQ2 aoeAFWNMSnRC+k//XxWKnDBGdZpKqQ2ZCxsB4ERT1qNoZ1tQodBqCHpGN2rc7pJ5gYBR FXWkRgAtz1PpSawh0VLYtN3nkH9ryALhKGAk7U3qLIuLxmTm8p27r2mcoSm0lfHlNq6l Mygw== X-Gm-Message-State: APjAAAVwCowzXEkZOJ0GC5nLOOFQPjOv67xRYGFwGzD7s77lNl7DiTRw 374BD9//f6aG9lAKaC1DAXc= X-Google-Smtp-Source: APXvYqzuBZSdOX4ePR6wO1qiVCkLYy0MlTfaDx5lSNI1wWONb110f2ap0dD3v4yuoxOi9HNz05o0OQ== X-Received: by 2002:a02:a806:: with SMTP id f6mr82117767jaj.74.1560714659061; Sun, 16 Jun 2019 12:50:59 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id t133sm20165655iof.21.2019.06.16.12.50.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 16 Jun 2019 12:50:58 -0700 (PDT) From: Noam Postavsky References: <87fto9yawl.fsf@gmail.com> Date: Sun, 16 Jun 2019 15:50:57 -0400 In-Reply-To: (Stefan Monnier's message of "Sun, 16 Jun 2019 08:35:01 -0400") Message-ID: <87d0jdxqam.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Stefan Monnier writes: >> I'm not sure that it is, e.g., python-rx might bind it too (if it >> weren't for the fact that python.el needs to maintain backwards >> compatibility with older Emacs). > > I think that would still be "python-rx using internals of rx". > And that could be fixed if we can rewrite it with rx-macrolet, right? Yeah, I can buy that. Mattias, how far is this "ry" thing from being finished? Would it make sense to land it before adding this new feature? From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 20:06:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky Cc: Michael Heerdegen , Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.15607155175111 (code B ref 36237); Sun, 16 Jun 2019 20:06:01 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 20:05:17 +0000 Received: from localhost ([127.0.0.1]:41516 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcbOv-0001KN-72 for submit@debbugs.gnu.org; Sun, 16 Jun 2019 16:05:17 -0400 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:39542) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcbOt-0001Jz-GL for 36237@debbugs.gnu.org; Sun, 16 Jun 2019 16:05:16 -0400 Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id D2487100C30; Sun, 16 Jun 2019 16:05:08 -0400 (EDT) Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id D2E121009BB; Sun, 16 Jun 2019 16:05:07 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1560715507; bh=WxlMlx1HJqloBplHijqp3T2zdiecpTsqB1lhFZQZAGA=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=a+VYoYRJC0AVHZNK247Qaey7XEeZ0Lfz68QCWI9g0Xn3VpVJI8QPzyyq5CQoBwWLW qX1Kk9xbfjsMBc7847aT9xLSgOTIoEdxdwUBF0lWKkFN3WbwqypDsXqznPoB9Vsakh UBXK/o31Gll5VJbbLIeBXlCsYDgAsdqRX2MziB0Dw0rW2ScCnflm7U1N6N6NYcZ1Ea czc6CJfwFbFkDT1gRl1Lj5JnjMiC0Q/uEgJbBJTZ111c6hnXPI2uSV1u1auljMYK2v 9K5Hguzfre5jMlEPg3FWKlUj+To/aeMKlEZizOw+hir+g+aO8DYvIpVLlviZwxbCmt FrTbHEkLsamnw== Received: from alfajor (unknown [157.52.10.58]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 8F4C6120C79; Sun, 16 Jun 2019 16:05:07 -0400 (EDT) From: Stefan Monnier Message-ID: References: <87fto9yawl.fsf@gmail.com> <87d0jdxqam.fsf@gmail.com> Date: Sun, 16 Jun 2019 16:04:59 -0400 In-Reply-To: <87d0jdxqam.fsf@gmail.com> (Noam Postavsky's message of "Sun, 16 Jun 2019 15:50:57 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain X-SPAM-LEVEL: X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) >>> I'm not sure that it is, e.g., python-rx might bind it too (if it >>> weren't for the fact that python.el needs to maintain backwards >>> compatibility with older Emacs). >> I think that would still be "python-rx using internals of rx". >> And that could be fixed if we can rewrite it with rx-macrolet, right? > Yeah, I can buy that. In this case I think it's OK to use "--" to signal that it's an internal name, and then use this internal name in python-rx. Stefan From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Drew Adams Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 20:26:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky , Stefan Monnier Cc: Michael Heerdegen , Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156071671515461 (code B ref 36237); Sun, 16 Jun 2019 20:26:01 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 20:25:15 +0000 Received: from localhost ([127.0.0.1]:41537 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcbiE-00041I-Vk for submit@debbugs.gnu.org; Sun, 16 Jun 2019 16:25:15 -0400 Received: from userp2120.oracle.com ([156.151.31.85]:56948) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcbiC-00040x-QH for 36237@debbugs.gnu.org; Sun, 16 Jun 2019 16:25:13 -0400 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5GKJoWY169169; Sun, 16 Jun 2019 20:25:04 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=RKBFhhPB4xxpTMNKsZETdBW02Akc/Mi7bS8QRFGmt7E=; b=oaldtXW9ot3XHdCGNCpzKddrqrfHNbvc4E67H4lKf87kqjPGzwifw/ivbm8Qw0KrhZ+Z QFs/CBJ1SfXxuEcK5fxwjGWM+rt1GgpuKkEiOhGkn00Xk5SEGyWBPyW+eIercCt0lyub 0yrRAle/+KMOhPdK66KEYu/NUdSBbtfa9wV8rvclqfNYKaA0+47PXr+kLIzgWk+sbHVU /U3U1R0HB1zzfJYbbRTdlspn/ObnxpZRdDQO6uVuzmG5qOevaufKkTMn4NhsSPntqKwG grgoMOGAvUsjdNgD3nhey6Km6s1HcfOKIZ+CFbzutWcqO2BHsQczzdu0gqPBHLbk8nDl uw== Received: from userp3030.oracle.com (userp3030.oracle.com [156.151.31.80]) by userp2120.oracle.com with ESMTP id 2t4saq3cmx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 16 Jun 2019 20:25:04 +0000 Received: from pps.filterd (userp3030.oracle.com [127.0.0.1]) by userp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5GKNmeu179784; Sun, 16 Jun 2019 20:25:04 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userp3030.oracle.com with ESMTP id 2t59gcxhwf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 16 Jun 2019 20:25:04 +0000 Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x5GKP1cA032197; Sun, 16 Jun 2019 20:25:01 GMT MIME-Version: 1.0 Message-ID: <905e202e-4893-412d-aaf4-a03ec486d5e3@default> Date: Sun, 16 Jun 2019 13:25:00 -0700 (PDT) From: Drew Adams References: <87fto9yawl.fsf@gmail.com> <87d0jdxqam.fsf@gmail.com> In-Reply-To: <87d0jdxqam.fsf@gmail.com> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4861.0 (x86)] Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9290 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906160196 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9290 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906160196 X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > how far is this "ry" thing from being finished? Please excuse this interruption from someone not really following this thread. Naive question: Are you really thinking about using `ry' as the user-visible name - e.g. as a replacement for, or alternative to, `rx'? (Until Noam posed that question I was thinking it was tongue-in-cheek.) I kinda hope not (but again, I'm ignorant of the context). If this is meant to stand for a regexp thingie, and you want an alternative to `rx', please try for something that suggests "regexp" or "regular expression" - `rx2', `rex', `rgx', `rg' ... - something suggestive. (We've had 45+ years of `C' as the successor to `B'. Surely we can do better. ;-)) From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 20:35:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Drew Adams Cc: Michael Heerdegen , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com, Noam Postavsky , Stefan Monnier Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156071725716517 (code B ref 36237); Sun, 16 Jun 2019 20:35:02 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 20:34:17 +0000 Received: from localhost ([127.0.0.1]:41543 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcbqy-0004IL-Tz for submit@debbugs.gnu.org; Sun, 16 Jun 2019 16:34:17 -0400 Received: from mail174c50.megamailservers.eu ([91.136.10.184]:56348 helo=mail36c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hcbqw-0004I9-6h for 36237@debbugs.gnu.org; Sun, 16 Jun 2019 16:34:15 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1560717252; bh=xzIQUnjEP+emm6zrwwcTrEWTOhjEltz0O+GmQ7zBjw4=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=U8NeOVAB44X9Me+PMIrha5QcLVwI+/XO79OHBTpUQN50BhnjeFS0jFS/h2p/CxBda 3LpYJtkt4bnFjXew0/6soPJ5nnM0ubxZn+CHCEHKyW2YEECPkHn7EIu5Kr/D+6zQ8X iZ7aYAISqjka/lGjf8MUhSwcRteFT+RtCDO19QFE= Feedback-ID: mattiase@acm.or Received: from [192.168.1.65] (c-e636e253.032-75-73746f71.bbcust.telenor.se [83.226.54.230]) (authenticated bits=0) by mail36c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x5GKY9Go001542; Sun, 16 Jun 2019 20:34:11 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= X-Priority: 3 In-Reply-To: <905e202e-4893-412d-aaf4-a03ec486d5e3@default> Date: Sun, 16 Jun 2019 22:34:09 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: <1AD26B82-1ECC-47E6-8BF4-4BC3CECBABA5@acm.org> References: <87fto9yawl.fsf@gmail.com> <87d0jdxqam.fsf@gmail.com> <905e202e-4893-412d-aaf4-a03ec486d5e3@default> X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B020C.5D06A7C4.000D, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=Y+3WTCWN c=1 sm=1 tr=0 a=M+GU/qJco4WXjv8D6jB2IA==:117 a=M+GU/qJco4WXjv8D6jB2IA==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=yPCof4ZbAAAA:8 a=uhhc41DGNRJV5ARftVYA:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 0.3 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) 16 juni 2019 kl. 22.25 skrev Drew Adams : >=20 >> how far is this "ry" thing from being finished? Not far, I hope. A few days, maybe, depending on available time. > Are you really thinking about using `ry' as the > user-visible name - e.g. as a replacement for, > or alternative to, `rx'? No, it's just a working title, to avoid clashes with the current rx. It = will be renamed to `rx' when done. From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Drew Adams Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2019 21:11:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com, Noam Postavsky , Stefan Monnier Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156071940820215 (code B ref 36237); Sun, 16 Jun 2019 21:11:01 +0000 Received: (at 36237) by debbugs.gnu.org; 16 Jun 2019 21:10:08 +0000 Received: from localhost ([127.0.0.1]:41576 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hccPg-0005Fz-J3 for submit@debbugs.gnu.org; Sun, 16 Jun 2019 17:10:08 -0400 Received: from userp2120.oracle.com ([156.151.31.85]:58456) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hccPf-0005FW-AG for 36237@debbugs.gnu.org; Sun, 16 Jun 2019 17:10:07 -0400 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5GL9tiM196505; Sun, 16 Jun 2019 21:09:59 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=Hg0v+iPJ+Vol2eGYZ8dGDaXcvV8Jt1ChlqV1FIv32GI=; b=GrWjSU663XHtAsSAK86UQvDSrhGXjrr5OF0oTZwHiqGW4pLKv/FPp44qLAfklZpblvrL UJLgRlhk5ZsMaSiW/K6niAw3ZF18o5OCZYUcGzn4cWqn3XQchUsTPtXIj9ZmPaVaZ3PT ui/nSC/YUFDRs70mpRnQIYK6VXJEsIfoT+5Slz7jV5MhnKSJqzDfu5SE0XWXKQX5LwSI W6f/7pDnTuM+7fPXr8cagbYk4yWf4LXZL55JfTzJsLEiMu9Td4aoa1hi49hzT+dC1Zsv PGOKtTm04fRZNoSAy1pQkmC/Wpzo4lDqtUn6kxCOeZucP/Kys4M1Ve25LqLPNEhVlkSL 2g== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by userp2120.oracle.com with ESMTP id 2t4saq3drd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 16 Jun 2019 21:09:59 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5GL97DP157637; Sun, 16 Jun 2019 21:09:58 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserp3030.oracle.com with ESMTP id 2t5cpd5s40-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 16 Jun 2019 21:09:58 +0000 Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x5GL9rHZ022015; Sun, 16 Jun 2019 21:09:54 GMT MIME-Version: 1.0 Message-ID: <5c99134a-d9a3-4c40-b415-c15d321ac91a@default> Date: Sun, 16 Jun 2019 14:09:52 -0700 (PDT) From: Drew Adams References: <87fto9yawl.fsf@gmail.com> <87d0jdxqam.fsf@gmail.com> <905e202e-4893-412d-aaf4-a03ec486d5e3@default> <1AD26B82-1ECC-47E6-8BF4-4BC3CECBABA5@acm.org> In-Reply-To: <1AD26B82-1ECC-47E6-8BF4-4BC3CECBABA5@acm.org> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4861.0 (x86)] Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9290 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=787 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906160203 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9290 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=839 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906160203 X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > > Are you really thinking about using `ry' as the > > user-visible name - e.g. as a replacement for, > > or alternative to, `rx'? >=20 > No, it's just a working title, to avoid clashes with the current rx. It > will be renamed to `rx' when done. Great; thx. Sorry for the noise. From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Juri Linkov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 17 Jun 2019 22:14:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Drew Adams Cc: Michael Heerdegen , Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= , Noam Postavsky , Stefan Monnier , kevin.legouguec@gmail.com, 36237@debbugs.gnu.org Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156080959626367 (code B ref 36237); Mon, 17 Jun 2019 22:14:02 +0000 Received: (at 36237) by debbugs.gnu.org; 17 Jun 2019 22:13:16 +0000 Received: from localhost ([127.0.0.1]:43418 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hczsK-0006rD-Hn for submit@debbugs.gnu.org; Mon, 17 Jun 2019 18:13:16 -0400 Received: from bongo.elm.relay.mailchannels.net ([23.83.212.21]:39762) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hczsF-0006qo-ND for 36237@debbugs.gnu.org; Mon, 17 Jun 2019 18:13:14 -0400 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id C9B8F5E1CAA; Mon, 17 Jun 2019 22:13:10 +0000 (UTC) Received: from pdx1-sub0-mail-a9.g.dreamhost.com (100-96-89-88.trex.outbound.svc.cluster.local [100.96.89.88]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id D1EE05E17F4; Mon, 17 Jun 2019 22:13:09 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Received: from pdx1-sub0-mail-a9.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.17.2); Mon, 17 Jun 2019 22:13:10 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Supply-Snatch: 13f5e29e70e7d6c7_1560809590618_2741534224 X-MC-Loop-Signature: 1560809590618:2679834716 X-MC-Ingress-Time: 1560809590617 Received: from pdx1-sub0-mail-a9.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a9.g.dreamhost.com (Postfix) with ESMTP id C17A283C5D; Mon, 17 Jun 2019 15:13:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=linkov.net; bh=lUyelIC5h9n0qS6JSnk1SE0cor0=; b= 1oX/3Cu/atsd0La+zlfpXsO6j+jJAZB4SQrlbUfZOnRCLnbcrDAHCkIFOxtvuNXa OHrf6eXp1u+4RSQHy0U63DGk9px2pgW17ISiIjdgTwlksIs8ECfUo4p1wsYZLvqx cI1A/oqXbg+drEh8iORdwFnp7W4MttX9C785yDzbQyM= Received: from mail.jurta.org (m91-129-109-209.cust.tele2.ee [91.129.109.209]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a9.g.dreamhost.com (Postfix) with ESMTPSA id DBFD083C9A; Mon, 17 Jun 2019 15:12:57 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a9 From: Juri Linkov Organization: LINKOV.NET References: <87fto9yawl.fsf@gmail.com> <87d0jdxqam.fsf@gmail.com> <905e202e-4893-412d-aaf4-a03ec486d5e3@default> Date: Mon, 17 Jun 2019 23:57:53 +0300 In-Reply-To: <905e202e-4893-412d-aaf4-a03ec486d5e3@default> (Drew Adams's message of "Sun, 16 Jun 2019 13:25:00 -0700 (PDT)") Message-ID: <87zhmgdk9j.fsf@mail.linkov.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeduuddrudeikedgtdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuggftfghnshhusghstghrihgsvgdpffftgfetoffjqffuvfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufhofhffjgfkfgggtgesthdtredttdertdenucfhrhhomheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqeenucfkphepledurdduvdelrddutdelrddvtdelnecurfgrrhgrmhepmhhouggvpehsmhhtphdphhgvlhhopehmrghilhdrjhhurhhtrgdrohhrghdpihhnvghtpeeluddruddvledruddtledrvddtledprhgvthhurhhnqdhprghthheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqedpmhgrihhlfhhrohhmpehjuhhriheslhhinhhkohhvrdhnvghtpdhnrhgtphhtthhopegurhgvfidrrggurghmshesohhrrggtlhgvrdgtohhmnecuvehluhhsthgvrhfuihiivgeptd X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > I kinda hope not (but again, I'm ignorant of the > context). If this is meant to stand for a regexp > thingie, and you want an alternative to `rx', > please try for something that suggests "regexp" > or "regular expression" - `rx2', `rex', `rgx', > `rg' ... - something suggestive. > > (We've had 45+ years of `C' as the successor to > `B'. Surely we can do better. ;-)) rx++ From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 18 Jun 2019 19:47:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156088716726543 (code B ref 36237); Tue, 18 Jun 2019 19:47:01 +0000 Received: (at 36237) by debbugs.gnu.org; 18 Jun 2019 19:46:07 +0000 Received: from localhost ([127.0.0.1]:45643 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdK3S-0006u2-G2 for submit@debbugs.gnu.org; Tue, 18 Jun 2019 15:46:07 -0400 Received: from mail211c50.megamailservers.eu ([91.136.10.221]:35784 helo=mail194c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdK3P-0006tG-47 for 36237@debbugs.gnu.org; Tue, 18 Jun 2019 15:46:04 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1560887160; bh=MLz5JpYEymNrBa09YmIz4fHXck+/ZgGj04CJlbrRIcQ=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=bOgRtBthLO46mw6pTOgpwBg4STUbjT4yt4H2lbLn93JjcLLB+igDOIEZJgyLh6Scy 8r9KuVaIMzpHFjD6EKc4Xi+xTYje75slDZ0TyPYHR6nz+Z5FXNzLvpBoWS6olEeNyB l/T2lDRJiy4/Qw1l9MqEWKp9sSQbfAhLf+hHI1cE= Feedback-ID: mattiase@acm.or Received: from [192.168.1.65] (c-e636e253.032-75-73746f71.bbcust.telenor.se [83.226.54.230]) (authenticated bits=0) by mail194c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x5IJjweo018931; Tue, 18 Jun 2019 19:46:00 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: <87fto9yawl.fsf@gmail.com> Date: Tue, 18 Jun 2019 21:45:57 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> References: <87fto9yawl.fsf@gmail.com> X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B020B.5D093F78.0044, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=OuZhNR3t c=1 sm=1 tr=0 a=M+GU/qJco4WXjv8D6jB2IA==:117 a=M+GU/qJco4WXjv8D6jB2IA==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=pGLkceISAAAA:8 a=M9u8WbzkAAAA:20 a=pNNhlyHfwFR-6d7Vh-8A:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) 16 juni 2019 kl. 14.25 skrev Noam Postavsky : >>> The plan was to replace rx with ry entirely when complete. >=20 > How far away is this? Would it make sense to delay this bug until = "ry" > comes in? The function-complete ry has been put at https://gitlab.com/mattiase/ry = for the time being. It should now be entirely compatible, including = support for `rx-constituents'. Your proposed `literal' was also added, = which was instructive; I needed to know how it would fit in. Bootstrapping Emacs with it (ry renamed to rx, of course) works, = including python-mode which uses `rx-constituents' for extension. It = also has fewer of the known bugs of the current rx, and a much more = extensive test suite. There are two things that perhaps need to be resolved before replacing = the current rx: 1. Is there externally developed elisp code that makes use of internal = rx functions and variables, perhaps for extension purposes, and do we = need to worry about breaking it? The code is old enough not to delineate = internal and public symbols clearly (no double-dash), which means that = people may have gone and used all sort of things. 2. What would a good extension mechanism look like, and should one be = put into place right away, so that we can point to a decent replacement = for the internal toys that users relied upon? Noam, unless the consensus is that ry is unequivocally as good or better = than rx, you could just as well apply your patch (suitably fixed up). = Even if later replaced, there is nothing fundamentally wrong with the = design; let's not hold it hostage. From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 19 Jun 2019 01:36:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156090810529201 (code B ref 36237); Wed, 19 Jun 2019 01:36:02 +0000 Received: (at 36237) by debbugs.gnu.org; 19 Jun 2019 01:35:05 +0000 Received: from localhost ([127.0.0.1]:45783 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdPVA-0007au-BJ for submit@debbugs.gnu.org; Tue, 18 Jun 2019 21:35:05 -0400 Received: from mail-io1-f42.google.com ([209.85.166.42]:42900) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdPV5-0007Zq-TD for 36237@debbugs.gnu.org; Tue, 18 Jun 2019 21:35:01 -0400 Received: by mail-io1-f42.google.com with SMTP id u19so34325555ior.9 for <36237@debbugs.gnu.org>; Tue, 18 Jun 2019 18:34:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=3ZhsfTttj4HD3gHmzwl7ibVG9vRy7qkIUcJciPnldmQ=; b=nZsp+OzSTd64zA9M0H1ZlBijJuXs5hVy5u8lLJ44DeHv9HsISXJggbgACct0QbuwCR PZfcEKcJ5oo9Db/YgennNymi/ZhUN0zH15wlmHf/6xPlFhFuoAIL803NxpRlk4fAcTzc 90K7TXc1Oo2XPJIs6VsBy9mil+GX0XfASFJ6oBZlVcdQ3TrECwZ073/XzIAYYALuK250 +2gY1EweISS0MiPO8qM8ywF8P5SRM7u3YixsA0XR2u1lR9scve6gsW/MC+4XbTCY2g+q uuksed51J7IFOKTxLXRkpLOYvvIQpIrJJrtPeIN58KHsNbqH/WzIf5mx4cWFzVNqtrXi 1MOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=3ZhsfTttj4HD3gHmzwl7ibVG9vRy7qkIUcJciPnldmQ=; b=MfcgnP5/UwYxIZ4uaEZ0bmab+VSb4JbPcRsMtl3UK7MG9tnwaHEGXGBjvn3WJ8ZpnU zzARWJK1jJ54Zu98lLJd0O3wFjHZKDs8xMIlJvccTbsnpjM7k1Ec4cyerjBVsYJI+WMC DQ5xdmS8p7Kzqh0TNcYxc3BEM7EsPLT+28WntT0V85wSV41cmklPDz4RclGtY6dGuHvv EazAL5xPRfkIf8nngH9jEHUdm+Vs1VNWN73xHj3hllLcmC+VIpTiwHPWhCqNYY3hJZJM e6WCslob7AvfcmdRCdr5e4bgaz46reAC6Xj1ZmFCpqw01Tj+yI9s+M0YnTiWCNe5liRE s+aw== X-Gm-Message-State: APjAAAUT26QkiTXdwujlC/NVFEWIBp9gLib8VrbNE5j5pkZXnqp+M3W/ mlsCKbKbjpFj4aAYgDzP34Q= X-Google-Smtp-Source: APXvYqyDuX5BuZ/JNIQ2dmoUBiTrBhBfktxVeYwAaI3SrRFYhLLmhQHXOPXjGqf7/XLalW1qvG8ImA== X-Received: by 2002:a02:b78a:: with SMTP id f10mr6960925jam.5.1560908094200; Tue, 18 Jun 2019 18:34:54 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id s6sm12025594ioo.31.2019.06.18.18.34.52 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 18 Jun 2019 18:34:53 -0700 (PDT) From: Noam Postavsky References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> Date: Tue, 18 Jun 2019 21:34:52 -0400 In-Reply-To: <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> ("Mattias \=\?utf-8\?Q\?Engdeg\=C3\=A5rd\=22's\?\= message of "Tue, 18 Jun 2019 21:45:57 +0200") Message-ID: <87tvcmwe6b.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mattias Engdeg=C3=A5rd writes: > The function-complete ry has been put at > https://gitlab.com/mattiase/ry for the time being. It should now be > entirely compatible, including support for `rx-constituents'. Your > proposed `literal' was also added, which was instructive; I needed to > know how it would fit in. Cool, I'll take a look. > Noam, unless the consensus is that ry is unequivocally as good or > better than rx, you could just as well apply your patch (suitably > fixed up). Even if later replaced, there is nothing fundamentally > wrong with the design; let's not hold it hostage. Sure. Here's the patch with regexp-quote change to literal, and rx--compile-to-lisp renamed. I'll wait a bit more and push this weekend if there are no more comments. --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=0001-Support-rx-and-regexp-EXPR-literal-EXPR-Bug-36237.patch Content-Description: patch >From 3302374b4b484e64d234084661cbf710807bfbe1 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Fri, 14 Jun 2019 08:43:17 -0400 Subject: [PATCH] Support (rx (and (regexp EXPR) (literal EXPR))) (Bug#36237) * lisp/emacs-lisp/rx.el (rx-regexp): Allow non-string forms. (rx-constituents): Add literal constituent, which is like a plain STRING form, but allows arbitrary lisp expressions. (rx-literal): New function. (rx-compile-to-lisp): New variable. (rx-subforms): New helper function for handling subforms, including non-constant case. (rx-group-if, rx-and, rx-or, rx-=, rx->=, rx-repeat, rx-submatch) (rx-submatch-n, rx-kleene, rx-atomic-p): Use it to handle non-constant subforms. (rx): Document new form, wrap non-constant forms with concat call. * test/lisp/emacs-lisp/rx-tests.el (rx-tests--match): New macro. (rx-nonstring-expr, rx-nonstring-expr-non-greedy): New tests. * etc/NEWS: Announce changes. --- etc/NEWS | 6 ++ lisp/emacs-lisp/rx.el | 188 ++++++++++++++++++++++++++------------- test/lisp/emacs-lisp/rx-tests.el | 41 +++++++++ 3 files changed, 172 insertions(+), 63 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 723f0a0fb0..42958bca36 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1380,12 +1380,18 @@ when given in a string. Previously, '(any "\x80-\xff")' would match characters U+0080...U+00FF. Now the expression matches raw bytes in the 128...255 range, as expected. +--- *** The rx 'or' and 'seq' forms no longer require any arguments. (or) produces a regexp that never matches anything, while (seq) matches the empty string, each being an identity for the operation. This also works for their aliases: '|' for 'or'; ':', 'and' and 'sequence' for 'seq'. +--- +*** 'regexp' and new 'literal' accept arbitrary lisp as arguments. +In this case, 'rx' will generate code which produces a regexp string +at runtime, instead of a constant string. + ** Frames +++ diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 8ef78fd69e..c925cc4415 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -47,9 +47,11 @@ ;; Rx translates a sexp notation for regular expressions into the ;; usual string notation. The translation can be done at compile-time -;; by using the `rx' macro. It can be done at run-time by calling -;; function `rx-to-string'. See the documentation of `rx' for a -;; complete description of the sexp notation. +;; by using the `rx' macro. The `regexp' and `literal' forms accept +;; non-constant expressions, in which case `rx' will translate to a +;; `concat' expression. Translation can be done fully at run-time by +;; calling function `rx-to-string'. See the documentation of `rx' for +;; a complete description of the sexp notation. ;; ;; Some examples of string regexps and their sexp counterparts: ;; @@ -78,8 +80,8 @@ ;; (+ (? ?\n)) (any " \t")) ;; ;; (concat "^\\(?:" something-else "\\)") -;; (rx (and line-start (eval something-else))), statically or -;; (rx-to-string '(and line-start ,something-else)), dynamically. +;; (rx (and line-start (regexp something-else))), statically or +;; (rx-to-string `(and line-start ,something-else)), dynamically. ;; ;; (regexp-opt '(STRING1 STRING2 ...)) ;; (rx (or STRING1 STRING2 ...)), or in other words, `or' automatically @@ -176,6 +178,7 @@ (defvar rx-constituents ;Not `const' because some modes extend it. (not-syntax . (rx-not-syntax 1 1)) ; sregex (category . (rx-category 1 1 rx-check-category)) (eval . (rx-eval 1 1)) + (literal . (rx-literal 1 1 stringp)) (regexp . (rx-regexp 1 1 stringp)) (regex . regexp) ; sregex (digit . "[[:digit:]]") @@ -302,6 +305,10 @@ (defvar rx-greedy-flag t "Non-nil means produce greedy regular expressions for `zero-or-one', `zero-or-more', and `one-or-more'. Dynamically bound.") +(defvar rx--compile-to-lisp nil + "Nil means return a regexp as a string. +Non-nil means we may return a lisp form which produces a +string (used for `rx' macro).") (defun rx-info (op head) "Return parsing/code generation info for OP. @@ -344,7 +351,7 @@ (defun rx-check (form) (> nargs max-args)) (error "rx form `%s' accepts at most %d args" (car form) max-args)) - (when (not (null type-pred)) + (when type-pred (dolist (sub-form (cdr form)) (unless (funcall type-pred sub-form) (error "rx form `%s' requires args satisfying `%s'" @@ -360,8 +367,9 @@ (defun rx-group-if (regexp group) ;; for concatenation ((eq group ':) (if (rx-atomic-p - (if (string-match - "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp) + (if (and (stringp regexp) + (string-match + "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp)) (substring regexp 0 (match-beginning 0)) regexp)) (setq group nil))) @@ -370,9 +378,10 @@ (defun rx-group-if (regexp group) ;; do anyway ((eq group t)) ((rx-atomic-p regexp t) (setq group nil))) - (if group - (concat "\\(?:" regexp "\\)") - regexp)) + (cond ((and group (stringp regexp)) + (concat "\\(?:" regexp "\\)")) + (group `("\\(?:" ,@regexp "\\)")) + (t regexp))) (defvar rx-parent) @@ -384,7 +393,7 @@ (defun rx-and (form) FORM is of the form `(and FORM1 ...)'." (rx-check form) (rx-group-if - (mapconcat (lambda (x) (rx-form x ':)) (cdr form) nil) + (rx-subforms (cdr form) ':) (and (memq rx-parent '(* t)) rx-parent))) @@ -396,7 +405,7 @@ (defun rx-or (form) ((null (cdr form)) regexp-unmatchable) ((cl-every #'stringp (cdr form)) (regexp-opt (cdr form) nil t)) - (t (mapconcat (lambda (x) (rx-form x '|)) (cdr form) "\\|"))) + (t (rx-subforms (cdr form) '| "\\|"))) (and (memq rx-parent '(: * t)) rx-parent))) @@ -669,7 +678,10 @@ (defun rx-= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `=' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) (defun rx->= (form) @@ -679,7 +691,10 @@ (defun rx->= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `>=' requires positive integer first arg")) - (format "%s\\{%d,\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d,\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d,\\}" (nth 1 form)))))) (defun rx-** (form) @@ -700,7 +715,10 @@ (defun rx-repeat (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `repeat' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) ((or (not (integerp (nth 2 form))) (< (nth 2 form) 0) (not (integerp (nth 1 form))) @@ -708,30 +726,26 @@ (defun rx-repeat (form) (< (nth 2 form) (nth 1 form))) (error "rx `repeat' range error")) (t - (format "%s\\{%d,%d\\}" (rx-form (nth 3 form) '*) - (nth 1 form) (nth 2 form))))) + (let ((subform (rx-form (nth 3 form) '*))) + (if (stringp subform) + (format "%s\\{%d,%d\\}" subform (nth 1 form) (nth 2 form)) + `(,@subform ,(format "\\{%d,%d\\}" (nth 1 form) (nth 2 form)))))))) (defun rx-submatch (form) "Parse and produce code from FORM, which is `(submatch ...)'." - (concat "\\(" - (if (= 2 (length form)) - ;; Only one sub-form. - (rx-form (cadr form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cdr form) nil)) - "\\)")) + (let ((subforms (rx-subforms (cdr form) ':))) + (if (stringp subforms) + (concat "\\(" subforms "\\)") + `("\\(" ,@subforms "\\)")))) (defun rx-submatch-n (form) "Parse and produce code from FORM, which is `(submatch-n N ...)'." - (let ((n (nth 1 form))) - (concat "\\(?" (number-to-string n) ":" - (if (= 3 (length form)) - ;; Only one sub-form. - (rx-form (nth 2 form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cddr form) nil)) - "\\)"))) + (let ((n (nth 1 form)) + (subforms (rx-subforms (cddr form) ':))) + (if (stringp subforms) + (concat "\\(?" (number-to-string n) ":" subforms "\\)") + `("\\(?" ,(number-to-string n) ":" ,@subforms "\\)")))) (defun rx-backref (form) "Parse and produce code from FORM, which is `(backref N)'." @@ -759,9 +773,12 @@ (defun rx-kleene (form) (t "?"))) (op (cond ((memq (car form) '(* *? 0+ zero-or-more)) "*") ((memq (car form) '(+ +? 1+ one-or-more)) "+") - (t "?")))) + (t "?"))) + (subform (rx-form (cadr form) '*))) (rx-group-if - (concat (rx-form (cadr form) '*) op suffix) + (if (stringp subform) + (concat subform op suffix) + `(,@subform ,(concat op suffix))) (and (memq rx-parent '(t *)) rx-parent)))) @@ -789,15 +806,18 @@ (defun rx-atomic-p (r &optional lax) be detected without much effort. A guarantee of no false negatives would require a theoretic specification of the set of all atomic regexps." - (let ((l (length r))) - (cond - ((<= l 1)) - ((= l 2) (= (aref r 0) ?\\)) - ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) - ((null lax) + (if (and rx--compile-to-lisp + (not (stringp r))) + nil ;; Runtime value, we must assume non-atomic. + (let ((l (length r))) (cond - ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) - ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r))))))) + ((<= l 1)) + ((= l 2) (= (aref r 0) ?\\)) + ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) + ((null lax) + (cond + ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) + ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r)))))))) (defun rx-syntax (form) @@ -853,9 +873,23 @@ (defun rx-greedy (form) (defun rx-regexp (form) "Parse and produce code from FORM, which is `(regexp STRING)'." - (rx-check form) - (rx-group-if (cadr form) rx-parent)) - + (cond ((stringp form) + (rx-group-if (cadr form) rx-parent)) + (rx--compile-to-lisp + ;; Always group non string forms, since we can't be sure they + ;; are atomic. + (rx-group-if (cdr form) t)) + (t (rx-check form)))) + +(defun rx-literal (form) + "Parse and produce code from FORM, which is `(literal STRING-EXP)'." + (cond ((stringp form) + ;; This is allowed(?), but makes little sense, you could just + ;; use STRING directly. + (rx-group-if (regexp-quote (cadr form)) rx-parent)) + (rx--compile-to-lisp + (rx-group-if `((regexp-quote ,(cadr form))) rx-parent)) + (t (rx-check form)))) (defun rx-form (form &optional parent) "Parse and produce code for regular expression FORM. @@ -886,12 +920,36 @@ (defun rx-form (form &optional parent) (t (error "rx syntax error at `%s'" form))))) +(defun rx-subforms (subforms &optional parent regexp-op) + (let ((listify (lambda (x) + (if (listp x) (copy-sequence x) + (list x)))) + (subregexps (cond ((cdr subforms) + (mapcar (lambda (x) (rx-form x parent)) subforms)) + (subforms + ;; Single form, no need for grouping. + (list (rx-form (car subforms)))) + ;; Zero forms. + (t "")))) + (cond ((or (not rx--compile-to-lisp) + (cl-every #'stringp subregexps)) + (mapconcat #'identity subregexps regexp-op)) + (regexp-op + (nconc (funcall listify (car subregexps)) + (cl-mapcan (lambda (x) + (cons regexp-op (funcall listify x))) + (cdr subregexps)))) + (t (cl-mapcan listify subregexps))))) + ;;;###autoload (defun rx-to-string (form &optional no-group) "Parse and produce code for regular expression FORM. FORM is a regular expression in sexp form. -NO-GROUP non-nil means don't put shy groups around the result." +NO-GROUP non-nil means don't put shy groups around the result. +Note that unlike for the `rx' macro, subforms `literal' and +`regexp' will not accept non-string arguments (so (literal +STRING) becomes just a more verbose version of STRING)." (rx-group-if (rx-form form) (null no-group))) @@ -901,8 +959,12 @@ (defmacro rx (&rest regexps) REGEXPS is a non-empty sequence of forms of the sort listed below. Note that `rx' is a Lisp macro; when used in a Lisp program being -compiled, the translation is performed by the compiler. -See `rx-to-string' for how to do such a translation at run-time. +compiled, the translation is performed by the compiler. The +`literal' and `regexp' forms accept subforms that will evaluate +to strings, in addition to constant strings. If REGEXPS include +such forms, then the result is an expression which returns a +regexp string, rather than a regexp string directly. See +`rx-to-string' for performing translation completely at run-time. The following are valid subforms of regular expressions in sexp notation. @@ -910,6 +972,10 @@ (defmacro rx (&rest regexps) STRING matches string STRING literally. +`(literal STRING)' + matches STRING literally, where STRING is any lisp + expression that evaluates to a string. + CHAR matches character CHAR literally. @@ -1208,12 +1274,16 @@ (defmacro rx (&rest regexps) `(regexp REGEXP)' include REGEXP in string notation in the result." - (cond ((null regexps) - (error "No regexp")) - ((cdr regexps) - (rx-to-string `(and ,@regexps) t)) - (t - (rx-to-string (car regexps) t)))) + (let* ((rx--compile-to-lisp t) + (re (cond ((null regexps) + (error "No regexp")) + ((cdr regexps) + (rx-to-string `(and ,@regexps) t)) + (t + (rx-to-string (car regexps) t))))) + (if (stringp re) + re + `(concat ,@re)))) (pcase-defmacro rx (&rest regexps) @@ -1275,14 +1345,6 @@ (pcase-defmacro rx (&rest regexps) for var in vars collect `(app (match-string ,i) ,var))))) -;; ;; sregex.el replacement - -;; ;;;###autoload (provide 'sregex) -;; ;;;###autoload (autoload 'sregex "rx") -;; (defalias 'sregex 'rx-to-string) -;; ;;;###autoload (autoload 'sregexq "rx" nil nil 'macro) -;; (defalias 'sregexq 'rx) - (provide 'rx) ;;; rx.el ends here diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 6f392d616d..bab71b522b 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -115,5 +115,46 @@ (ert-deftest rx-seq () ;; Test zero-argument `seq'. (should (equal (rx (seq)) ""))) +(defmacro rx-tests--match (regexp string &optional match) + (macroexp-let2 nil strexp string + `(ert-info ((format "Matching %S to %S" ',regexp ,strexp)) + (should (string-match ,regexp ,strexp)) + ,@(when match + `((should (equal (match-string 0 ,strexp) ,match))))))) + +(ert-deftest rx-nonstring-expr () + (let ((bee "b") + (vowel "[aeiou]")) + (rx-tests--match (rx "a" (literal bee) "c") "abc") + (rx-tests--match (rx "a" (regexp bee) "c") "abc") + (rx-tests--match (rx "a" (or (regexp bee) "xy") "c") "abc") + (rx-tests--match (rx "a" (or "xy" (regexp bee)) "c") "abc") + (should-not (string-match (rx (or (regexp bee) "xy")) "")) + (rx-tests--match (rx "a" (= 3 (regexp bee)) "c") "abbbc") + (rx-tests--match (rx "x" (= 3 (regexp vowel)) "z") "xeoez") + (should-not (string-match (rx "x" (= 3 (regexp vowel)) "z") "xe[]z")) + (rx-tests--match (rx "x" (= 3 (literal vowel)) "z") + "x[aeiou][aeiou][aeiou]z") + (rx-tests--match (rx "x" (repeat 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xauz") + (rx-tests--match (rx "x" (>= 1 (regexp vowel)) "z") "xaiiz") + (rx-tests--match (rx "x" (** 1 2 (regexp vowel)) "z") "xaiz") + (rx-tests--match (rx "x" (group (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (group-n 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (? (regexp vowel)) "z") "xz"))) + +(ert-deftest rx-nonstring-expr-non-greedy () + "`rx's greediness can't affect runtime regexp parts." + (let ((ad-min "[ad]*?") + (ad-max "[ad]*") + (ad "[ad]")) + (rx-tests--match (rx "c" (regexp ad-min) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (regexp ad-max) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (minimal-match (regexp ad-max)) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (maximal-match (regexp ad-min)) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (minimal-match (0+ (regexp ad))) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (maximal-match (0+ (regexp ad))) "a") "cdaaada" "cdaaada"))) + (provide 'rx-tests) ;; rx-tests.el ends here. -- 2.11.0 --=-=-=-- From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 19 Jun 2019 15:44:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.15609589871355 (code B ref 36237); Wed, 19 Jun 2019 15:44:01 +0000 Received: (at 36237) by debbugs.gnu.org; 19 Jun 2019 15:43:07 +0000 Received: from localhost ([127.0.0.1]:47299 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdcjr-0000Lm-88 for submit@debbugs.gnu.org; Wed, 19 Jun 2019 11:43:07 -0400 Received: from mail205c50.megamailservers.eu ([91.136.10.215]:38888 helo=mail193c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdcjo-0000Lc-7C for 36237@debbugs.gnu.org; Wed, 19 Jun 2019 11:43:05 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1560958982; bh=KmUS+Z7B7iIAseU+7W1Rn2r5W+XLorZBbRhgDkc6GC8=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=lKpGjaUHzgLTA9+iGV7gmTHBALowCkA0c37hvYUiGl7tyYYIgkqDCrhVYVxCN65uU E5ZdB0M5l8BaxLPtY3ZkD7REJMU1R6wMDdW0FpJ64K6l4Ri57ZxXToYCnlYdCSYM4X wymxcIl+dZ7MJkjkAXHaLL2WBj1dbxxCLJjmfwxw= Feedback-ID: mattiase@acm.or Received: from [192.168.1.65] (c-e636e253.032-75-73746f71.bbcust.telenor.se [83.226.54.230]) (authenticated bits=0) by mail193c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x5JFgwI5007396; Wed, 19 Jun 2019 15:42:59 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: <87tvcmwe6b.fsf@gmail.com> Date: Wed, 19 Jun 2019 17:42:57 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0213.5D0A5806.0038, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=PM8hB8iC c=1 sm=1 tr=0 a=M+GU/qJco4WXjv8D6jB2IA==:117 a=M+GU/qJco4WXjv8D6jB2IA==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=pGLkceISAAAA:8 a=Z_9CyQLO4t7mDJ5I03IA:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) 19 juni 2019 kl. 03.34 skrev Noam Postavsky : >=20 > Sure. Here's the patch with regexp-quote change to literal, and > rx--compile-to-lisp renamed. I'll wait a bit more and push this = weekend > if there are no more comments. Thank you. Some comments: -;; (rx (and line-start (eval something-else))), statically or -;; (rx-to-string '(and line-start ,something-else)), dynamically. +;; (rx (and line-start (regexp something-else))), statically or +;; (rx-to-string `(and line-start ,something-else)), dynamically. With your patch, the rx-to-string example should no longer be = recommended, but eval is still of interest for compile-time = substitution. What about: ;; (rx (and line-start (eval something-else))), statically or ;; (rx (and line-start (regexp something-else))), dynamically. (extra points if you change `and' into `seq') + (cond ((stringp form) + (rx-group-if (cadr form) rx-parent)) + (rx--compile-to-lisp + ;; Always group non string forms, since we can't be sure they "non-string forms" +(defun rx-literal (form) + "Parse and produce code from FORM, which is `(literal STRING-EXP)'." + (cond ((stringp form) + ;; This is allowed(?), but makes little sense, you could just + ;; use STRING directly. Yes, I did the same in ry. Maybe `literal' should be disallowed entirely = in rx-to-string, since it's more likely to be a misunderstanding on the = user's part. =20 +(defun rx-subforms (subforms &optional parent regexp-op) REGEXP-OP is perhaps better named SEPARATOR? + (cl-mapcan (lambda (x) + (cons regexp-op (funcall listify x))) + (cdr subregexps)))) + (t (cl-mapcan listify subregexps))))) Any reason for using cl-mapcan instead of straight mapcan? Not that it matters much. +NO-GROUP non-nil means don't put shy groups around the result. +Note that unlike for the `rx' macro, subforms `literal' and +`regexp' will not accept non-string arguments (so (literal +STRING) becomes just a more verbose version of STRING)." Try not breaking the line inside (literal STRING). From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 20 Jun 2019 00:30:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156099059612609 (code B ref 36237); Thu, 20 Jun 2019 00:30:02 +0000 Received: (at 36237) by debbugs.gnu.org; 20 Jun 2019 00:29:56 +0000 Received: from localhost ([127.0.0.1]:47607 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdkxf-0003HI-6b for submit@debbugs.gnu.org; Wed, 19 Jun 2019 20:29:56 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:44047) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hdkxc-0003H2-3o for 36237@debbugs.gnu.org; Wed, 19 Jun 2019 20:29:53 -0400 Received: by mail-io1-f65.google.com with SMTP id s7so758196iob.11 for <36237@debbugs.gnu.org>; Wed, 19 Jun 2019 17:29:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=rcisLlVVrxNWymEQ/n4frtvh4SnS+wFJ4JEyH9aTLJo=; b=NJeRWOm5wmhQ54QiDbsp3BiZg7I+4+CYFGmgKZEbmELR9bzgUsnB8BBFQQXilmRfJJ 3TCem7jeyoXuodQ/iVe8sBp6XjoDpT4PiOsk/ceWJSmX8yM2deemVHB8vr8/5I1+Wlhu FJZuK9Ii0pGBdNNz7yhrpJjajtpW+VgpXarzDkXffKKqzBJSvOdq3oJFcpkSUxeR8+tU GflI1d2f335DLXBbhHdx+NH+sMTdyk5JCMN1tAygKnreZUw4XOTwDoq0yhyYOJQwEZf6 HvAQ2jTcY0mUA8DmxmTacz6fN99hY2nDHAZPLuDrLFUMP54GjgmNaGtSnMPP7Vx8JFyW v1Kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=rcisLlVVrxNWymEQ/n4frtvh4SnS+wFJ4JEyH9aTLJo=; b=dIaUmS8FNVURgnMVgedzLr2ggL/3MuddF0Vez+kVMo8y0ZV1OzfxFz9FdS6KyU+rFY CSRAX9BsKMGRwTdqCJ20BSq/AFd40n+93xFL/z9LREo+vSFlNrPNk2KZspu2XN6A+y65 hgYY22J2kUikVE61dEyOBRQz1bo4Nlo0DUALaXtfgjBkZNxrJl2Sbh8xOdsYTwMnThLg Q385zOEFHgUr0YMRpf+xzKmzFeXTiRFcIY78RR1M6lLJkGso/R5ZaQleLWKmdfGouGeX MUn3y7akVith9w25I1Q0WtSo43puLR5be8UBs0wvSG1xzCOiW3yX/al5vaFyHhTVZ33y s60w== X-Gm-Message-State: APjAAAVsU2+nq2OoqElcOO/jjZw2nuyheKn6EKIQoPLNHHARXdJnCSfJ F1NkLVqjlkYywV0SC7v45rc= X-Google-Smtp-Source: APXvYqzW0ZxwE+oYRZERodMno/5iDdggAQUOwfiQSg2sitzehVzYG2OSGhwQ2R/2liuXdEriYWWHcw== X-Received: by 2002:a6b:ee15:: with SMTP id i21mr2330270ioh.281.1560990586495; Wed, 19 Jun 2019 17:29:46 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id 15sm21268932ioe.46.2019.06.19.17.29.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 19 Jun 2019 17:29:45 -0700 (PDT) From: Noam Postavsky References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> Date: Wed, 19 Jun 2019 20:29:44 -0400 In-Reply-To: ("Mattias \=\?utf-8\?Q\?Engdeg\=C3\=A5rd\=22's\?\= message of "Wed, 19 Jun 2019 17:42:57 +0200") Message-ID: <87o92tw13b.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mattias Engdeg=C3=A5rd writes: > +;; (rx (and line-start (regexp something-else))), statically or > +;; (rx-to-string `(and line-start ,something-else)), dynamically. > > With your patch, the rx-to-string example should no longer be > recommended, but eval is still of interest for compile-time > substitution. What about: > > ;; (rx (and line-start (eval something-else))), statically or > ;; (rx (and line-start (regexp something-else))), dynamically. Not sure that we really want to get into the subtleties of static eval in the intro examples. I'm thinking we just drop the rx-to-string example, without replacement. > + ;; Always group non string forms, since we can't be sure they > > "non-string forms" Right. > +(defun rx-literal (form) > + "Parse and produce code from FORM, which is `(literal STRING-EXP)'." > + (cond ((stringp form) > + ;; This is allowed(?), but makes little sense, you could just > + ;; use STRING directly. > > Yes, I did the same in ry. Maybe `literal' should be disallowed > entirely in rx-to-string, since it's more likely to be a > misunderstanding on the user's part. I think disallowing it could potentially be annoying during development, e.g., building incrementally in re-builder. > +(defun rx-subforms (subforms &optional parent regexp-op) > > REGEXP-OP is perhaps better named SEPARATOR? Yeah, especially since it's just the one "\\|" operator. > + (cl-mapcan (lambda (x) > + (cons regexp-op (funcall listify x))) > + (cdr subregexps)))) > + (t (cl-mapcan listify subregexps))))) > > Any reason for using cl-mapcan instead of straight mapcan? > Not that it matters much. I, um, didn't realize mapcan was builtin (when I saw mapcan elsewhere I just assumed it was from cl.el). In my defence, it's new since 26.1 :p (In addition to the above two points, I've renamed this function to rx--subforms, and re-arranged the code a bit) > +`regexp' will not accept non-string arguments (so (literal > +STRING) becomes just a more verbose version of STRING)." > > Try not breaking the line inside (literal STRING). Right. --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=0001-Support-rx-and-regexp-EXPR-literal-EXPR-Bug-36237.patch Content-Description: patch >From 6351f9d8ac0ff5643b849f2c8e3eb44ea1641fc5 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Fri, 14 Jun 2019 08:43:17 -0400 Subject: [PATCH] Support (rx (and (regexp EXPR) (literal EXPR))) (Bug#36237) * lisp/emacs-lisp/rx.el (rx-regexp): Allow non-string forms. (rx-constituents): Add literal constituent, which is like a plain STRING form, but allows arbitrary lisp expressions. (rx-literal): New function. (rx-compile-to-lisp): New variable. (rx--subforms): New helper function for handling subforms, including non-constant case. (rx-group-if, rx-and, rx-or, rx-=, rx->=, rx-repeat, rx-submatch) (rx-submatch-n, rx-kleene, rx-atomic-p): Use it to handle non-constant subforms. (rx): Document new form, wrap non-constant forms with concat call. * test/lisp/emacs-lisp/rx-tests.el (rx-tests--match): New macro. (rx-nonstring-expr, rx-nonstring-expr-non-greedy): New tests. * etc/NEWS: Announce changes. --- etc/NEWS | 6 ++ lisp/emacs-lisp/rx.el | 189 ++++++++++++++++++++++++++------------- test/lisp/emacs-lisp/rx-tests.el | 41 +++++++++ 3 files changed, 173 insertions(+), 63 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 723f0a0fb0..42958bca36 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1380,12 +1380,18 @@ when given in a string. Previously, '(any "\x80-\xff")' would match characters U+0080...U+00FF. Now the expression matches raw bytes in the 128...255 range, as expected. +--- *** The rx 'or' and 'seq' forms no longer require any arguments. (or) produces a regexp that never matches anything, while (seq) matches the empty string, each being an identity for the operation. This also works for their aliases: '|' for 'or'; ':', 'and' and 'sequence' for 'seq'. +--- +*** 'regexp' and new 'literal' accept arbitrary lisp as arguments. +In this case, 'rx' will generate code which produces a regexp string +at runtime, instead of a constant string. + ** Frames +++ diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 8ef78fd69e..12e33aaded 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -47,9 +47,11 @@ ;; Rx translates a sexp notation for regular expressions into the ;; usual string notation. The translation can be done at compile-time -;; by using the `rx' macro. It can be done at run-time by calling -;; function `rx-to-string'. See the documentation of `rx' for a -;; complete description of the sexp notation. +;; by using the `rx' macro. The `regexp' and `literal' forms accept +;; non-constant expressions, in which case `rx' will translate to a +;; `concat' expression. Translation can be done fully at run-time by +;; calling function `rx-to-string'. See the documentation of `rx' for +;; a complete description of the sexp notation. ;; ;; Some examples of string regexps and their sexp counterparts: ;; @@ -78,8 +80,7 @@ ;; (+ (? ?\n)) (any " \t")) ;; ;; (concat "^\\(?:" something-else "\\)") -;; (rx (and line-start (eval something-else))), statically or -;; (rx-to-string '(and line-start ,something-else)), dynamically. +;; (rx (seq line-start (regexp something-else))) ;; ;; (regexp-opt '(STRING1 STRING2 ...)) ;; (rx (or STRING1 STRING2 ...)), or in other words, `or' automatically @@ -176,6 +177,7 @@ (defvar rx-constituents ;Not `const' because some modes extend it. (not-syntax . (rx-not-syntax 1 1)) ; sregex (category . (rx-category 1 1 rx-check-category)) (eval . (rx-eval 1 1)) + (literal . (rx-literal 1 1 stringp)) (regexp . (rx-regexp 1 1 stringp)) (regex . regexp) ; sregex (digit . "[[:digit:]]") @@ -302,6 +304,10 @@ (defvar rx-greedy-flag t "Non-nil means produce greedy regular expressions for `zero-or-one', `zero-or-more', and `one-or-more'. Dynamically bound.") +(defvar rx--compile-to-lisp nil + "Nil means return a regexp as a string. +Non-nil means we may return a lisp form which produces a +string (used for `rx' macro).") (defun rx-info (op head) "Return parsing/code generation info for OP. @@ -344,7 +350,7 @@ (defun rx-check (form) (> nargs max-args)) (error "rx form `%s' accepts at most %d args" (car form) max-args)) - (when (not (null type-pred)) + (when type-pred (dolist (sub-form (cdr form)) (unless (funcall type-pred sub-form) (error "rx form `%s' requires args satisfying `%s'" @@ -360,8 +366,9 @@ (defun rx-group-if (regexp group) ;; for concatenation ((eq group ':) (if (rx-atomic-p - (if (string-match - "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp) + (if (and (stringp regexp) + (string-match + "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp)) (substring regexp 0 (match-beginning 0)) regexp)) (setq group nil))) @@ -370,9 +377,10 @@ (defun rx-group-if (regexp group) ;; do anyway ((eq group t)) ((rx-atomic-p regexp t) (setq group nil))) - (if group - (concat "\\(?:" regexp "\\)") - regexp)) + (cond ((and group (stringp regexp)) + (concat "\\(?:" regexp "\\)")) + (group `("\\(?:" ,@regexp "\\)")) + (t regexp))) (defvar rx-parent) @@ -384,7 +392,7 @@ (defun rx-and (form) FORM is of the form `(and FORM1 ...)'." (rx-check form) (rx-group-if - (mapconcat (lambda (x) (rx-form x ':)) (cdr form) nil) + (rx--subforms (cdr form) ':) (and (memq rx-parent '(* t)) rx-parent))) @@ -396,7 +404,7 @@ (defun rx-or (form) ((null (cdr form)) regexp-unmatchable) ((cl-every #'stringp (cdr form)) (regexp-opt (cdr form) nil t)) - (t (mapconcat (lambda (x) (rx-form x '|)) (cdr form) "\\|"))) + (t (rx--subforms (cdr form) '| "\\|"))) (and (memq rx-parent '(: * t)) rx-parent))) @@ -669,7 +677,10 @@ (defun rx-= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `=' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) (defun rx->= (form) @@ -679,7 +690,10 @@ (defun rx->= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `>=' requires positive integer first arg")) - (format "%s\\{%d,\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d,\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d,\\}" (nth 1 form)))))) (defun rx-** (form) @@ -700,7 +714,10 @@ (defun rx-repeat (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `repeat' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) ((or (not (integerp (nth 2 form))) (< (nth 2 form) 0) (not (integerp (nth 1 form))) @@ -708,30 +725,26 @@ (defun rx-repeat (form) (< (nth 2 form) (nth 1 form))) (error "rx `repeat' range error")) (t - (format "%s\\{%d,%d\\}" (rx-form (nth 3 form) '*) - (nth 1 form) (nth 2 form))))) + (let ((subform (rx-form (nth 3 form) '*))) + (if (stringp subform) + (format "%s\\{%d,%d\\}" subform (nth 1 form) (nth 2 form)) + `(,@subform ,(format "\\{%d,%d\\}" (nth 1 form) (nth 2 form)))))))) (defun rx-submatch (form) "Parse and produce code from FORM, which is `(submatch ...)'." - (concat "\\(" - (if (= 2 (length form)) - ;; Only one sub-form. - (rx-form (cadr form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cdr form) nil)) - "\\)")) + (let ((subforms (rx--subforms (cdr form) ':))) + (if (stringp subforms) + (concat "\\(" subforms "\\)") + `("\\(" ,@subforms "\\)")))) (defun rx-submatch-n (form) "Parse and produce code from FORM, which is `(submatch-n N ...)'." - (let ((n (nth 1 form))) - (concat "\\(?" (number-to-string n) ":" - (if (= 3 (length form)) - ;; Only one sub-form. - (rx-form (nth 2 form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cddr form) nil)) - "\\)"))) + (let ((n (nth 1 form)) + (subforms (rx--subforms (cddr form) ':))) + (if (stringp subforms) + (concat "\\(?" (number-to-string n) ":" subforms "\\)") + `("\\(?" ,(number-to-string n) ":" ,@subforms "\\)")))) (defun rx-backref (form) "Parse and produce code from FORM, which is `(backref N)'." @@ -759,9 +772,12 @@ (defun rx-kleene (form) (t "?"))) (op (cond ((memq (car form) '(* *? 0+ zero-or-more)) "*") ((memq (car form) '(+ +? 1+ one-or-more)) "+") - (t "?")))) + (t "?"))) + (subform (rx-form (cadr form) '*))) (rx-group-if - (concat (rx-form (cadr form) '*) op suffix) + (if (stringp subform) + (concat subform op suffix) + `(,@subform ,(concat op suffix))) (and (memq rx-parent '(t *)) rx-parent)))) @@ -789,15 +805,18 @@ (defun rx-atomic-p (r &optional lax) be detected without much effort. A guarantee of no false negatives would require a theoretic specification of the set of all atomic regexps." - (let ((l (length r))) - (cond - ((<= l 1)) - ((= l 2) (= (aref r 0) ?\\)) - ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) - ((null lax) + (if (and rx--compile-to-lisp + (not (stringp r))) + nil ;; Runtime value, we must assume non-atomic. + (let ((l (length r))) (cond - ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) - ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r))))))) + ((<= l 1)) + ((= l 2) (= (aref r 0) ?\\)) + ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) + ((null lax) + (cond + ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) + ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r)))))))) (defun rx-syntax (form) @@ -853,9 +872,23 @@ (defun rx-greedy (form) (defun rx-regexp (form) "Parse and produce code from FORM, which is `(regexp STRING)'." - (rx-check form) - (rx-group-if (cadr form) rx-parent)) - + (cond ((stringp form) + (rx-group-if (cadr form) rx-parent)) + (rx--compile-to-lisp + ;; Always group non-string forms, since we can't be sure they + ;; are atomic. + (rx-group-if (cdr form) t)) + (t (rx-check form)))) + +(defun rx-literal (form) + "Parse and produce code from FORM, which is `(literal STRING-EXP)'." + (cond ((stringp form) + ;; This is allowed, but makes little sense, you could just + ;; use STRING directly. + (rx-group-if (regexp-quote (cadr form)) rx-parent)) + (rx--compile-to-lisp + (rx-group-if `((regexp-quote ,(cadr form))) rx-parent)) + (t (rx-check form)))) (defun rx-form (form &optional parent) "Parse and produce code for regular expression FORM. @@ -886,12 +919,38 @@ (defun rx-form (form &optional parent) (t (error "rx syntax error at `%s'" form))))) +(defun rx--subforms (subforms &optional parent separator) + "Produce code for regular expressions SUBFORMS. +SUBFORMS is a list of regular expression sexps. +PARENT controls grouping, as in `rx-form'. +Insert SEPARATOR between the code from each of SUBFORMS." + (if (null (cdr subforms)) + ;; Zero or one forms, no need for grouping. + (and subforms (rx-form (car subforms))) + (let ((listify (lambda (x) + (if (listp x) (copy-sequence x) + (list x))))) + (setq subforms (mapcar (lambda (x) (rx-form x parent)) subforms)) + (cond ((or (not rx--compile-to-lisp) + (cl-every #'stringp subforms)) + (mapconcat #'identity subforms separator)) + (separator + (nconc (funcall listify (car subforms)) + (mapcan (lambda (x) + (cons separator (funcall listify x))) + (cdr subforms)))) + (t (mapcan listify subforms)))))) + ;;;###autoload (defun rx-to-string (form &optional no-group) "Parse and produce code for regular expression FORM. FORM is a regular expression in sexp form. -NO-GROUP non-nil means don't put shy groups around the result." +NO-GROUP non-nil means don't put shy groups around the result. + +In contrast to the `rx' macro, subforms `literal' and `regexp' +will not accept non-string arguments, i.e., (literal STRING) +becomes just a more verbose version of STRING." (rx-group-if (rx-form form) (null no-group))) @@ -901,8 +960,12 @@ (defmacro rx (&rest regexps) REGEXPS is a non-empty sequence of forms of the sort listed below. Note that `rx' is a Lisp macro; when used in a Lisp program being -compiled, the translation is performed by the compiler. -See `rx-to-string' for how to do such a translation at run-time. +compiled, the translation is performed by the compiler. The +`literal' and `regexp' forms accept subforms that will evaluate +to strings, in addition to constant strings. If REGEXPS include +such forms, then the result is an expression which returns a +regexp string, rather than a regexp string directly. See +`rx-to-string' for performing translation completely at run-time. The following are valid subforms of regular expressions in sexp notation. @@ -910,6 +973,10 @@ (defmacro rx (&rest regexps) STRING matches string STRING literally. +`(literal STRING)' + matches STRING literally, where STRING is any lisp + expression that evaluates to a string. + CHAR matches character CHAR literally. @@ -1208,12 +1275,16 @@ (defmacro rx (&rest regexps) `(regexp REGEXP)' include REGEXP in string notation in the result." - (cond ((null regexps) - (error "No regexp")) - ((cdr regexps) - (rx-to-string `(and ,@regexps) t)) - (t - (rx-to-string (car regexps) t)))) + (let* ((rx--compile-to-lisp t) + (re (cond ((null regexps) + (error "No regexp")) + ((cdr regexps) + (rx-to-string `(and ,@regexps) t)) + (t + (rx-to-string (car regexps) t))))) + (if (stringp re) + re + `(concat ,@re)))) (pcase-defmacro rx (&rest regexps) @@ -1275,14 +1346,6 @@ (pcase-defmacro rx (&rest regexps) for var in vars collect `(app (match-string ,i) ,var))))) -;; ;; sregex.el replacement - -;; ;;;###autoload (provide 'sregex) -;; ;;;###autoload (autoload 'sregex "rx") -;; (defalias 'sregex 'rx-to-string) -;; ;;;###autoload (autoload 'sregexq "rx" nil nil 'macro) -;; (defalias 'sregexq 'rx) - (provide 'rx) ;;; rx.el ends here diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 6f392d616d..bab71b522b 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -115,5 +115,46 @@ (ert-deftest rx-seq () ;; Test zero-argument `seq'. (should (equal (rx (seq)) ""))) +(defmacro rx-tests--match (regexp string &optional match) + (macroexp-let2 nil strexp string + `(ert-info ((format "Matching %S to %S" ',regexp ,strexp)) + (should (string-match ,regexp ,strexp)) + ,@(when match + `((should (equal (match-string 0 ,strexp) ,match))))))) + +(ert-deftest rx-nonstring-expr () + (let ((bee "b") + (vowel "[aeiou]")) + (rx-tests--match (rx "a" (literal bee) "c") "abc") + (rx-tests--match (rx "a" (regexp bee) "c") "abc") + (rx-tests--match (rx "a" (or (regexp bee) "xy") "c") "abc") + (rx-tests--match (rx "a" (or "xy" (regexp bee)) "c") "abc") + (should-not (string-match (rx (or (regexp bee) "xy")) "")) + (rx-tests--match (rx "a" (= 3 (regexp bee)) "c") "abbbc") + (rx-tests--match (rx "x" (= 3 (regexp vowel)) "z") "xeoez") + (should-not (string-match (rx "x" (= 3 (regexp vowel)) "z") "xe[]z")) + (rx-tests--match (rx "x" (= 3 (literal vowel)) "z") + "x[aeiou][aeiou][aeiou]z") + (rx-tests--match (rx "x" (repeat 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xauz") + (rx-tests--match (rx "x" (>= 1 (regexp vowel)) "z") "xaiiz") + (rx-tests--match (rx "x" (** 1 2 (regexp vowel)) "z") "xaiz") + (rx-tests--match (rx "x" (group (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (group-n 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (? (regexp vowel)) "z") "xz"))) + +(ert-deftest rx-nonstring-expr-non-greedy () + "`rx's greediness can't affect runtime regexp parts." + (let ((ad-min "[ad]*?") + (ad-max "[ad]*") + (ad "[ad]")) + (rx-tests--match (rx "c" (regexp ad-min) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (regexp ad-max) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (minimal-match (regexp ad-max)) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (maximal-match (regexp ad-min)) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (minimal-match (0+ (regexp ad))) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (maximal-match (0+ (regexp ad))) "a") "cdaaada" "cdaaada"))) + (provide 'rx-tests) ;; rx-tests.el ends here. -- 2.11.0 --=-=-=-- From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 20 Jun 2019 10:27:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156102639826750 (code B ref 36237); Thu, 20 Jun 2019 10:27:01 +0000 Received: (at 36237) by debbugs.gnu.org; 20 Jun 2019 10:26:38 +0000 Received: from localhost ([127.0.0.1]:47907 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hduH7-0006xN-Pl for submit@debbugs.gnu.org; Thu, 20 Jun 2019 06:26:38 -0400 Received: from mail1426c50.megamailservers.eu ([91.136.14.26]:34976 helo=mail102c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hduH3-0006x6-Fa for 36237@debbugs.gnu.org; Thu, 20 Jun 2019 06:26:35 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1561026386; bh=uVZhj6yncd5qOH1lgDPk+g6oSRu2ziB8XJ2+5lcK3U8=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=CKAY2ut1j4b6qTeggDx/rpVk4ajci3HmJjx+4lOZWdtQFReJP435jTT765VBQ7Ip9 mPwC5vpuNQYbMvEm+ANtTZBskPqFgQW1crLnswVBZ/vKk8U/0eaoJO0/swmgCTACW3 Dt8t8sEs3/lg6UOyqIoXQUjqYeoKORyZsjWbnHq0= Feedback-ID: mattiase@acm.or Received: from [192.168.1.65] (c-e636e253.032-75-73746f71.bbcust.telenor.se [83.226.54.230]) (authenticated bits=0) by mail102c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x5KAQMYP004969; Thu, 20 Jun 2019 10:26:23 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: <87o92tw13b.fsf@gmail.com> Date: Thu, 20 Jun 2019 12:26:21 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0206.5D0B5F52.004A, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=F7x5iJpN c=1 sm=1 tr=0 a=M+GU/qJco4WXjv8D6jB2IA==:117 a=M+GU/qJco4WXjv8D6jB2IA==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=pGLkceISAAAA:8 a=Td0tSAp4GFf4f10Xf_8A:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) 20 juni 2019 kl. 02.29 skrev Noam Postavsky : >=20 > <0001-Support-rx-and-regexp-EXPR-literal-EXPR-Bug-36237.patch> Things I didn't notice earlier: -;; (rx (and line-start (eval something-else))), statically or -;; (rx-to-string '(and line-start ,something-else)), dynamically. +;; (rx (seq line-start (regexp something-else))) You can actually drop the `seq' form entirely, since it's implicit in = `rx'. It was only needed for `rx-to-string' which is now gone. +`(literal STRING)' + matches STRING literally, where STRING is any lisp + expression that evaluates to a string. It's better to name the metavariable EXPR, STRING-EXPR or LISP-EXPR to = make it clear that it's an arbitrary lisp expression, especially since = STRING is used for a constant string just above. The same goes for `regexp', since it can now be a lisp expression; this = should be mentioned in the describing paragraph, using a similar = phrasing. The `literal' item should probably be moved next to `regexp', = since they are closely related. The paragraph on `eval' uses FORM, which is too generic; presumably it = should become EXPR too (but not STRING-EXPR, since it can be any rx = value). From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 22 Jun 2019 22:07:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156124117025028 (code B ref 36237); Sat, 22 Jun 2019 22:07:01 +0000 Received: (at 36237) by debbugs.gnu.org; 22 Jun 2019 22:06:10 +0000 Received: from localhost ([127.0.0.1]:52624 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1heo9B-0006Vc-2r for submit@debbugs.gnu.org; Sat, 22 Jun 2019 18:06:09 -0400 Received: from mail-io1-f44.google.com ([209.85.166.44]:33908) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1heo98-0006V4-8s for 36237@debbugs.gnu.org; Sat, 22 Jun 2019 18:06:07 -0400 Received: by mail-io1-f44.google.com with SMTP id k8so23608iot.1 for <36237@debbugs.gnu.org>; Sat, 22 Jun 2019 15:06:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=+9lctW79u6hxQa8juAnnKGkzAH/IQCIRwX3daB1MQ1c=; b=XJ2sezFiS+UolIFrsazbStTV9mC/Jhl4zZfpL3DlSZFARZwVsN/p16zQ6W7iMYqH+3 ldSko6MF6HgRFHzXnWRS1TPG2VyzvjtK4ha4CI4vy5LQvwr+I+lP3sXr5v2C/StxICwR 7zgdn3gw5VfA+C6QM1NdEheLq/0mgnmWEKUhFWMBpTy+msvMCsO5paIllupOQHgRNdkZ ZbF6avxis2Z0xMphrD8bA7UeHpwNQytJZi+V+zG5GcPZrcQ2zQgum4h4zeWt9OG9FtGm 9zKU4t/AAq7I/OSBK3hi36KUWUDY6rfHJ8/lxkQa+GMezoC8OdSL4Nipx3vt7iL6k8j6 20rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=+9lctW79u6hxQa8juAnnKGkzAH/IQCIRwX3daB1MQ1c=; b=S0olWEvCfwtbomtEZQHPMcBR4KIfWZh0ZeLjyTWsS7swZYW4uX06LG9mJh0A0Z5tbx JN11mEVOOb4ShZbAvJH7r8OA+VSJ5dFgnt46NPk7SlUMoYYIReCwng2rT0UT/adf0Jk6 JU0NKa6Y6oJ8B3mNjI0YwCkFdYuuqscFi0rorYVRWDirVdvgzs9LocgTk07fdjPKaldi I5BoZa9ykfigtyBVH2p/wdYb+RJl08GsnWY/oFvhoG2rhQXg2cCZ4LF9gAHz7ZtLkihZ 2OJ3G1ciuIKe0MXckxtJjJabYt4VAOOvKSKu1SrNXwk91krVoXla3NTIHXvVMUhABATP /b/A== X-Gm-Message-State: APjAAAXL4V2qG3IsjFmCDDxTkiQnv9c/wNi6gPSXwT7g8SdcAiIVxscp 5/gpHo+0PAebVN1X/0iwiGQ= X-Google-Smtp-Source: APXvYqwRVGLUVddX5nFuIi12XzILAaGssRqy9P8i6aAF+VzwSz07MPiTV21ST4u+DitvVBwah3aWLA== X-Received: by 2002:a5d:9c46:: with SMTP id 6mr1944997iof.6.1561241160641; Sat, 22 Jun 2019 15:06:00 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id p25sm8599389iol.48.2019.06.22.15.05.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 22 Jun 2019 15:05:59 -0700 (PDT) From: Noam Postavsky References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> Date: Sat, 22 Jun 2019 18:05:58 -0400 In-Reply-To: ("Mattias \=\?utf-8\?Q\?Engdeg\=C3\=A5rd\=22's\?\= message of "Thu, 20 Jun 2019 12:26:21 +0200") Message-ID: <877e9duvg9.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mattias Engdeg=C3=A5rd writes: > -;; (rx (and line-start (eval something-else))), statically or > -;; (rx-to-string '(and line-start ,something-else)), dynamically. > +;; (rx (seq line-start (regexp something-else))) > > You can actually drop the `seq' form entirely, since it's implicit in `rx= '. > It was only needed for `rx-to-string' which is now gone. Yeah, that applies to most of the examples actually. Updated (and I found a couple of mistakes in them). > +`(literal STRING)' > + matches STRING literally, where STRING is any lisp > + expression that evaluates to a string. > > It's better to name the metavariable EXPR, STRING-EXPR or LISP-EXPR to > make it clear that it's an arbitrary lisp expression, especially since > STRING is used for a constant string just above. Sure. > The same goes for `regexp', since it can now be a lisp expression; > this should be mentioned in the describing paragraph, using a similar > phrasing. The `literal' item should probably be moved next to > `regexp', since they are closely related. Yeah, I wasn't entirely sure whether `literal' should be considered more related to `regexp' or STRING. I guess since I've added a mention of `literal' and `regexp' in the paragraphs above it makes sense to put them at the end together. > The paragraph on `eval' uses FORM, which is too generic No, it's not generic, see (info "(elisp) Intro Eval"): A Lisp object that is intended for evaluation is called a "form" or "expression"(1). --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=0001-Support-rx-and-regexp-EXPR-literal-EXPR-Bug-36237.patch Content-Description: patch >From 3346081acbac014ac3ecef468a46c19e60e9dcc0 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Fri, 14 Jun 2019 08:43:17 -0400 Subject: [PATCH] Support (rx (and (regexp EXPR) (literal EXPR))) (Bug#36237) * lisp/emacs-lisp/rx.el (rx-regexp): Allow non-string forms. (rx-constituents): Add literal constituent, which is like a plain STRING form, but allows arbitrary lisp expressions. (rx-literal): New function. (rx-compile-to-lisp): New variable. (rx--subforms): New helper function for handling subforms, including non-constant case. (rx-group-if, rx-and, rx-or, rx-=, rx->=, rx-repeat, rx-submatch) (rx-submatch-n, rx-kleene, rx-atomic-p): Use it to handle non-constant subforms. (rx): Document new form, wrap non-constant forms with concat call. * test/lisp/emacs-lisp/rx-tests.el (rx-tests--match): New macro. (rx-nonstring-expr, rx-nonstring-expr-non-greedy): New tests. * etc/NEWS: Announce changes. squash! Support (rx (and (regexp EXPR) (literal EXPR))) (Bug#36237) --- etc/NEWS | 6 + lisp/emacs-lisp/rx.el | 240 +++++++++++++++++++++++++-------------- test/lisp/emacs-lisp/rx-tests.el | 41 +++++++ 3 files changed, 200 insertions(+), 87 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 0cfac248a3..dc034a55af 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1400,12 +1400,18 @@ when given in a string. Previously, '(any "\x80-\xff")' would match characters U+0080...U+00FF. Now the expression matches raw bytes in the 128...255 range, as expected. +--- *** The rx 'or' and 'seq' forms no longer require any arguments. (or) produces a regexp that never matches anything, while (seq) matches the empty string, each being an identity for the operation. This also works for their aliases: '|' for 'or'; ':', 'and' and 'sequence' for 'seq'. +--- +*** 'regexp' and new 'literal' accept arbitrary lisp as arguments. +In this case, 'rx' will generate code which produces a regexp string +at runtime, instead of a constant string. + ** Frames +++ diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 8ef78fd69e..c59eb40f08 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -47,57 +47,58 @@ ;; Rx translates a sexp notation for regular expressions into the ;; usual string notation. The translation can be done at compile-time -;; by using the `rx' macro. It can be done at run-time by calling -;; function `rx-to-string'. See the documentation of `rx' for a -;; complete description of the sexp notation. +;; by using the `rx' macro. The `regexp' and `literal' forms accept +;; non-constant expressions, in which case `rx' will translate to a +;; `concat' expression. Translation can be done fully at run-time by +;; calling function `rx-to-string'. See the documentation of `rx' for +;; a complete description of the sexp notation. ;; ;; Some examples of string regexps and their sexp counterparts: ;; ;; "^[a-z]*" -;; (rx (and line-start (0+ (in "a-z")))) +;; (rx line-start (0+ (in "a-z"))) ;; ;; "\n[^ \t]" -;; (rx (and "\n" (not (any " \t")))) +;; (rx ?\n (not (in " \t"))) ;; ;; "\\*\\*\\* EOOH \\*\\*\\*\n" ;; (rx "*** EOOH ***\n") ;; ;; "\\<\\(catch\\|finally\\)\\>[^_]" -;; (rx (and word-start (submatch (or "catch" "finally")) word-end -;; (not (any ?_)))) +;; (rx word-start (submatch (or "catch" "finally")) word-end +;; (not (in ?_))) ;; ;; "[ \t\n]*:\\([^:]+\\|$\\)" -;; (rx (and (zero-or-more (in " \t\n")) ":" -;; (submatch (or line-end (one-or-more (not (any ?:))))))) +;; (rx (* (in " \t\n")) ":" +;; (submatch (or line-end (+ (not (in ?:)))))) ;; -;; "^content-transfer-encoding:\\(\n?[\t ]\\)*quoted-printable\\(\n?[\t ]\\)*" -;; (rx (and line-start -;; "content-transfer-encoding:" -;; (+ (? ?\n)) (any " \t") -;; "quoted-printable" -;; (+ (? ?\n)) (any " \t")) +;; "^content-transfer-encoding:\\(?:\n?[\t ]\\)*quoted-printable\\(?:\n?[\t ]\\)*" +;; (rx line-start +;; "content-transfer-encoding:" +;; (* (? ?\n) (in " \t")) +;; "quoted-printable" +;; (* (? ?\n) (in " \t"))) ;; ;; (concat "^\\(?:" something-else "\\)") -;; (rx (and line-start (eval something-else))), statically or -;; (rx-to-string '(and line-start ,something-else)), dynamically. +;; (rx line-start (regexp something-else)) ;; ;; (regexp-opt '(STRING1 STRING2 ...)) ;; (rx (or STRING1 STRING2 ...)), or in other words, `or' automatically ;; calls `regexp-opt' as needed. ;; ;; "^;;\\s-*\n\\|^\n" -;; (rx (or (and line-start ";;" (0+ space) ?\n) -;; (and line-start ?\n))) +;; (rx (or (seq line-start ";;" (0+ space) ?\n) +;; (seq line-start ?\n))) ;; ;; "\\$[I]d: [^ ]+ \\([^ ]+\\) " -;; (rx (and "$Id: " -;; (1+ (not (in " "))) -;; " " -;; (submatch (1+ (not (in " ")))) -;; " ")) +;; (rx "$Id: " +;; (1+ (not (in " "))) +;; " " +;; (submatch (1+ (not (in " ")))) +;; " ") ;; ;; "\\\\\\\\\\[\\w+" -;; (rx (and ?\\ ?\\ ?\[ (1+ word))) +;; (rx "\\\\[" (1+ word)) ;; ;; etc. @@ -176,6 +177,7 @@ (defvar rx-constituents ;Not `const' because some modes extend it. (not-syntax . (rx-not-syntax 1 1)) ; sregex (category . (rx-category 1 1 rx-check-category)) (eval . (rx-eval 1 1)) + (literal . (rx-literal 1 1 stringp)) (regexp . (rx-regexp 1 1 stringp)) (regex . regexp) ; sregex (digit . "[[:digit:]]") @@ -302,6 +304,10 @@ (defvar rx-greedy-flag t "Non-nil means produce greedy regular expressions for `zero-or-one', `zero-or-more', and `one-or-more'. Dynamically bound.") +(defvar rx--compile-to-lisp nil + "Nil means return a regexp as a string. +Non-nil means we may return a lisp form which produces a +string (used for `rx' macro).") (defun rx-info (op head) "Return parsing/code generation info for OP. @@ -344,7 +350,7 @@ (defun rx-check (form) (> nargs max-args)) (error "rx form `%s' accepts at most %d args" (car form) max-args)) - (when (not (null type-pred)) + (when type-pred (dolist (sub-form (cdr form)) (unless (funcall type-pred sub-form) (error "rx form `%s' requires args satisfying `%s'" @@ -360,8 +366,9 @@ (defun rx-group-if (regexp group) ;; for concatenation ((eq group ':) (if (rx-atomic-p - (if (string-match - "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp) + (if (and (stringp regexp) + (string-match + "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp)) (substring regexp 0 (match-beginning 0)) regexp)) (setq group nil))) @@ -370,9 +377,10 @@ (defun rx-group-if (regexp group) ;; do anyway ((eq group t)) ((rx-atomic-p regexp t) (setq group nil))) - (if group - (concat "\\(?:" regexp "\\)") - regexp)) + (cond ((and group (stringp regexp)) + (concat "\\(?:" regexp "\\)")) + (group `("\\(?:" ,@regexp "\\)")) + (t regexp))) (defvar rx-parent) @@ -384,7 +392,7 @@ (defun rx-and (form) FORM is of the form `(and FORM1 ...)'." (rx-check form) (rx-group-if - (mapconcat (lambda (x) (rx-form x ':)) (cdr form) nil) + (rx--subforms (cdr form) ':) (and (memq rx-parent '(* t)) rx-parent))) @@ -396,7 +404,7 @@ (defun rx-or (form) ((null (cdr form)) regexp-unmatchable) ((cl-every #'stringp (cdr form)) (regexp-opt (cdr form) nil t)) - (t (mapconcat (lambda (x) (rx-form x '|)) (cdr form) "\\|"))) + (t (rx--subforms (cdr form) '| "\\|"))) (and (memq rx-parent '(: * t)) rx-parent))) @@ -669,7 +677,10 @@ (defun rx-= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `=' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) (defun rx->= (form) @@ -679,7 +690,10 @@ (defun rx->= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `>=' requires positive integer first arg")) - (format "%s\\{%d,\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d,\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d,\\}" (nth 1 form)))))) (defun rx-** (form) @@ -700,7 +714,10 @@ (defun rx-repeat (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `repeat' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) ((or (not (integerp (nth 2 form))) (< (nth 2 form) 0) (not (integerp (nth 1 form))) @@ -708,30 +725,26 @@ (defun rx-repeat (form) (< (nth 2 form) (nth 1 form))) (error "rx `repeat' range error")) (t - (format "%s\\{%d,%d\\}" (rx-form (nth 3 form) '*) - (nth 1 form) (nth 2 form))))) + (let ((subform (rx-form (nth 3 form) '*))) + (if (stringp subform) + (format "%s\\{%d,%d\\}" subform (nth 1 form) (nth 2 form)) + `(,@subform ,(format "\\{%d,%d\\}" (nth 1 form) (nth 2 form)))))))) (defun rx-submatch (form) "Parse and produce code from FORM, which is `(submatch ...)'." - (concat "\\(" - (if (= 2 (length form)) - ;; Only one sub-form. - (rx-form (cadr form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cdr form) nil)) - "\\)")) + (let ((subforms (rx--subforms (cdr form) ':))) + (if (stringp subforms) + (concat "\\(" subforms "\\)") + `("\\(" ,@subforms "\\)")))) (defun rx-submatch-n (form) "Parse and produce code from FORM, which is `(submatch-n N ...)'." - (let ((n (nth 1 form))) - (concat "\\(?" (number-to-string n) ":" - (if (= 3 (length form)) - ;; Only one sub-form. - (rx-form (nth 2 form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cddr form) nil)) - "\\)"))) + (let ((n (nth 1 form)) + (subforms (rx--subforms (cddr form) ':))) + (if (stringp subforms) + (concat "\\(?" (number-to-string n) ":" subforms "\\)") + `("\\(?" ,(number-to-string n) ":" ,@subforms "\\)")))) (defun rx-backref (form) "Parse and produce code from FORM, which is `(backref N)'." @@ -759,9 +772,12 @@ (defun rx-kleene (form) (t "?"))) (op (cond ((memq (car form) '(* *? 0+ zero-or-more)) "*") ((memq (car form) '(+ +? 1+ one-or-more)) "+") - (t "?")))) + (t "?"))) + (subform (rx-form (cadr form) '*))) (rx-group-if - (concat (rx-form (cadr form) '*) op suffix) + (if (stringp subform) + (concat subform op suffix) + `(,@subform ,(concat op suffix))) (and (memq rx-parent '(t *)) rx-parent)))) @@ -789,15 +805,18 @@ (defun rx-atomic-p (r &optional lax) be detected without much effort. A guarantee of no false negatives would require a theoretic specification of the set of all atomic regexps." - (let ((l (length r))) - (cond - ((<= l 1)) - ((= l 2) (= (aref r 0) ?\\)) - ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) - ((null lax) + (if (and rx--compile-to-lisp + (not (stringp r))) + nil ;; Runtime value, we must assume non-atomic. + (let ((l (length r))) (cond - ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) - ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r))))))) + ((<= l 1)) + ((= l 2) (= (aref r 0) ?\\)) + ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) + ((null lax) + (cond + ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) + ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r)))))))) (defun rx-syntax (form) @@ -853,9 +872,23 @@ (defun rx-greedy (form) (defun rx-regexp (form) "Parse and produce code from FORM, which is `(regexp STRING)'." - (rx-check form) - (rx-group-if (cadr form) rx-parent)) - + (cond ((stringp form) + (rx-group-if (cadr form) rx-parent)) + (rx--compile-to-lisp + ;; Always group non-string forms, since we can't be sure they + ;; are atomic. + (rx-group-if (cdr form) t)) + (t (rx-check form)))) + +(defun rx-literal (form) + "Parse and produce code from FORM, which is `(literal STRING-EXP)'." + (cond ((stringp form) + ;; This is allowed, but makes little sense, you could just + ;; use STRING directly. + (rx-group-if (regexp-quote (cadr form)) rx-parent)) + (rx--compile-to-lisp + (rx-group-if `((regexp-quote ,(cadr form))) rx-parent)) + (t (rx-check form)))) (defun rx-form (form &optional parent) "Parse and produce code for regular expression FORM. @@ -886,12 +919,38 @@ (defun rx-form (form &optional parent) (t (error "rx syntax error at `%s'" form))))) +(defun rx--subforms (subforms &optional parent separator) + "Produce code for regular expressions SUBFORMS. +SUBFORMS is a list of regular expression sexps. +PARENT controls grouping, as in `rx-form'. +Insert SEPARATOR between the code from each of SUBFORMS." + (if (null (cdr subforms)) + ;; Zero or one forms, no need for grouping. + (and subforms (rx-form (car subforms))) + (let ((listify (lambda (x) + (if (listp x) (copy-sequence x) + (list x))))) + (setq subforms (mapcar (lambda (x) (rx-form x parent)) subforms)) + (cond ((or (not rx--compile-to-lisp) + (cl-every #'stringp subforms)) + (mapconcat #'identity subforms separator)) + (separator + (nconc (funcall listify (car subforms)) + (mapcan (lambda (x) + (cons separator (funcall listify x))) + (cdr subforms)))) + (t (mapcan listify subforms)))))) + ;;;###autoload (defun rx-to-string (form &optional no-group) "Parse and produce code for regular expression FORM. FORM is a regular expression in sexp form. -NO-GROUP non-nil means don't put shy groups around the result." +NO-GROUP non-nil means don't put shy groups around the result. + +In contrast to the `rx' macro, subforms `literal' and `regexp' +will not accept non-string arguments, i.e., (literal STRING) +becomes just a more verbose version of STRING." (rx-group-if (rx-form form) (null no-group))) @@ -901,8 +960,12 @@ (defmacro rx (&rest regexps) REGEXPS is a non-empty sequence of forms of the sort listed below. Note that `rx' is a Lisp macro; when used in a Lisp program being -compiled, the translation is performed by the compiler. -See `rx-to-string' for how to do such a translation at run-time. +compiled, the translation is performed by the compiler. The +`literal' and `regexp' forms accept subforms that will evaluate +to strings, in addition to constant strings. If REGEXPS include +such forms, then the result is an expression which returns a +regexp string, rather than a regexp string directly. See +`rx-to-string' for performing translation completely at run-time. The following are valid subforms of regular expressions in sexp notation. @@ -1202,18 +1265,29 @@ (defmacro rx (&rest regexps) `(backref N)' matches what was matched previously by submatch N. +`(literal STRING-EXPR)' + matches STRING-EXPR literally, where STRING-EXPR is any lisp + expression that evaluates to a string. + +`(regexp REGEXP-EXPR)' + include REGEXP-EXPR in string notation in the result, where + REGEXP-EXPR is any lisp expression that evaluates a string + containing a valid regexp. + `(eval FORM)' evaluate FORM and insert result. If result is a string, - `regexp-quote' it. - -`(regexp REGEXP)' - include REGEXP in string notation in the result." - (cond ((null regexps) - (error "No regexp")) - ((cdr regexps) - (rx-to-string `(and ,@regexps) t)) - (t - (rx-to-string (car regexps) t)))) + `regexp-quote' it. Note that FORM is evaluated during + macroexpansion." + (let* ((rx--compile-to-lisp t) + (re (cond ((null regexps) + (error "No regexp")) + ((cdr regexps) + (rx-to-string `(and ,@regexps) t)) + (t + (rx-to-string (car regexps) t))))) + (if (stringp re) + re + `(concat ,@re)))) (pcase-defmacro rx (&rest regexps) @@ -1275,14 +1349,6 @@ (pcase-defmacro rx (&rest regexps) for var in vars collect `(app (match-string ,i) ,var))))) -;; ;; sregex.el replacement - -;; ;;;###autoload (provide 'sregex) -;; ;;;###autoload (autoload 'sregex "rx") -;; (defalias 'sregex 'rx-to-string) -;; ;;;###autoload (autoload 'sregexq "rx" nil nil 'macro) -;; (defalias 'sregexq 'rx) - (provide 'rx) ;;; rx.el ends here diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 6f392d616d..bab71b522b 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -115,5 +115,46 @@ (ert-deftest rx-seq () ;; Test zero-argument `seq'. (should (equal (rx (seq)) ""))) +(defmacro rx-tests--match (regexp string &optional match) + (macroexp-let2 nil strexp string + `(ert-info ((format "Matching %S to %S" ',regexp ,strexp)) + (should (string-match ,regexp ,strexp)) + ,@(when match + `((should (equal (match-string 0 ,strexp) ,match))))))) + +(ert-deftest rx-nonstring-expr () + (let ((bee "b") + (vowel "[aeiou]")) + (rx-tests--match (rx "a" (literal bee) "c") "abc") + (rx-tests--match (rx "a" (regexp bee) "c") "abc") + (rx-tests--match (rx "a" (or (regexp bee) "xy") "c") "abc") + (rx-tests--match (rx "a" (or "xy" (regexp bee)) "c") "abc") + (should-not (string-match (rx (or (regexp bee) "xy")) "")) + (rx-tests--match (rx "a" (= 3 (regexp bee)) "c") "abbbc") + (rx-tests--match (rx "x" (= 3 (regexp vowel)) "z") "xeoez") + (should-not (string-match (rx "x" (= 3 (regexp vowel)) "z") "xe[]z")) + (rx-tests--match (rx "x" (= 3 (literal vowel)) "z") + "x[aeiou][aeiou][aeiou]z") + (rx-tests--match (rx "x" (repeat 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xauz") + (rx-tests--match (rx "x" (>= 1 (regexp vowel)) "z") "xaiiz") + (rx-tests--match (rx "x" (** 1 2 (regexp vowel)) "z") "xaiz") + (rx-tests--match (rx "x" (group (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (group-n 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (? (regexp vowel)) "z") "xz"))) + +(ert-deftest rx-nonstring-expr-non-greedy () + "`rx's greediness can't affect runtime regexp parts." + (let ((ad-min "[ad]*?") + (ad-max "[ad]*") + (ad "[ad]")) + (rx-tests--match (rx "c" (regexp ad-min) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (regexp ad-max) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (minimal-match (regexp ad-max)) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (maximal-match (regexp ad-min)) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (minimal-match (0+ (regexp ad))) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (maximal-match (0+ (regexp ad))) "a") "cdaaada" "cdaaada"))) + (provide 'rx-tests) ;; rx-tests.el ends here. -- 2.11.0 --=-=-=-- From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 23 Jun 2019 11:10:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156128819410054 (code B ref 36237); Sun, 23 Jun 2019 11:10:02 +0000 Received: (at 36237) by debbugs.gnu.org; 23 Jun 2019 11:09:54 +0000 Received: from localhost ([127.0.0.1]:52912 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hf0Ne-0002c6-9d for submit@debbugs.gnu.org; Sun, 23 Jun 2019 07:09:54 -0400 Received: from mail208c50.megamailservers.eu ([91.136.10.218]:53090 helo=mail194c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hf0Nc-0002bv-6H for 36237@debbugs.gnu.org; Sun, 23 Jun 2019 07:09:53 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1561288189; bh=acXNXtF3i0GcFQ2ycftS/UL88j8aMg2BLbzBnLU4bI0=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=nbmfjqM1Gbuemlt8siFXZtZwuLwN4j2nYDCRZhAlStdj4iRA9zhkRnRX/MRhJlaWj vHhu7oRO9GfRqYRpanJ2cLxYpijqGFzYXnjh15vnxTuVUrLuOfzv26bmfe65T8tcI7 vpTRsqVCaigeshaviHFjhTb5/cprwhY83XcY0VZo= Feedback-ID: mattiase@acm.or Received: from [192.168.0.4] ([188.150.171.71]) (authenticated bits=0) by mail194c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x5NB9kSc032500; Sun, 23 Jun 2019 11:09:48 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: <877e9duvg9.fsf@gmail.com> Date: Sun, 23 Jun 2019 13:09:46 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: <5B00DCD9-0718-44AF-89C1-110CFDC17444@acm.org> References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> <877e9duvg9.fsf@gmail.com> X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0202.5D0F5DFD.000D, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=OuZhNR3t c=1 sm=1 tr=0 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=pGLkceISAAAA:8 a=1etVCN-2JTeQF3UX0_AA:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) 23 juni 2019 kl. 00.05 skrev Noam Postavsky : >=20 > Yeah, that applies to most of the examples actually. Updated (and I > found a couple of mistakes in them). Very good, thank you! I double-checked them with xr and only found one = error (see below). >> The paragraph on `eval' uses FORM, which is too generic >=20 > No, it's not generic, see (info "(elisp) Intro Eval"): >=20 > A Lisp object that is intended for evaluation is called a "form" = or > "expression"(1). You are entirely correct, of course; what I meant is that the docs = frequently use "form" for the `rx' whatchamacallits even though they = aren't Lisp expressions. The terminology is a mess; use whatever you = find understandable. >squash! Support (rx (and (regexp EXPR) (literal EXPR))) (Bug#36237) Remnants of rebase editing? ;; "[ \t\n]*:\\([^:]+\\|$\\)" -;; (rx (and (zero-or-more (in " \t\n")) ":" -;; (submatch (or line-end (one-or-more (not (any ?:))))))) +;; (rx (* (in " \t\n")) ":" +;; (submatch (or line-end (+ (not (in ?:)))))) The correct translation of the `or'-pattern is (or (+ (not (any ":"))) eol) since the order of the branches matters. Maybe it's the regexp string = that should be the other way around; hard to tell without any context. ;; "^;;\\s-*\n\\|^\n" -;; (rx (or (and line-start ";;" (0+ space) ?\n) -;; (and line-start ?\n))) +;; (rx (or (seq line-start ";;" (0+ space) ?\n) +;; (seq line-start ?\n))) This should be correct. The regexp compiler translates `[[:space:]]` and = `\s-` to different bytecodes, but as far as I can tell they end up = having identical semantics in the end. Same goes for `[[:word:]]' vs = `\sw' (alias `\w'), and so on. +`(literal STRING-EXPR)' + matches STRING-EXPR literally, where STRING-EXPR is any lisp + expression that evaluates to a string. + +`(regexp REGEXP-EXPR)' + include REGEXP-EXPR in string notation in the result, where + REGEXP-EXPR is any lisp expression that evaluates a string + containing a valid regexp. Missed "to" after "evaluate"? I'm happy with the patch after the obvious fixes. From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Drew Adams Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 23 Jun 2019 14:46:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky , Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156130115931425 (code B ref 36237); Sun, 23 Jun 2019 14:46:02 +0000 Received: (at 36237) by debbugs.gnu.org; 23 Jun 2019 14:45:59 +0000 Received: from localhost ([127.0.0.1]:54096 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hf3kl-0008Am-GI for submit@debbugs.gnu.org; Sun, 23 Jun 2019 10:45:59 -0400 Received: from aserp2120.oracle.com ([141.146.126.78]:58736) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hf3kk-0008AZ-4t for 36237@debbugs.gnu.org; Sun, 23 Jun 2019 10:45:58 -0400 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5NEjcAH150148; Sun, 23 Jun 2019 14:45:38 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=dhsKy+otVI7M08ytAx0A44GC1kz9jnZ6cqcNVhLQacM=; b=N0HdK3Qxrb6ze1R4l8CiVBc+oQaOO48ek1qTVkDzqMeAer8dVXcwwN3HCTHXRYPUDNlx 7EmZDn8JTq8UdIyB4qmwg3GW3LiOhgVO5T1f26yiRBd2e7T/BLgbeVYMI0CP+4yd51uz JVDV9vhHIMqkszs+GKfo+LyPc/qUN5WNN/gjlSgTetkVY8cceWzLAVSjI1mhonmM8m4k ZAyCqW+Jr/YR8jaCsaWrj/q7ZAbEKKw56dBcRskG7zhi5fYmdpZ4hhf2LGQKIL7O1yCH /w08VGfXsYHcQx5TnCzgFFg4Szh+7wUcOkYLj3tDBkWcXwYPuiWvpfUnpddvZBQivE8E Wg== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by aserp2120.oracle.com with ESMTP id 2t9c9pau93-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 23 Jun 2019 14:45:38 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x5NEjN3d157266; Sun, 23 Jun 2019 14:45:37 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserp3030.oracle.com with ESMTP id 2t9acb5avv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 23 Jun 2019 14:45:37 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x5NEjRuv026825; Sun, 23 Jun 2019 14:45:27 GMT MIME-Version: 1.0 Message-ID: <717f0dcf-8083-4053-b6a3-2fc7ca167627@default> Date: Sun, 23 Jun 2019 07:45:26 -0700 (PDT) From: Drew Adams References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> <877e9duvg9.fsf@gmail.com> In-Reply-To: <877e9duvg9.fsf@gmail.com> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4861.0 (x86)] Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9297 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=936 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906230129 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9297 signatures=668687 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1906230129 X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Minor: "at run-time" -> "at run time" Emacs docs seem to use "runtime" as adjective and "run time" as noun, which is fairly conventional. Sometimes, outside Emacs, "runtime" is used for both. From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 23 Jun 2019 15:47:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.15613047764641 (code B ref 36237); Sun, 23 Jun 2019 15:47:02 +0000 Received: (at 36237) by debbugs.gnu.org; 23 Jun 2019 15:46:16 +0000 Received: from localhost ([127.0.0.1]:54135 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hf4h5-0001Cj-01 for submit@debbugs.gnu.org; Sun, 23 Jun 2019 11:46:16 -0400 Received: from mail-io1-f41.google.com ([209.85.166.41]:43366) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hf4h2-0001CP-1p for 36237@debbugs.gnu.org; Sun, 23 Jun 2019 11:46:13 -0400 Received: by mail-io1-f41.google.com with SMTP id k20so299949ios.10 for <36237@debbugs.gnu.org>; Sun, 23 Jun 2019 08:46:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=+ccbpZTzBZfU6yqANyirCHLlmnrepIMF3US6U/0YlTM=; b=SrrNKtYOhBEb6WedvfehRoEEPKuAfjuNVsD7HevRkM+yWrZTAaRE4yOZ93npgqXDI0 R45NkB6r/AUaPixcuFdpqrH1kWVuynsPALHI6u0Ll6XZWlsBr3674sFGU8AXfZNbQ5Wx 8pTJ7cEhOJEE+xumf/Upc9wKnouL0ChgHMCyH1QXfwYeY1m184S/qbEk2kbu4OAlGJaO Bv+YW3IiwKpXbjFHz7IuN1xHBitJIjhw9JIX+CpsOMEefBIQZUoz9nG/cfzVhAItYMOs ZYUQ0c3A7rNr1Ynm/whJIl/bsXYJrYBVL1Y/bgY5wvQsnJPSb2ZLwGvtN9yxsXmkoOwQ V4cA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=+ccbpZTzBZfU6yqANyirCHLlmnrepIMF3US6U/0YlTM=; b=iHEgsXJLDZf0TwTaVJEZpb0TuXiRZTg83NfQor33dilBzk7TC3rM9SUVxc1kLs+nO/ /GwWnLHkohh37vwtk+oi0u0X5nEXZmDNQkCf0+aWDUEMHqfXiS9YlJUGIfDMErrQq8Pa YDpjxbAq9XpC9zRYnVxY2LitRskf9zPPq7keozy5/P35LASr2BjukIZqRb+9K4fvlXM6 7eA1cPKKSf6ROOdZHCRizoK8pTyVN2U0f5BUQVxlzbxKVU+ohqfvzMtjheyJdWyKId1w uPgRyvwP0U1S11SP3hcJnr0jvpJJS/Og6o3Mg6ZE3kiKzSfcELBqLdoQPL+3BhBzJmJC Q/8A== X-Gm-Message-State: APjAAAVT1ImwTRzSvgfFfFpZEum5Rw0nrs7FIVlIRHqHNfBptdPxJRYc IZIyynVRqOwMvi7/DxWHLXg= X-Google-Smtp-Source: APXvYqzw1glXspxe8qABOARz9wgm80HVdfQnXtShz7FjvFHspIfj24OkdRrghDU1vRfMgvO5XNn5PA== X-Received: by 2002:a05:6602:220a:: with SMTP id n10mr34401056ion.205.1561304766344; Sun, 23 Jun 2019 08:46:06 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id t4sm7864866ioj.26.2019.06.23.08.46.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 23 Jun 2019 08:46:05 -0700 (PDT) From: Noam Postavsky References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> <877e9duvg9.fsf@gmail.com> <5B00DCD9-0718-44AF-89C1-110CFDC17444@acm.org> Date: Sun, 23 Jun 2019 11:46:04 -0400 In-Reply-To: <5B00DCD9-0718-44AF-89C1-110CFDC17444@acm.org> ("Mattias \=\?utf-8\?Q\?Engdeg\=C3\=A5rd\=22's\?\= message of "Sun, 23 Jun 2019 13:09:46 +0200") Message-ID: <87ef3ktidf.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mattias Engdeg=C3=A5rd writes: > > what I meant is that the docs frequently use "form" for the `rx' > whatchamacallits even though they aren't Lisp expressions. The > terminology is a mess; use whatever you find understandable. Well, the rest of the rx docstring uses SEXP for the `rx' whatchamacallits, so I think leaving it as (eval FORM) should be fine. And hopefully we'll be able to deprecate eval soon enough so it won't matter too much. >>squash! Support (rx (and (regexp EXPR) (literal EXPR))) (Bug#36237) > > Remnants of rebase editing? Oops, yes. I wish git would comment out the "squash!..." line automatically. > since the order of the branches matters. Maybe it's the regexp string > that should be the other way around; hard to tell without any context. Yeah, I switched the regexp string instead, on the grounds that otherwise "$" would almost never match (except at end of buffer) since [^:] already matches \n. > +`(regexp REGEXP-EXPR)' > + include REGEXP-EXPR in string notation in the result, where > + REGEXP-EXPR is any lisp expression that evaluates a string > + containing a valid regexp. > > Missed "to" after "evaluate"? Oops. > I'm happy with the patch after the obvious fixes. I'll wait a few more days in case something else comes up. Drew Adams writes: > Minor: > > "at run-time" -> "at run time" > > Emacs docs seem to use "runtime" as > adjective and "run time" as noun, which > is fairly conventional. Sometimes, > outside Emacs, "runtime" is used for both. The elisp manual has a couple of "run-time" as well, but more cases of "run time" so I went with that. --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=0001-Support-rx-and-regexp-EXPR-literal-EXPR-Bug-36237.patch Content-Description: patch >From f0680d83907ada3d2c094625ee3446dfe696251a Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Fri, 14 Jun 2019 08:43:17 -0400 Subject: [PATCH] Support (rx (and (regexp EXPR) (literal EXPR))) (Bug#36237) * lisp/emacs-lisp/rx.el (rx-regexp): Allow non-string forms. (rx-constituents): Add literal constituent, which is like a plain STRING form, but allows arbitrary lisp expressions. (rx-literal): New function. (rx-compile-to-lisp): New variable. (rx--subforms): New helper function for handling subforms, including non-constant case. (rx-group-if, rx-and, rx-or, rx-=, rx->=, rx-repeat, rx-submatch) (rx-submatch-n, rx-kleene, rx-atomic-p): Use it to handle non-constant subforms. (rx): Document new form, wrap non-constant forms with concat call. * test/lisp/emacs-lisp/rx-tests.el (rx-tests--match): New macro. (rx-nonstring-expr, rx-nonstring-expr-non-greedy): New tests. * etc/NEWS: Announce changes. --- etc/NEWS | 6 + lisp/emacs-lisp/rx.el | 242 +++++++++++++++++++++++++-------------- test/lisp/emacs-lisp/rx-tests.el | 41 +++++++ 3 files changed, 201 insertions(+), 88 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 0cfac248a3..4c31f48da2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1400,12 +1400,18 @@ when given in a string. Previously, '(any "\x80-\xff")' would match characters U+0080...U+00FF. Now the expression matches raw bytes in the 128...255 range, as expected. +--- *** The rx 'or' and 'seq' forms no longer require any arguments. (or) produces a regexp that never matches anything, while (seq) matches the empty string, each being an identity for the operation. This also works for their aliases: '|' for 'or'; ':', 'and' and 'sequence' for 'seq'. +--- +*** 'regexp' and new 'literal' accept arbitrary lisp as arguments. +In this case, 'rx' will generate code which produces a regexp string +at run time, instead of a constant string. + ** Frames +++ diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 8ef78fd69e..5951caf051 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -47,57 +47,58 @@ ;; Rx translates a sexp notation for regular expressions into the ;; usual string notation. The translation can be done at compile-time -;; by using the `rx' macro. It can be done at run-time by calling -;; function `rx-to-string'. See the documentation of `rx' for a -;; complete description of the sexp notation. +;; by using the `rx' macro. The `regexp' and `literal' forms accept +;; non-constant expressions, in which case `rx' will translate to a +;; `concat' expression. Translation can be done fully at run time by +;; calling function `rx-to-string'. See the documentation of `rx' for +;; a complete description of the sexp notation. ;; ;; Some examples of string regexps and their sexp counterparts: ;; ;; "^[a-z]*" -;; (rx (and line-start (0+ (in "a-z")))) +;; (rx line-start (0+ (in "a-z"))) ;; ;; "\n[^ \t]" -;; (rx (and "\n" (not (any " \t")))) +;; (rx ?\n (not (in " \t"))) ;; ;; "\\*\\*\\* EOOH \\*\\*\\*\n" ;; (rx "*** EOOH ***\n") ;; ;; "\\<\\(catch\\|finally\\)\\>[^_]" -;; (rx (and word-start (submatch (or "catch" "finally")) word-end -;; (not (any ?_)))) +;; (rx word-start (submatch (or "catch" "finally")) word-end +;; (not (in ?_))) ;; -;; "[ \t\n]*:\\([^:]+\\|$\\)" -;; (rx (and (zero-or-more (in " \t\n")) ":" -;; (submatch (or line-end (one-or-more (not (any ?:))))))) +;; "[ \t\n]*:\\($\\|[^:]+\\)" +;; (rx (* (in " \t\n")) ":" +;; (submatch (or line-end (+ (not (in ?:)))))) ;; -;; "^content-transfer-encoding:\\(\n?[\t ]\\)*quoted-printable\\(\n?[\t ]\\)*" -;; (rx (and line-start -;; "content-transfer-encoding:" -;; (+ (? ?\n)) (any " \t") -;; "quoted-printable" -;; (+ (? ?\n)) (any " \t")) +;; "^content-transfer-encoding:\\(?:\n?[\t ]\\)*quoted-printable\\(?:\n?[\t ]\\)*" +;; (rx line-start +;; "content-transfer-encoding:" +;; (* (? ?\n) (in " \t")) +;; "quoted-printable" +;; (* (? ?\n) (in " \t"))) ;; ;; (concat "^\\(?:" something-else "\\)") -;; (rx (and line-start (eval something-else))), statically or -;; (rx-to-string '(and line-start ,something-else)), dynamically. +;; (rx line-start (regexp something-else)) ;; ;; (regexp-opt '(STRING1 STRING2 ...)) ;; (rx (or STRING1 STRING2 ...)), or in other words, `or' automatically ;; calls `regexp-opt' as needed. ;; ;; "^;;\\s-*\n\\|^\n" -;; (rx (or (and line-start ";;" (0+ space) ?\n) -;; (and line-start ?\n))) +;; (rx (or (seq line-start ";;" (0+ space) ?\n) +;; (seq line-start ?\n))) ;; ;; "\\$[I]d: [^ ]+ \\([^ ]+\\) " -;; (rx (and "$Id: " -;; (1+ (not (in " "))) -;; " " -;; (submatch (1+ (not (in " ")))) -;; " ")) +;; (rx "$Id: " +;; (1+ (not (in " "))) +;; " " +;; (submatch (1+ (not (in " ")))) +;; " ") ;; ;; "\\\\\\\\\\[\\w+" -;; (rx (and ?\\ ?\\ ?\[ (1+ word))) +;; (rx "\\\\[" (1+ word)) ;; ;; etc. @@ -176,6 +177,7 @@ (defvar rx-constituents ;Not `const' because some modes extend it. (not-syntax . (rx-not-syntax 1 1)) ; sregex (category . (rx-category 1 1 rx-check-category)) (eval . (rx-eval 1 1)) + (literal . (rx-literal 1 1 stringp)) (regexp . (rx-regexp 1 1 stringp)) (regex . regexp) ; sregex (digit . "[[:digit:]]") @@ -302,6 +304,10 @@ (defvar rx-greedy-flag t "Non-nil means produce greedy regular expressions for `zero-or-one', `zero-or-more', and `one-or-more'. Dynamically bound.") +(defvar rx--compile-to-lisp nil + "Nil means return a regexp as a string. +Non-nil means we may return a lisp form which produces a +string (used for `rx' macro).") (defun rx-info (op head) "Return parsing/code generation info for OP. @@ -344,7 +350,7 @@ (defun rx-check (form) (> nargs max-args)) (error "rx form `%s' accepts at most %d args" (car form) max-args)) - (when (not (null type-pred)) + (when type-pred (dolist (sub-form (cdr form)) (unless (funcall type-pred sub-form) (error "rx form `%s' requires args satisfying `%s'" @@ -360,8 +366,9 @@ (defun rx-group-if (regexp group) ;; for concatenation ((eq group ':) (if (rx-atomic-p - (if (string-match - "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp) + (if (and (stringp regexp) + (string-match + "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'" regexp)) (substring regexp 0 (match-beginning 0)) regexp)) (setq group nil))) @@ -370,9 +377,10 @@ (defun rx-group-if (regexp group) ;; do anyway ((eq group t)) ((rx-atomic-p regexp t) (setq group nil))) - (if group - (concat "\\(?:" regexp "\\)") - regexp)) + (cond ((and group (stringp regexp)) + (concat "\\(?:" regexp "\\)")) + (group `("\\(?:" ,@regexp "\\)")) + (t regexp))) (defvar rx-parent) @@ -384,7 +392,7 @@ (defun rx-and (form) FORM is of the form `(and FORM1 ...)'." (rx-check form) (rx-group-if - (mapconcat (lambda (x) (rx-form x ':)) (cdr form) nil) + (rx--subforms (cdr form) ':) (and (memq rx-parent '(* t)) rx-parent))) @@ -396,7 +404,7 @@ (defun rx-or (form) ((null (cdr form)) regexp-unmatchable) ((cl-every #'stringp (cdr form)) (regexp-opt (cdr form) nil t)) - (t (mapconcat (lambda (x) (rx-form x '|)) (cdr form) "\\|"))) + (t (rx--subforms (cdr form) '| "\\|"))) (and (memq rx-parent '(: * t)) rx-parent))) @@ -669,7 +677,10 @@ (defun rx-= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `=' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) (defun rx->= (form) @@ -679,7 +690,10 @@ (defun rx->= (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `>=' requires positive integer first arg")) - (format "%s\\{%d,\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d,\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d,\\}" (nth 1 form)))))) (defun rx-** (form) @@ -700,7 +714,10 @@ (defun rx-repeat (form) (unless (and (integerp (nth 1 form)) (> (nth 1 form) 0)) (error "rx `repeat' requires positive integer first arg")) - (format "%s\\{%d\\}" (rx-form (nth 2 form) '*) (nth 1 form))) + (let ((subform (rx-form (nth 2 form) '*))) + (if (stringp subform) + (format "%s\\{%d\\}" subform (nth 1 form)) + `(,@subform ,(format "\\{%d\\}" (nth 1 form)))))) ((or (not (integerp (nth 2 form))) (< (nth 2 form) 0) (not (integerp (nth 1 form))) @@ -708,30 +725,26 @@ (defun rx-repeat (form) (< (nth 2 form) (nth 1 form))) (error "rx `repeat' range error")) (t - (format "%s\\{%d,%d\\}" (rx-form (nth 3 form) '*) - (nth 1 form) (nth 2 form))))) + (let ((subform (rx-form (nth 3 form) '*))) + (if (stringp subform) + (format "%s\\{%d,%d\\}" subform (nth 1 form) (nth 2 form)) + `(,@subform ,(format "\\{%d,%d\\}" (nth 1 form) (nth 2 form)))))))) (defun rx-submatch (form) "Parse and produce code from FORM, which is `(submatch ...)'." - (concat "\\(" - (if (= 2 (length form)) - ;; Only one sub-form. - (rx-form (cadr form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cdr form) nil)) - "\\)")) + (let ((subforms (rx--subforms (cdr form) ':))) + (if (stringp subforms) + (concat "\\(" subforms "\\)") + `("\\(" ,@subforms "\\)")))) (defun rx-submatch-n (form) "Parse and produce code from FORM, which is `(submatch-n N ...)'." - (let ((n (nth 1 form))) - (concat "\\(?" (number-to-string n) ":" - (if (= 3 (length form)) - ;; Only one sub-form. - (rx-form (nth 2 form)) - ;; Several sub-forms implicitly concatenated. - (mapconcat (lambda (re) (rx-form re ':)) (cddr form) nil)) - "\\)"))) + (let ((n (nth 1 form)) + (subforms (rx--subforms (cddr form) ':))) + (if (stringp subforms) + (concat "\\(?" (number-to-string n) ":" subforms "\\)") + `("\\(?" ,(number-to-string n) ":" ,@subforms "\\)")))) (defun rx-backref (form) "Parse and produce code from FORM, which is `(backref N)'." @@ -759,9 +772,12 @@ (defun rx-kleene (form) (t "?"))) (op (cond ((memq (car form) '(* *? 0+ zero-or-more)) "*") ((memq (car form) '(+ +? 1+ one-or-more)) "+") - (t "?")))) + (t "?"))) + (subform (rx-form (cadr form) '*))) (rx-group-if - (concat (rx-form (cadr form) '*) op suffix) + (if (stringp subform) + (concat subform op suffix) + `(,@subform ,(concat op suffix))) (and (memq rx-parent '(t *)) rx-parent)))) @@ -789,15 +805,18 @@ (defun rx-atomic-p (r &optional lax) be detected without much effort. A guarantee of no false negatives would require a theoretic specification of the set of all atomic regexps." - (let ((l (length r))) - (cond - ((<= l 1)) - ((= l 2) (= (aref r 0) ?\\)) - ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) - ((null lax) + (if (and rx--compile-to-lisp + (not (stringp r))) + nil ;; Runtime value, we must assume non-atomic. + (let ((l (length r))) (cond - ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) - ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r))))))) + ((<= l 1)) + ((= l 2) (= (aref r 0) ?\\)) + ((= l 3) (string-match "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)" r)) + ((null lax) + (cond + ((string-match "\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'" r)) + ((string-match "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'" r)))))))) (defun rx-syntax (form) @@ -853,9 +872,23 @@ (defun rx-greedy (form) (defun rx-regexp (form) "Parse and produce code from FORM, which is `(regexp STRING)'." - (rx-check form) - (rx-group-if (cadr form) rx-parent)) - + (cond ((stringp form) + (rx-group-if (cadr form) rx-parent)) + (rx--compile-to-lisp + ;; Always group non-string forms, since we can't be sure they + ;; are atomic. + (rx-group-if (cdr form) t)) + (t (rx-check form)))) + +(defun rx-literal (form) + "Parse and produce code from FORM, which is `(literal STRING-EXP)'." + (cond ((stringp form) + ;; This is allowed, but makes little sense, you could just + ;; use STRING directly. + (rx-group-if (regexp-quote (cadr form)) rx-parent)) + (rx--compile-to-lisp + (rx-group-if `((regexp-quote ,(cadr form))) rx-parent)) + (t (rx-check form)))) (defun rx-form (form &optional parent) "Parse and produce code for regular expression FORM. @@ -886,12 +919,38 @@ (defun rx-form (form &optional parent) (t (error "rx syntax error at `%s'" form))))) +(defun rx--subforms (subforms &optional parent separator) + "Produce code for regular expressions SUBFORMS. +SUBFORMS is a list of regular expression sexps. +PARENT controls grouping, as in `rx-form'. +Insert SEPARATOR between the code from each of SUBFORMS." + (if (null (cdr subforms)) + ;; Zero or one forms, no need for grouping. + (and subforms (rx-form (car subforms))) + (let ((listify (lambda (x) + (if (listp x) (copy-sequence x) + (list x))))) + (setq subforms (mapcar (lambda (x) (rx-form x parent)) subforms)) + (cond ((or (not rx--compile-to-lisp) + (cl-every #'stringp subforms)) + (mapconcat #'identity subforms separator)) + (separator + (nconc (funcall listify (car subforms)) + (mapcan (lambda (x) + (cons separator (funcall listify x))) + (cdr subforms)))) + (t (mapcan listify subforms)))))) + ;;;###autoload (defun rx-to-string (form &optional no-group) "Parse and produce code for regular expression FORM. FORM is a regular expression in sexp form. -NO-GROUP non-nil means don't put shy groups around the result." +NO-GROUP non-nil means don't put shy groups around the result. + +In contrast to the `rx' macro, subforms `literal' and `regexp' +will not accept non-string arguments, i.e., (literal STRING) +becomes just a more verbose version of STRING." (rx-group-if (rx-form form) (null no-group))) @@ -901,8 +960,12 @@ (defmacro rx (&rest regexps) REGEXPS is a non-empty sequence of forms of the sort listed below. Note that `rx' is a Lisp macro; when used in a Lisp program being -compiled, the translation is performed by the compiler. -See `rx-to-string' for how to do such a translation at run-time. +compiled, the translation is performed by the compiler. The +`literal' and `regexp' forms accept subforms that will evaluate +to strings, in addition to constant strings. If REGEXPS include +such forms, then the result is an expression which returns a +regexp string, rather than a regexp string directly. See +`rx-to-string' for performing translation completely at run time. The following are valid subforms of regular expressions in sexp notation. @@ -1202,18 +1265,29 @@ (defmacro rx (&rest regexps) `(backref N)' matches what was matched previously by submatch N. +`(literal STRING-EXPR)' + matches STRING-EXPR literally, where STRING-EXPR is any lisp + expression that evaluates to a string. + +`(regexp REGEXP-EXPR)' + include REGEXP-EXPR in string notation in the result, where + REGEXP-EXPR is any lisp expression that evaluates to a + string containing a valid regexp. + `(eval FORM)' evaluate FORM and insert result. If result is a string, - `regexp-quote' it. - -`(regexp REGEXP)' - include REGEXP in string notation in the result." - (cond ((null regexps) - (error "No regexp")) - ((cdr regexps) - (rx-to-string `(and ,@regexps) t)) - (t - (rx-to-string (car regexps) t)))) + `regexp-quote' it. Note that FORM is evaluated during + macroexpansion." + (let* ((rx--compile-to-lisp t) + (re (cond ((null regexps) + (error "No regexp")) + ((cdr regexps) + (rx-to-string `(and ,@regexps) t)) + (t + (rx-to-string (car regexps) t))))) + (if (stringp re) + re + `(concat ,@re)))) (pcase-defmacro rx (&rest regexps) @@ -1275,14 +1349,6 @@ (pcase-defmacro rx (&rest regexps) for var in vars collect `(app (match-string ,i) ,var))))) -;; ;; sregex.el replacement - -;; ;;;###autoload (provide 'sregex) -;; ;;;###autoload (autoload 'sregex "rx") -;; (defalias 'sregex 'rx-to-string) -;; ;;;###autoload (autoload 'sregexq "rx" nil nil 'macro) -;; (defalias 'sregexq 'rx) - (provide 'rx) ;;; rx.el ends here diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 6f392d616d..bab71b522b 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -115,5 +115,46 @@ (ert-deftest rx-seq () ;; Test zero-argument `seq'. (should (equal (rx (seq)) ""))) +(defmacro rx-tests--match (regexp string &optional match) + (macroexp-let2 nil strexp string + `(ert-info ((format "Matching %S to %S" ',regexp ,strexp)) + (should (string-match ,regexp ,strexp)) + ,@(when match + `((should (equal (match-string 0 ,strexp) ,match))))))) + +(ert-deftest rx-nonstring-expr () + (let ((bee "b") + (vowel "[aeiou]")) + (rx-tests--match (rx "a" (literal bee) "c") "abc") + (rx-tests--match (rx "a" (regexp bee) "c") "abc") + (rx-tests--match (rx "a" (or (regexp bee) "xy") "c") "abc") + (rx-tests--match (rx "a" (or "xy" (regexp bee)) "c") "abc") + (should-not (string-match (rx (or (regexp bee) "xy")) "")) + (rx-tests--match (rx "a" (= 3 (regexp bee)) "c") "abbbc") + (rx-tests--match (rx "x" (= 3 (regexp vowel)) "z") "xeoez") + (should-not (string-match (rx "x" (= 3 (regexp vowel)) "z") "xe[]z")) + (rx-tests--match (rx "x" (= 3 (literal vowel)) "z") + "x[aeiou][aeiou][aeiou]z") + (rx-tests--match (rx "x" (repeat 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (repeat 1 2 (regexp vowel)) "z") "xauz") + (rx-tests--match (rx "x" (>= 1 (regexp vowel)) "z") "xaiiz") + (rx-tests--match (rx "x" (** 1 2 (regexp vowel)) "z") "xaiz") + (rx-tests--match (rx "x" (group (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (group-n 1 (regexp vowel)) "z") "xaz") + (rx-tests--match (rx "x" (? (regexp vowel)) "z") "xz"))) + +(ert-deftest rx-nonstring-expr-non-greedy () + "`rx's greediness can't affect runtime regexp parts." + (let ((ad-min "[ad]*?") + (ad-max "[ad]*") + (ad "[ad]")) + (rx-tests--match (rx "c" (regexp ad-min) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (regexp ad-max) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (minimal-match (regexp ad-max)) "a") "cdaaada" "cdaaada") + (rx-tests--match (rx "c" (maximal-match (regexp ad-min)) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (minimal-match (0+ (regexp ad))) "a") "cdaaada" "cda") + (rx-tests--match (rx "c" (maximal-match (0+ (regexp ad))) "a") "cdaaada" "cdaaada"))) + (provide 'rx-tests) ;; rx-tests.el ends here. -- 2.11.0 --=-=-=-- From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 24 Jun 2019 03:51:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Noam Postavsky Cc: Michael Heerdegen , Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.15613482103588 (code B ref 36237); Mon, 24 Jun 2019 03:51:01 +0000 Received: (at 36237) by debbugs.gnu.org; 24 Jun 2019 03:50:10 +0000 Received: from localhost ([127.0.0.1]:55380 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hfFzd-0000vo-Km for submit@debbugs.gnu.org; Sun, 23 Jun 2019 23:50:09 -0400 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:62921) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hfFzc-0000vY-2k for 36237@debbugs.gnu.org; Sun, 23 Jun 2019 23:50:08 -0400 Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id B1A151009BB; Sun, 23 Jun 2019 23:50:02 -0400 (EDT) Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id B54DE100944; Sun, 23 Jun 2019 23:50:01 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1561348201; bh=qmPDO6sigsrjWdBCm4Zf6W3Kn91/a5UxBqqeryGmyME=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=CIABJOOpt2KylXtSXdJKdIbA8gImNtIJBF7UN9yJUaQ5SU9iU3uZKApXPWlo1cbFk 2TxnZ8k0K81p28Go92miM7P7tqY5xXVR+Eon+KlfAYWNctjuWIvX0H7fcjYXYwOwTD np9YG2ftMibqvIb1aWllQIzT6Aksmg8xSvRf8FIOJEMx43+bssBW9HvCz39XQL9Ubx Yzt/UW0mVokgHhSWPEFBinZPgEJi8VsleLBMJp15bOjxMRPxEqEyLT2QdBO7S6ckwW dEVAczzSWFfv8/D1SIT1dt7l1VfWwpAZMp3cdJnyCKLeGocpHZG5ajJjQlL/e+E9X4 2KfnRQDb4kYBg== Received: from alfajor (104-195-207-100.cpe.teksavvy.com [104.195.207.100]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 559B412058A; Sun, 23 Jun 2019 23:50:01 -0400 (EDT) From: Stefan Monnier Message-ID: References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> <877e9duvg9.fsf@gmail.com> <5B00DCD9-0718-44AF-89C1-110CFDC17444@acm.org> <87ef3ktidf.fsf@gmail.com> Date: Sun, 23 Jun 2019 23:50:00 -0400 In-Reply-To: <87ef3ktidf.fsf@gmail.com> (Noam Postavsky's message of "Sun, 23 Jun 2019 11:46:04 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP AWL 0.107 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain X-SPAM-LEVEL: X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) > Well, the rest of the rx docstring uses SEXP for the `rx' > whatchamacallits, FWIW, I think `RX` would make sense for them. Stefan From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 24 Jun 2019 10:54:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Stefan Monnier Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Noam Postavsky , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156137359229952 (code B ref 36237); Mon, 24 Jun 2019 10:54:02 +0000 Received: (at 36237) by debbugs.gnu.org; 24 Jun 2019 10:53:12 +0000 Received: from localhost ([127.0.0.1]:55635 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hfMb2-0007n2-JQ for submit@debbugs.gnu.org; Mon, 24 Jun 2019 06:53:12 -0400 Received: from mail1423c50.megamailservers.eu ([91.136.14.23]:44282 helo=mail102c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hfMaz-0007ml-Q1 for 36237@debbugs.gnu.org; Mon, 24 Jun 2019 06:53:11 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1561373582; bh=+R+93uWyjb8ekyXfzUKh17UxgXf6PGLUPlD2MCN399E=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=d0LPWvZayKt8DvNz3qjloClmUAw846DQoEE614NNMIvvTBGm262aS0GGlj0H2tAZY 2leb9fLqaGS892n41u7zZ24TYKvso5RFhPuUYlQTErSnyvNK+XMSILAT6pc1qXd7OE 8vR+XLU+82pTz8fErSAUMaNxRUQ1g+yMHvtkr2gg= Feedback-ID: mattiase@acm.or Received: from [192.168.0.4] ([188.150.171.71]) (authenticated bits=0) by mail102c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x5OAqwu6002106; Mon, 24 Jun 2019 10:53:01 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= In-Reply-To: Date: Mon, 24 Jun 2019 12:52:57 +0200 Content-Transfer-Encoding: 7bit Message-Id: <0137D2C1-02DA-4F53-AAD0-FF1DB6E8F022@acm.org> References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> <877e9duvg9.fsf@gmail.com> <5B00DCD9-0718-44AF-89C1-110CFDC17444@acm.org> <87ef3ktidf.fsf@gmail.com> X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B020C.5D10AB8E.006A, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=RfS+9Wlv c=1 sm=1 tr=0 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=iRZporoAAAAA:8 a=z16Wk9wdMDSRfnHKZDkA:9 a=CjuIK1q_8ugA:10 a=NOBgFS-JBQ2l-kSd6-zu:22 X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) 24 juni 2019 kl. 05.50 skrev Stefan Monnier : > >> Well, the rest of the rx docstring uses SEXP for the `rx' >> whatchamacallits, > > FWIW, I think `RX` would make sense for them. Agreed; ry uses RX in its doc strings. From debbugs-submit-bounces@debbugs.gnu.org Tue Jun 25 07:10:39 2019 Received: (at control) by debbugs.gnu.org; 25 Jun 2019 11:10:39 +0000 Received: from localhost ([127.0.0.1]:58736 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hfjLS-0000zw-N7 for submit@debbugs.gnu.org; Tue, 25 Jun 2019 07:10:38 -0400 Received: from mail154c50.megamailservers.eu ([91.136.10.164]:38194 helo=mail50c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hfjLR-0000zk-3N for control@debbugs.gnu.org; Tue, 25 Jun 2019 07:10:38 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1561461034; bh=7zhQCvfiXEGya+spOFtaB9GT9595IS8tcFamMT9xAdI=; h=From:Subject:Date:To:From; b=EUUGbRmNV5b7SMxlOTbZje87gDfQhpTJvSMKQaGr+RphaCA5PiRcpYeMW8/WzZxP+ x+A1FV2gPsdVhmkRapJStiPIkZJJg7efWlFeRjfe90yI28NJrASGWXGuRJW5HkWe8M Tl7VVoEUTZey44N3XDNwFQHmlsy+zOdnyU4Bszdw= Feedback-ID: mattiase@acm.or Received: from [192.168.0.4] ([188.150.171.71]) (authenticated bits=0) by mail50c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x5PBA3we015433 for ; Tue, 25 Jun 2019 11:10:19 +0000 From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Subject: merge bug#6985 and bug#36237 Message-Id: <739B4405-91CE-4959-A4AA-B20F43A2C77D@acm.org> Date: Tue, 25 Jun 2019 13:10:02 +0200 To: control@debbugs.gnu.org X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0215.5D12011B.0039, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=U/y889ju c=1 sm=1 tr=0 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17 a=kj9zAlcOel0A:10 a=rd3u-HMx5ZKSivniw9QA:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 0.3 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) merge 6985 36237 thanks From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 26 Jun 2019 02:09:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156151488929692 (code B ref 36237); Wed, 26 Jun 2019 02:09:02 +0000 Received: (at 36237) by debbugs.gnu.org; 26 Jun 2019 02:08:09 +0000 Received: from localhost ([127.0.0.1]:33969 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hfxM1-0007il-3w for submit@debbugs.gnu.org; Tue, 25 Jun 2019 22:08:09 -0400 Received: from mail-io1-f53.google.com ([209.85.166.53]:36167) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hfxLt-0007i3-M5; Tue, 25 Jun 2019 22:08:04 -0400 Received: by mail-io1-f53.google.com with SMTP id h6so1584131ioh.3; Tue, 25 Jun 2019 19:08:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=4m7dV8mNPwdUGzC+abI6tCvQPBrsXSIu80iLK+8fdR8=; b=fqYOh3UnjqXAc1VCCMkhIQaXEQOSYD56DSpfxXHXMjLr9GgLt/G7s8AohebLVl8Klr Gxso/ovUheqkYN6PwDHk0kPhDM+mNxTjLG1g83f+p/y7HiUvKfOrmFv5tleknjctUE+v 6Gn+CWX5EWzeRnBNGwuVw93BXqVa5ZDzO3pIoe3UMh8HhnME5kKBY+qGAcw/R9XYkHBf sdMRiFuvwgtMafjQ8lQ9LEhLU1E0cc31etoQop1FwxwE2gwuJfn7fALX18MrxBQ1WyQd MTWrnAfEsBsQ4T5pUn/221bAEaoDy+DiHCHITGjTAoi98uvbbiV+POe7uDjYk4IMKtPl f85A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=4m7dV8mNPwdUGzC+abI6tCvQPBrsXSIu80iLK+8fdR8=; b=fwoNbIL+T7YnHIUiApM07CCzDK8I7ptnvMyjYoOWtGnXkJF7dcuAIfSNmJdZGTRmN2 UTnIScygiN0Ifv/m4FlkJZxFCcdw9aKJoLv+06WFaQX2BpiBeugPyB4L+EhUSIPpq5Jd oWwUCPfmJgyX4bO1q5C2PXm6c5Op+d1F+3c7bovX4Nm5lSUSxjnXfhxuufkWeX0FxZVf 3Qu+Gnc8bSReP/DCewtu8hzKB+t6cnxxiJwj+A0hYdMw3Ebm3rHoIVd9w+ER8D6PF/md lVTeneKN1qb1EnQ6DuwJPbIzcGZhu8ONppjwNTdJmYzCHHW2pXKELjDrGtrWA3hmDazO xOTA== X-Gm-Message-State: APjAAAXTV/pME3YSJQxIznXlHIZDUvMC6ehrhzNzLO92qNe/SvQ06PxB KpQpzHJ4mm3hiuQdv8CepP79SHpV X-Google-Smtp-Source: APXvYqw2GmE0KKYK7bEg5B5VCn7qTLK6NvYUxrpbFikJXgobxMQJhBXpYk0JusP/S964TrVjEumKSA== X-Received: by 2002:a02:c646:: with SMTP id k6mr1745379jan.134.1561514876006; Tue, 25 Jun 2019 19:07:56 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id l2sm12338383ioh.20.2019.06.25.19.07.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Jun 2019 19:07:54 -0700 (PDT) From: Noam Postavsky References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> <877e9duvg9.fsf@gmail.com> <5B00DCD9-0718-44AF-89C1-110CFDC17444@acm.org> <87ef3ktidf.fsf@gmail.com> Date: Tue, 25 Jun 2019 22:07:53 -0400 In-Reply-To: <87ef3ktidf.fsf@gmail.com> (Noam Postavsky's message of "Sun, 23 Jun 2019 11:46:04 -0400") Message-ID: <87ftnxrtdy.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) tags 36237 fixed close 36237 27.1 quit > I'll wait a few more days in case something else comes up. Pushed to master. b59ffd2290 2019-06-25T22:00:03-04:00 "Support (rx (and (regexp EXPR) (literal EXPR))) (Bug#36237)" https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=b59ffd2290ff744ca4e7cc2748ba6b66fb2f99f1 From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) In-Reply-To: <87v9x6xvml.fsf@gmail.com> Resent-From: Andy Moreton Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 26 Jun 2019 12:25:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: fixed patch To: 36237@debbugs.gnu.org X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.156155185912121 (code B ref -1); Wed, 26 Jun 2019 12:25:01 +0000 Received: (at submit) by debbugs.gnu.org; 26 Jun 2019 12:24:19 +0000 Received: from localhost ([127.0.0.1]:34452 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg6yI-00039R-On for submit@debbugs.gnu.org; Wed, 26 Jun 2019 08:24:18 -0400 Received: from lists.gnu.org ([209.51.188.17]:43713) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg6yG-00039J-PE for submit@debbugs.gnu.org; Wed, 26 Jun 2019 08:24:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52789) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hg6yE-0008BR-TU for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 08:24:16 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RDNS_DYNAMIC,URIBL_BLOCKED autolearn=disabled version=3.3.2 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hg6yD-0004R0-7u for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 08:24:14 -0400 Received: from 195-159-176-226.customer.powertech.no ([195.159.176.226]:44394 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hg6yC-00042T-RR for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 08:24:13 -0400 Received: from list by blaine.gmane.org with local (Exim 4.89) (envelope-from ) id 1hg6xz-000bj4-F8 for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 14:23:59 +0200 X-Injected-Via-Gmane: http://gmane.org/ From: Andy Moreton Date: Wed, 26 Jun 2019 13:23:53 +0100 Message-ID: References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> <877e9duvg9.fsf@gmail.com> <5B00DCD9-0718-44AF-89C1-110CFDC17444@acm.org> <87ef3ktidf.fsf@gmail.com> <87ftnxrtdy.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (windows-nt) Cancel-Lock: sha1:9qTQrdvV92z9qeW2wasGtQZkn64= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 195.159.176.226 X-Spam-Score: -0.8 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.8 (-) On Tue 25 Jun 2019, Noam Postavsky wrote: > tags 36237 fixed > close 36237 27.1 > quit > >> I'll wait a few more days in case something else comes up. > > Pushed to master. > > b59ffd2290 2019-06-25T22:00:03-04:00 "Support (rx (and (regexp EXPR) (literal EXPR))) (Bug#36237)" > https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=b59ffd2290ff744ca4e7cc2748ba6b66fb2f99f1 With "emacs -Q" from emacs-26: (setq foo (rx (group (or "abc" "def")))) => "\\(\\(?:abc\\|def\\)\\)" (setq bar (rx-to-string `(regexp ,foo))) => "\\(?:\\(\\(?:abc\\|def\\)\\)\\)" (setq bar (rx (regexp foo))) => error "rx form ‘regexp’ requires args satisfying ‘stringp’" With "emacs -Q from master: (setq foo (rx (group (or "abc" "def")))) => "\\(\\(?:abc\\|def\\)\\)" (setq bar (rx-to-string `(regexp ,foo))) => ("\\(?:" "\\)") ; unexpected result (setq bar (rx (regexp foo))) => "\\(?:\\(\\(?:abc\\|def\\)\\)\\)" Please fix this regression. AndyM From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 26 Jun 2019 12:57:05 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: fixed patch To: Andy Moreton Cc: 36237@debbugs.gnu.org Received: via spool by 36237-submit@debbugs.gnu.org id=B36237.156155378514979 (code B ref 36237); Wed, 26 Jun 2019 12:57:05 +0000 Received: (at 36237) by debbugs.gnu.org; 26 Jun 2019 12:56:25 +0000 Received: from localhost ([127.0.0.1]:34476 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg7TM-0003tX-TC for submit@debbugs.gnu.org; Wed, 26 Jun 2019 08:56:25 -0400 Received: from mail-io1-f43.google.com ([209.85.166.43]:35652) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg7TK-0003t7-Kd for 36237@debbugs.gnu.org; Wed, 26 Jun 2019 08:56:22 -0400 Received: by mail-io1-f43.google.com with SMTP id m24so1531523ioo.2 for <36237@debbugs.gnu.org>; Wed, 26 Jun 2019 05:56:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:in-reply-to:references:user-agent:date :message-id:mime-version; bh=+H087QcJ9pQgml3Mzrtrx+aqWvqUTZ6S3sQPid7pvRo=; b=njbcsmZr3b3Hpe7SGVueIewqgQ6HUVw0TIeVpOfQ65py78Dt5N2VarX9nYTy0DxTlS k4X6AJjowTmjQ7o4t5sOq31ANhxehF4umXNk1VlZQvIoi0Czugk1NW1l5quIZnmV4nie K3/wRReF1mQeOWi2/vlCbnDFgq4NAIx2V5ud0OPHt6GUzM/paExJsb24tGAuC8lDGmob +1prYYiLnYiWrYVf35jvvVHYNBTX8QzRKAmGdb+RKdNlR+m6OWQy4KPvHg86Zy2l+r0I IarELx25+32Qktpecvzxp1aWiYuUu4QYnImWVLM6GYnbxdfJvAmKqXtm01V2f4JvLME8 Hdpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references :user-agent:date:message-id:mime-version; bh=+H087QcJ9pQgml3Mzrtrx+aqWvqUTZ6S3sQPid7pvRo=; b=e7oqzmD/j69H2h06Rmh2hY0TCPq8oYW9F/WPIia2SrYaZ1n50KPKF4Q2S8IHcNvAt4 PnTNb/D5f9oDnZK15RG+gJCGt3BRQA3m1UBBvV9MSuM8o+TFFwsICYJ2HCskPc4rSHqO bLdIxuHuoVAfByiYeiYYuZE/RAh67/bEl7VVkxLMGMGaEgYE5SDmvIpeJ7Ngw6i8uMr5 Iv7/wjWdDz52cxhyKo0UwLr3Gb3GSsv5cZQKNrfex9cSSyL3DUVRkxF0aOK5WwfnpG5m sKl0rsQS5FatkDNsb8/5SBLS1oUqqVB4z8pnXcuhD3BpMQRUO4F5OW1qEgZVO+Uq75S8 k7Ng== X-Gm-Message-State: APjAAAUw0Mdq92YPWL5FaX5zfq+fai35DdGc5mTnYQqoQHQZlikwoD8i EI7eLGF28FtDvs0ASF4UDLjJWYl/ X-Google-Smtp-Source: APXvYqyRmYMwcgUR0MMIcOHcTGNd3Frm1S2hMvhI3McPDrBHALr3TqaUh2tRcYSmmALm50D6NcGA6g== X-Received: by 2002:a05:6638:63a:: with SMTP id h26mr4649667jar.92.1561553776602; Wed, 26 Jun 2019 05:56:16 -0700 (PDT) Received: from minid (cbl-45-2-119-34.yyz.frontiernetworks.ca. [45.2.119.34]) by smtp.gmail.com with ESMTPSA id r139sm35187190iod.61.2019.06.26.05.56.14 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 26 Jun 2019 05:56:15 -0700 (PDT) From: Noam Postavsky In-Reply-To: (Andy Moreton's message of "Wed, 26 Jun 2019 13:23:53 +0100") References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> <877e9duvg9.fsf@gmail.com> <5B00DCD9-0718-44AF-89C1-110CFDC17444@acm.org> <87ef3ktidf.fsf@gmail.com> <87ftnxrtdy.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) Date: Wed, 26 Jun 2019 08:56:11 -0400 Message-ID: <871rzgtsic.fsf@gmail.com> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Andy Moreton writes: > (setq bar (rx-to-string `(regexp ,foo))) > => ("\\(?:" "\\)") ; unexpected result Oops, should be fixed now. 9233865b70 2019-06-26T08:50:27-04:00 "Fix (rx-to-string (and (literal STR) (regexp STR)) regression" https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=9233865b7005831e63755eb84ae7da060f878a55 From unknown Sat Jun 14 19:39:04 2025 X-Loop: help-debbugs@gnu.org Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) In-Reply-To: <87v9x6xvml.fsf@gmail.com> Resent-From: Andy Moreton Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 26 Jun 2019 13:09:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 36237 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: fixed patch To: 36237@debbugs.gnu.org X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.156155454016117 (code B ref -1); Wed, 26 Jun 2019 13:09:01 +0000 Received: (at submit) by debbugs.gnu.org; 26 Jun 2019 13:09:00 +0000 Received: from localhost ([127.0.0.1]:34485 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg7fY-0004Bt-1c for submit@debbugs.gnu.org; Wed, 26 Jun 2019 09:09:00 -0400 Received: from lists.gnu.org ([209.51.188.17]:59304) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hg7fV-0004Bl-B8 for submit@debbugs.gnu.org; Wed, 26 Jun 2019 09:08:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:35299) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hg7fU-0005rb-A1 for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 09:08:57 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RDNS_DYNAMIC,URIBL_BLOCKED autolearn=disabled version=3.3.2 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hg7fT-00057x-94 for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 09:08:56 -0400 Received: from 195-159-176-226.customer.powertech.no ([195.159.176.226]:47436 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hg7fT-000560-2L for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 09:08:55 -0400 Received: from list by blaine.gmane.org with local (Exim 4.89) (envelope-from ) id 1hg7fR-000Kn3-9d for bug-gnu-emacs@gnu.org; Wed, 26 Jun 2019 15:08:53 +0200 X-Injected-Via-Gmane: http://gmane.org/ From: Andy Moreton Date: Wed, 26 Jun 2019 14:08:47 +0100 Message-ID: References: <87fto9yawl.fsf@gmail.com> <385FA4F7-7FB5-43A2-B571-CFBA20B24123@acm.org> <87tvcmwe6b.fsf@gmail.com> <87o92tw13b.fsf@gmail.com> <877e9duvg9.fsf@gmail.com> <5B00DCD9-0718-44AF-89C1-110CFDC17444@acm.org> <87ef3ktidf.fsf@gmail.com> <87ftnxrtdy.fsf@gmail.com> <871rzgtsic.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (windows-nt) Cancel-Lock: sha1:vVHlNxkDrn0kux01XCrGZncggW4= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 195.159.176.226 X-Spam-Score: -0.8 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.8 (-) On Wed 26 Jun 2019, Noam Postavsky wrote: > Andy Moreton writes: > >> (setq bar (rx-to-string `(regexp ,foo))) >> => ("\\(?:" "\\)") ; unexpected result > > Oops, should be fixed now. > > 9233865b70 2019-06-26T08:50:27-04:00 "Fix (rx-to-string (and (literal STR) (regexp STR)) regression" > https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=9233865b7005831e63755eb84ae7da060f878a55 Thanks Noam, that's all back to normal again. AndyM