From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Newsgroups: gmane.emacs.bugs Subject: bug#37849: composable character alternatives in rx Date: Mon, 21 Oct 2019 12:24:21 +0200 Message-ID: <0F77D35E-52A7-4332-913E-DDD286461F00@acm.org> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_A5D7A71E-F7D3-4086-A2E5-8E608F8FFC42" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="150150"; mail-complaints-to="usenet@blaine.gmane.org" To: 37849@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Oct 21 12:25:29 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1iMUsS-000cv1-PB for geb-bug-gnu-emacs@m.gmane.org; Mon, 21 Oct 2019 12:25:29 +0200 Original-Received: from localhost ([::1]:37274 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iMUsR-0002az-39 for geb-bug-gnu-emacs@m.gmane.org; Mon, 21 Oct 2019 06:25:27 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:42355) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iMUs4-0002Za-DT for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 06:25:05 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iMUs2-0008JQ-Pr for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 06:25:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:46955) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iMUs2-0008JB-Gj for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 06:25:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1iMUs2-0005VY-6k for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 06:25:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 21 Oct 2019 10:25:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 37849 X-GNU-PR-Package: emacs X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.157165347521099 (code B ref -1); Mon, 21 Oct 2019 10:25:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 21 Oct 2019 10:24:35 +0000 Original-Received: from localhost ([127.0.0.1]:55773 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMUra-0005UF-PG for submit@debbugs.gnu.org; Mon, 21 Oct 2019 06:24:35 -0400 Original-Received: from lists.gnu.org ([209.51.188.17]:35453) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMUrY-0005U8-D0 for submit@debbugs.gnu.org; Mon, 21 Oct 2019 06:24:32 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:42263) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iMUrW-0001zR-Ny for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 06:24:32 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iMUrV-000896-73 for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 06:24:30 -0400 Original-Received: from mail80c50.megamailservers.eu ([91.136.10.90]:35876 helo=mail70c50.megamailservers.eu) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iMUrU-00088U-Hi for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 06:24:29 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1571653463; bh=MS/WJe3Oxd/r0y2NU7gp+9E+RjbxurZ8DttwaqM7+dU=; h=From:Subject:Date:To:From; b=GHa5iJLH4b/AvesfV1nJ7Kyg76RgGD9Qw335C9cOQVub3PF89cbM9CY4O+Ycogx4r AZ2B0BH1U9I6cdyjlTGY194VmPlAFMqJxweSSmcOQlrVFSXWS3REDQo46jljDc+9FJ b0ATyFWfV2oLlR8neOkLoFjKZWLpeZIJmUCtoJp4= Feedback-ID: mattiase@acm.or Original-Received: from [192.168.1.64] (c-e636e253.032-75-73746f71.bbcust.telenor.se [83.226.54.230]) (authenticated bits=0) by mail70c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x9LAOLiZ026603 for ; Mon, 21 Oct 2019 10:24:23 +0000 X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0204.5DAD8757.0041, 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-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=c6bVvi1l c=1 sm=1 tr=0 a=M+GU/qJco4WXjv8D6jB2IA==:117 a=M+GU/qJco4WXjv8D6jB2IA==:17 a=M51BFTxLslgA:10 a=OqN6m0tyAAAA:8 a=UhdY8sGSxoVGZ3PE4iEA:9 a=CjuIK1q_8ugA:10 a=zQ3WUrxWzkcA:10 a=NP-Ykj6oU4nmw8ZbQoEA:9 a=B2y7HmGcmWMA:10 a=MNNCb3fd_EpUFEaGHBWG:22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:169896 Archived-At: --Apple-Mail=_A5D7A71E-F7D3-4086-A2E5-8E608F8FFC42 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii Now that rx is user-extendible, some holes are showing. Example (from = python.el): (simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?=3D= ?%))) ;; FIXME: rx should support (not simple-operator). (not-simple-operator . ,(rx (not (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?=3D = ?%)))) (This code uses the old rx-constituents mechanism, but the point applies = equally to new-style definitions.) More generally, there is currently no way to: (1) Get the complement of a defined (any ...) form (2) Get the union of two defined (any ...) forms (3) Get the intersection of two defined (not (any ...)) forms (1), which the example above was about, could be solved by expanding = definitions inside 'not'. This is a step away from the principle that = user-defined things are only allowed where general rx forms are, but = perhaps tolerable. Proposed patch attached. (2) can be solved by expanding definitions inside 'any', and allowing = 'any' inside 'any' (flattening). Not sure I like this. An alternative is to ensure that (or (any X) (any Y)) -> (any X Y), but = then we either need to allow 'or' inside 'not', or add an intersection = operator: (intersect (not (any X)) (not (any Y)) -> (not (any X Y)) We could also make 'not' variadic, turning it into complement-of-union: (not (any A) (any B)) -> (not (any A B)) Olin Shivers's SRE has a complete and closed set of operations on = character sets (https://scsh.net/docu/post/sre.html). That would be = principled and perhaps useful, but difficult to do fully in rx because = not all such expressions can be rendered into Emacs regexps. Nothing = prevents us from making a partial implementation, however. --Apple-Mail=_A5D7A71E-F7D3-4086-A2E5-8E608F8FFC42 Content-Disposition: attachment; filename=0001-Expand-rx-definitions-inside-not.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Expand-rx-definitions-inside-not.patch" Content-Transfer-Encoding: quoted-printable =46rom=20a2f7d4fbe0b1d37c233e0beffc4b2b8fd4df3013=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Fri,=2018=20Oct=202019=2016:03:20=20+0200=0A= Subject:=20[PATCH]=20Expand=20rx=20definitions=20inside=20(not=20...)=0A=0A= *=20lisp/emacs-lisp/rx.el=20(rx--lookup-def,=20rx--expand-def)=0A= (rx--translate-symbol,=20rx--translate-any,=20rx--translate-form):=0A*=20= test/lisp/emacs-lisp/rx-tests.el=20(rx-not,=20rx-def-in-not):=0A*=20= doc/lispref/searching.texi=20(Rx=20Constructs,=20Extending=20Rx):=0A= Allow=20user-defined=20rx=20constructs=20to=20be=20expanded=20inside=20= (not=20...)=0Aforms,=20for=20better=20composability.=0A---=0A=20= doc/lispref/searching.texi=20=20=20=20=20=20=20|=20=20=204=20+-=0A=20= lisp/emacs-lisp/rx.el=20=20=20=20=20=20=20=20=20=20=20=20|=20100=20= ++++++++++++++++++-------------=0A=20test/lisp/emacs-lisp/rx-tests.el=20= |=20=2017=20+++++-=0A=203=20files=20changed,=2077=20insertions(+),=2044=20= deletions(-)=0A=0Adiff=20--git=20a/doc/lispref/searching.texi=20= b/doc/lispref/searching.texi=0Aindex=205178575a3b..74b15cfc7f=20100644=0A= ---=20a/doc/lispref/searching.texi=0A+++=20b/doc/lispref/searching.texi=0A= @@=20-1214,7=20+1214,7=20@@=20Rx=20Constructs=0A=20@item=20@code{(not=20= @var{charspec})}=0A=20@cindex=20@code{not}=20in=20rx=0A=20Match=20a=20= character=20not=20included=20in=20@var{charspec}.=20=20@var{charspec}=20= can=0A-be=20an=20@code{any},=20@code{syntax}=20or=20@code{category}=20= form,=20or=20a=0A+be=20an=20@code{any},=20@code{not},=20@code{syntax}=20= or=20@code{category}=20form,=20or=20a=0A=20character=20class.@*=0A=20= Corresponding=20string=20regexp:=20@samp{[^@dots{}]},=20= @samp{\S@var{code}},=0A=20@samp{\C@var{code}}=0A@@=20-1581,7=20+1581,7=20= @@=20Extending=20Rx=0A=20User-defined=20forms=20are=20allowed=20wherever=20= arbitrary=20@code{rx}=0A=20expressions=20are=20expected;=20for=20= example,=20in=20the=20body=20of=20a=0A=20@code{zero-or-one}=20form,=20= but=20not=20inside=20@code{any}=20or=20@code{category}=0A-forms.=0A= +forms.=20=20They=20are=20also=20allowed=20inside=20@code{not}=20forms.=0A= =20@end=20itemize=0A=20=0A=20@defmac=20rx-define=20name=20[arglist]=20= rx-form=0Adiff=20--git=20a/lisp/emacs-lisp/rx.el=20= b/lisp/emacs-lisp/rx.el=0Aindex=20006a393921..8d8db5f3c4=20100644=0A---=20= a/lisp/emacs-lisp/rx.el=0A+++=20b/lisp/emacs-lisp/rx.el=0A@@=20-122,9=20= +122,27=20@@=20rx--local-definitions=0A=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20as=20the=20rx=20form=20DEF=20(which=20can=20= contain=20members=20of=20ARGS).")=0A=20=0A=20(defsubst=20rx--lookup-def=20= (name)=0A+=20=20"Current=20definition=20of=20NAME:=20(DEF)=20or=20(ARGS=20= DEF),=20or=20nil=20if=20none."=0A=20=20=20(or=20(cdr=20(assq=20name=20= rx--local-definitions))=0A=20=20=20=20=20=20=20(get=20name=20= 'rx-definition)))=0A=20=0A+(defun=20rx--expand-def=20(form)=0A+=20=20= "FORM=20expanded=20(once)=20if=20a=20user-defined=20construct;=20= otherwise=20nil."=0A+=20=20(cond=20((symbolp=20form)=0A+=20=20=20=20=20=20= =20=20=20(let=20((def=20(rx--lookup-def=20form)))=0A+=20=20=20=20=20=20=20= =20=20=20=20(and=20def=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (if=20(cdr=20def)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(error=20"Not=20an=20`rx'=20symbol=20definition:=20%s"=20form)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(car=20def)))))=0A+=20= =20=20=20=20=20=20=20((consp=20form)=0A+=20=20=20=20=20=20=20=20=20(let*=20= ((op=20(car=20form))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (def=20(rx--lookup-def=20op)))=0A+=20=20=20=20=20=20=20=20=20=20=20(and=20= def=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(cdr=20def)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--expand-template=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20op=20(cdr=20form)=20(nth=200=20def)=20(nth=201=20def))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(error=20"Not=20an=20= `rx'=20form=20definition:=20%s"=20op)))))))=0A+=0A=20;;=20TODO:=20= Additions=20to=20consider:=0A=20;;=20-=20A=20construct=20like=20`or'=20= but=20without=20the=20match=20order=20guarantee,=0A=20;;=20=20=20maybe=20= `unordered-or'.=20=20Useful=20for=20composition=20or=20generation=20of=0A= @@=20-155,11=20+173,8=20@@=20rx--translate-symbol=0A=20=20=20=20=20=20=20= ((let=20((class=20(cdr=20(assq=20sym=20rx--char-classes))))=0A=20=20=20=20= =20=20=20=20=20=20(and=20class=20(cons=20(list=20(concat=20"[[:"=20= (symbol-name=20class)=20":]]"))=20t))))=0A=20=0A-=20=20=20=20=20=20((let=20= ((definition=20(rx--lookup-def=20sym)))=0A-=20=20=20=20=20=20=20=20=20= (and=20definition=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20= (cdr=20definition)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(error=20"Not=20an=20`rx'=20symbol=20definition:=20%s"=20sym)=0A-=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate=20(nth=200=20= definition))))))=0A+=20=20=20=20=20=20((let=20((expanded=20= (rx--expand-def=20sym)))=0A+=20=20=20=20=20=20=20=20=20(and=20expanded=20= (rx--translate=20expanded))))=0A=20=0A=20=20=20=20=20=20=20;;=20For=20= compatibility=20with=20old=20rx.=0A=20=20=20=20=20=20=20((let=20((entry=20= (assq=20sym=20rx-constituents)))=0A@@=20-445,21=20+460,26=20@@=20= rx--translate-not=0A=20=20=20=20=20(error=20"rx=20`not'=20form=20takes=20= exactly=20one=20argument"))=0A=20=20=20(let=20((arg=20(car=20body)))=0A=20= =20=20=20=20(cond=0A-=20=20=20=20=20((consp=20arg)=0A-=20=20=20=20=20=20= (pcase=20(car=20arg)=0A-=20=20=20=20=20=20=20=20((or=20'any=20'in=20= 'char)=20(rx--translate-any=20=20=20=20=20=20(not=20negated)=20(cdr=20= arg)))=0A-=20=20=20=20=20=20=20=20('syntax=20=20=20=20=20=20=20=20=20=20=20= =20=20(rx--translate-syntax=20=20=20(not=20negated)=20(cdr=20arg)))=0A-=20= =20=20=20=20=20=20=20('category=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-category=20(not=20negated)=20(cdr=20arg)))=0A-=20=20=20=20= =20=20=20=20('not=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-not=20=20=20=20=20=20(not=20negated)=20(cdr=20arg)))=0A-=20= =20=20=20=20=20=20=20(_=20(error=20"Illegal=20argument=20to=20rx=20= `not':=20%S"=20arg))))=0A+=20=20=20=20=20((and=20(consp=20arg)=0A+=20=20=20= =20=20=20=20=20=20=20=20(pcase=20(car=20arg)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20((or=20'any=20'in=20'char)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(rx--translate-any=20=20=20=20=20=20(not=20negated)=20(cdr=20= arg)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20('syntax=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(rx--translate-syntax=20=20=20(not=20= negated)=20(cdr=20arg)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= ('category=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-category=20(not=20negated)=20(cdr=20arg)))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20('not=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(rx--translate-not=20=20=20=20=20=20(not=20negated)=20(cdr=20= arg))))))=0A+=20=20=20=20=20((let=20((class=20(cdr=20(assq=20arg=20= rx--char-classes))))=0A+=20=20=20=20=20=20=20=20(and=20class=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20(rx--translate-any=20(not=20negated)=20= (list=20class)))))=0A=20=20=20=20=20=20((eq=20arg=20'word-boundary)=0A=20= =20=20=20=20=20=20(rx--translate-symbol=0A=20=20=20=20=20=20=20=20(if=20= negated=20'word-boundary=20'not-word-boundary)))=0A-=20=20=20=20=20(t=0A= -=20=20=20=20=20=20(let=20((class=20(cdr=20(assq=20arg=20= rx--char-classes))))=0A-=20=20=20=20=20=20=20=20(if=20class=0A-=20=20=20=20= =20=20=20=20=20=20=20=20(rx--translate-any=20(not=20negated)=20(list=20= class))=0A-=20=20=20=20=20=20=20=20=20=20(error=20"Illegal=20argument=20= to=20rx=20`not':=20%s"=20arg)))))))=0A+=20=20=20=20=20((let=20((expanded=20= (rx--expand-def=20arg)))=0A+=20=20=20=20=20=20=20=20(and=20expanded=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-not=20negated=20(list=20= expanded)))))=0A+=20=20=20=20=20(t=20(error=20"Illegal=20argument=20to=20= rx=20`not':=20%S"=20arg)))))=0A=20=0A=20(defun=20rx--atomic-regexp=20= (item)=0A=20=20=20"ITEM=20is=20(REGEXP=20.=20PRECEDENCE);=20return=20a=20= regexp=20of=20precedence=20t."=0A@@=20-873,30=20+893,28=20@@=20= rx--translate-form=0A=20=20=20=20=20=20=20((or=20'regexp=20'regex)=20=20=20= =20=20=20(rx--translate-regexp=20body))=0A=20=0A=20=20=20=20=20=20=20(op=0A= -=20=20=20=20=20=20=20(unless=20(symbolp=20op)=0A-=20=20=20=20=20=20=20=20= =20(error=20"Bad=20rx=20operator=20`%S'"=20op))=0A-=20=20=20=20=20=20=20= (let=20((definition=20(rx--lookup-def=20op)))=0A-=20=20=20=20=20=20=20=20= =20(if=20definition=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(cdr=20= definition)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--expand-template=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20op=20body=20(nth=200=20definition)=20(nth=201=20definition)))=0A-=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(error=20"Not=20an=20`rx'=20= form=20definition:=20%s"=20op))=0A-=0A-=20=20=20=20=20=20=20=20=20=20=20= ;;=20For=20compatibility=20with=20old=20rx.=0A-=20=20=20=20=20=20=20=20=20= =20=20(let=20((entry=20(assq=20op=20rx-constituents)))=0A-=20=20=20=20=20= =20=20=20=20=20=20=20=20(if=20(progn=0A-=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(while=20(and=20entry=20(not=20(consp=20(cdr=20= entry))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(setq=20entry=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(if=20(symbolp=20(cdr=20entry))=0A-=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20;;=20Alias=20for=20another=20entry.=0A-=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(assq=20= (cdr=20entry)=20rx-constituents)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Wrong=20type,=20try=20= further=20down=20the=20list.=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(assq=20(car=20entry)=0A-=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(cdr=20(memq=20entry=20rx-constituents))))))=0A= -=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20entry)=0A-=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-compat-form=20= (cdr=20entry)=20form)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (error=20"Unknown=20rx=20form=20`%s'"=20op)))))))))=0A+=20=20=20=20=20=20= =20(cond=0A+=20=20=20=20=20=20=20=20((not=20(symbolp=20op))=20(error=20= "Bad=20rx=20operator=20`%S'"=20op))=0A+=0A+=20=20=20=20=20=20=20=20((let=20= ((expanded=20(rx--expand-def=20form)))=0A+=20=20=20=20=20=20=20=20=20=20=20= (and=20expanded=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate=20expanded))))=0A+=0A+=20=20=20=20=20=20=20=20;;=20For=20= compatibility=20with=20old=20rx.=0A+=20=20=20=20=20=20=20=20((let=20= ((entry=20(assq=20op=20rx-constituents)))=0A+=20=20=20=20=20=20=20=20=20=20= =20(and=20(progn=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (while=20(and=20entry=20(not=20(consp=20(cdr=20entry))))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20entry=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20= (symbolp=20(cdr=20entry))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Alias=20for=20another=20= entry.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(assq=20(cdr=20entry)=20rx-constituents)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20;;=20Wrong=20type,=20try=20further=20down=20the=20list.=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (assq=20(car=20entry)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cdr=20(memq=20= entry=20rx-constituents))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20entry)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-compat-form=20(cdr=20entry)=20form))))=0A+=0A+=20=20=20=20= =20=20=20=20(t=20(error=20"Unknown=20rx=20form=20`%s'"=20op)))))))=0A=20=0A= =20(defconst=20rx--builtin-forms=0A=20=20=20'(seq=20sequence=20:=20and=20= or=20|=20any=20in=20char=20not-char=20not=0Adiff=20--git=20= a/test/lisp/emacs-lisp/rx-tests.el=20b/test/lisp/emacs-lisp/rx-tests.el=0A= index=20ef2541d83a..4ecc805aea=20100644=0A---=20= a/test/lisp/emacs-lisp/rx-tests.el=0A+++=20= b/test/lisp/emacs-lisp/rx-tests.el=0A@@=20-268,7=20+268,9=20@@=20rx-not=0A= =20=20=20(should=20(equal=20(rx=20(not=20(syntax=20punctuation))=20(not=20= (syntax=20escape)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20"\\S.\\S\\"))=0A=20=20=20(should=20(equal=20(rx=20(not=20(category=20= tone-mark))=20(not=20(category=20lao)))=0A-=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"\\C4\\Co")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20"\\C4\\Co"))=0A+=20=20(should=20(equal=20(rx=20(not=20= (not=20ascii))=20(not=20(not=20(not=20(any=20"a-z")))))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20"[[:ascii:]][^a-z]")))=0A=20=0A=20= (ert-deftest=20rx-group=20()=0A=20=20=20(should=20(equal=20(rx=20(group=20= nonl)=20(submatch=20"x")=0A@@=20-404,6=20+406,19=20@@=20= rx-redefine-builtin=0A=20=20=20(should-error=20(rx-let-eval=20= '((not-char=20()=20"x"))=20nil))=0A=20=20=20(should-error=20(rx-let-eval=20= '((not-char=20"x"))=20nil)))=0A=20=0A+(ert-deftest=20rx-def-in-not=20()=0A= +=20=20"Test=20definition=20expansion=20inside=20(not=20...)."=0A+=20=20= (rx-let=20((a=20alpha)=0A+=20=20=20=20=20=20=20=20=20=20=20(b=20(not=20= hex))=0A+=20=20=20=20=20=20=20=20=20=20=20(c=20(not=20(category=20= base)))=0A+=20=20=20=20=20=20=20=20=20=20=20(d=20(x)=20(any=20?a=20x=20= ?z))=0A+=20=20=20=20=20=20=20=20=20=20=20(e=20(x)=20(syntax=20x))=0A+=20=20= =20=20=20=20=20=20=20=20=20(f=20(not=20b)))=0A+=20=20=20=20(should=20= (equal=20(rx=20(not=20a)=20(not=20b)=20(not=20c)=20(not=20f))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[^[:alpha:]][[:xdigit:]]\\c.[^[:xdigit:]]"))=0A+=20=20=20=20(should=20= (equal=20(rx=20(not=20(d=20?m))=20(not=20(e=20symbol)))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20"[^amz]\\S_"))))=0A+=0A=20= (ert-deftest=20rx-constituents=20()=0A=20=20=20(let=20((rx-constituents=0A= =20=20=20=20=20=20=20=20=20=20(append=20'((beta=20.=20gamma)=0A--=20=0A= 2.21.0=20(Apple=20Git-122)=0A=0A= --Apple-Mail=_A5D7A71E-F7D3-4086-A2E5-8E608F8FFC42--