From unknown Sat Jun 14 18:47:17 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#36237 <36237@debbugs.gnu.org> To: bug#36237 <36237@debbugs.gnu.org> Subject: Status: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Reply-To: bug#36237 <36237@debbugs.gnu.org> Date: Sun, 15 Jun 2025 01:47:17 +0000 retitle 36237 Support (rx (and (regexp EXPR) (regexp-quote EXPR))) reassign 36237 emacs submitter 36237 Noam Postavsky severity 36237 wishlist tag 36237 fixed patch thanks From debbugs-submit-bounces@debbugs.gnu.org Sat Jun 15 19:43:49 2019 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 To: bug-gnu-emacs@gnu.org Subject: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: submit 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 debbugs-submit-bounces@debbugs.gnu.org Sat Jun 15 20:04:00 2019 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 To: Noam Postavsky Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: 36237@debbugs.gnu.org, stefan monnier , =?utf-8?Q?k=C3=A9vin?= le gouguec 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 debbugs-submit-bounces@debbugs.gnu.org Sat Jun 15 20:28:33 2019 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 To: Michael Heerdegen Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: 36237@debbugs.gnu.org, stefan monnier , =?utf-8?Q?k=C3=A9vin?= le gouguec 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 16 06:04:02 2019 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: =?utf-8?Q?Mattias_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\)) Subject: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) Message-Id: Date: Sun, 16 Jun 2019 12:03:53 +0200 To: Noam Postavsky , 36237@debbugs.gnu.org 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 16 07:35:03 2019 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 To: Mattias =?windows-1252?Q?Engdeg=E5rd?= Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Noam Postavsky , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 16 08:26:02 2019 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 To: Stefan Monnier Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , Mattias =?utf-8?Q?Engdeg=C3=A5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 16 08:35:17 2019 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 To: Noam Postavsky Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , Mattias =?windows-1252?Q?Engdeg=E5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 16 15:51:07 2019 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 To: Stefan Monnier Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , Mattias =?utf-8?Q?Engde?= =?utf-8?Q?g=C3=A5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 16 16:05:17 2019 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 To: Noam Postavsky Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , Mattias =?windows-1252?Q?Engdeg=E5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 16 16:25:15 2019 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 To: Noam Postavsky , Stefan Monnier Subject: RE: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , =?iso-8859-1?B?TWF0dGlhcyBFbmdkZWflcmQ=?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 16 16:34:17 2019 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\)) Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) From: =?utf-8?Q?Mattias_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> To: Drew Adams 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com, Noam Postavsky , Stefan Monnier 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 16 17:10:08 2019 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 To: =?iso-8859-1?B?TWF0dGlhcyBFbmdkZWflcmQ=?= Subject: RE: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com, Noam Postavsky , Stefan Monnier 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 debbugs-submit-bounces@debbugs.gnu.org Mon Jun 17 18:13:16 2019 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 To: Drew Adams Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , Mattias =?iso-8859-1?Q?Engdeg=E5rd?= , Noam Postavsky , Stefan Monnier , kevin.legouguec@gmail.com, 36237@debbugs.gnu.org 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 debbugs-submit-bounces@debbugs.gnu.org Tue Jun 18 15:46:07 2019 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\)) Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) From: =?utf-8?Q?Mattias_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> To: Noam Postavsky 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Tue Jun 18 21:35:05 2019 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 To: Mattias =?utf-8?Q?Engdeg=C3=A5rd?= Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Wed Jun 19 11:43:07 2019 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\)) Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) From: =?utf-8?Q?Mattias_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> To: Noam Postavsky 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Wed Jun 19 20:29:56 2019 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 To: Mattias =?utf-8?Q?Engdeg=C3=A5rd?= Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Thu Jun 20 06:26:38 2019 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\)) Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) From: =?utf-8?Q?Mattias_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> To: Noam Postavsky 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sat Jun 22 18:06:09 2019 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 To: Mattias =?utf-8?Q?Engdeg=C3=A5rd?= Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 23 07:09:54 2019 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\)) Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) From: =?utf-8?Q?Mattias_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> To: Noam Postavsky 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 23 10:45:59 2019 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 To: Noam Postavsky , =?utf-8?B?TWF0dGlhcyBFbmdkZWfDpXJk?= Subject: RE: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 23 11:46:16 2019 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 To: Mattias =?utf-8?Q?Engdeg=C3=A5rd?= Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Sun Jun 23 23:50:09 2019 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 To: Noam Postavsky Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , Mattias =?windows-1252?Q?Engdeg=E5rd?= , 36237@debbugs.gnu.org, kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Mon Jun 24 06:53:12 2019 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\)) Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) From: =?utf-8?Q?Mattias_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> To: Stefan Monnier 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Noam Postavsky , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Tue Jun 25 22:08:09 2019 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 To: Mattias =?utf-8?Q?Engdeg=C3=A5rd?= Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: Michael Heerdegen , 36237@debbugs.gnu.org, Stefan Monnier , kevin.legouguec@gmail.com 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 debbugs-submit-bounces@debbugs.gnu.org Wed Jun 26 08:24:19 2019 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/ To: bug-gnu-emacs@gnu.org From: Andy Moreton Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: submit 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 debbugs-submit-bounces@debbugs.gnu.org Wed Jun 26 08:56:25 2019 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 To: Andy Moreton Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: 36237 Cc: 36237@debbugs.gnu.org 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 debbugs-submit-bounces@debbugs.gnu.org Wed Jun 26 09:09:00 2019 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/ To: bug-gnu-emacs@gnu.org From: Andy Moreton Subject: Re: bug#36237: Support (rx (and (regexp EXPR) (regexp-quote EXPR))) 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-Debbugs-Envelope-To: submit 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 From unknown Sat Jun 14 18:47:17 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Thu, 25 Jul 2019 11:24:09 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator