From unknown Fri Jun 20 07:13:29 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#37849 <37849@debbugs.gnu.org> To: bug#37849 <37849@debbugs.gnu.org> Subject: Status: composable character alternatives in rx Reply-To: bug#37849 <37849@debbugs.gnu.org> Date: Fri, 20 Jun 2025 14:13:29 +0000 retitle 37849 composable character alternatives in rx reassign 37849 emacs submitter 37849 Mattias Engdeg=C3=A5rd severity 37849 normal thanks From debbugs-submit-bounces@debbugs.gnu.org Mon Oct 21 06:24:35 2019 Received: (at submit) by debbugs.gnu.org; 21 Oct 2019 10:24:35 +0000 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 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 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 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=BAYES_50,RCVD_IN_DNSWL_LOW, 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 1iMUrV-000896-73 for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 06:24:30 -0400 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 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 From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= Content-Type: multipart/mixed; boundary="Apple-Mail=_A5D7A71E-F7D3-4086-A2E5-8E608F8FFC42" Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Subject: composable character alternatives in rx Message-Id: <0F77D35E-52A7-4332-913E-DDD286461F00@acm.org> Date: Mon, 21 Oct 2019 12:24:21 +0200 To: bug-gnu-emacs@gnu.org 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-Rules: 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-Received-From: 91.136.10.90 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 (--) --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-- From debbugs-submit-bounces@debbugs.gnu.org Sun Oct 27 05:17:49 2019 Received: (at 37849) by debbugs.gnu.org; 27 Oct 2019 09:17:49 +0000 Received: from localhost ([127.0.0.1]:41675 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iOegG-0007Wp-Pb for submit@debbugs.gnu.org; Sun, 27 Oct 2019 05:17:48 -0400 Received: from mail233c50.megamailservers.eu ([91.136.10.243]:49840 helo=mail37c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iOegD-0007Wb-Ey for 37849@debbugs.gnu.org; Sun, 27 Oct 2019 05:17:47 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1572167863; bh=bm+zIcn1nZaWGLDTA9I6Zgm0f/l92ZmbzAYEixuTgnI=; h=From:Subject:Date:To:From; b=Q5EJPUKroq5pZyPdQlQ8LKkDqBAxSWVc3CP7dwhO92B4W68SrtfGGSn51jWFafH+T +zehOCkKyqMXI0wXgMJxUSWuc188cNQQNSlHoDKQi2Sm+Jtbl5pONkYbdboVKRExs5 TSrRcJfUjZjSoP8ZNdQwNBzTADVTVcAORSr9UohY= Feedback-ID: mattiase@acm.or Received: from [192.168.0.4] (c188-150-171-71.bredband.comhem.se [188.150.171.71]) (authenticated bits=0) by mail37c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x9R9Hfna013430 for <37849@debbugs.gnu.org>; Sun, 27 Oct 2019 09:17:42 +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#37849: composable character alternatives in rx Message-Id: Date: Sun, 27 Oct 2019 10:17:40 +0100 To: 37849@debbugs.gnu.org X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B020C.5DB560B7.0003, 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=eN1tc0h1 c=1 sm=1 tr=0 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=1ARHx0tzj0sTjJdY5qkA:9 a=CjuIK1q_8ugA:10 a=pHzHmUro8NiASowvMSCR:22 a=6VlIyEUom7LUIeUMNQJH:22 X-Spam-Score: 0.3 (/) X-Debbugs-Envelope-To: 37849 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 (/) Expansion inside (not ...) should be uncontroversial; now pushed = (cbd439e785). Character set operators (union, intersection, difference) would be = useful. Consider: (rx-define ident-chars (any "a-zA-Z0-9")) (rx-define operator-chars (any ?+ ?- ?* ?/ ?< ?> ?=3D)) There is then currently no way to form the set of characters that = excludes both the above sets. From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 06 16:58:58 2019 Received: (at 37849) by debbugs.gnu.org; 6 Dec 2019 21:58:59 +0000 Received: from localhost ([127.0.0.1]:47124 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1idLco-0005KW-JE for submit@debbugs.gnu.org; Fri, 06 Dec 2019 16:58:58 -0500 Received: from mail1475c50.megamailservers.eu ([91.136.14.75]:35302 helo=mail118c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1idLcm-0005KH-7L for 37849@debbugs.gnu.org; Fri, 06 Dec 2019 16:58:57 -0500 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1575669529; bh=MWkN3K5RwyG/bVLEc/UwuUEmkHsReYSJI8dlyA5qgF0=; h=From:Subject:Date:To:From; b=e9w5JlIfMBLPLVmwyVVx6tDSHt/x0+vdNR/NEROVqOGsISEyaWLXIz7coi9N/+omX FcwkmsO55ORv2c5WkQyTPg7RLjEsU5G3c3id+DwJyxh0wmPYQECLF3JUd/S9kfwO5t anwK936kcaCzAJgb42noETwpASBQtm1qP00Q4OvQ= Feedback-ID: mattiase@acm.or Received: from stanniol.lan (c-6f4fe655.032-75-73746f71.bbcust.telenor.se [85.230.79.111]) (authenticated bits=0) by mail118c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id xB6Lwl7f023924 for <37849@debbugs.gnu.org>; Fri, 6 Dec 2019 21:58:48 +0000 From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= Content-Type: multipart/mixed; boundary="Apple-Mail=_C688033D-9F8B-4891-B400-E7544B217FCA" Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Subject: Re: bug#37849: composable character alternatives in rx Message-Id: Date: Fri, 6 Dec 2019 22:58:46 +0100 To: 37849@debbugs.gnu.org X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B020F.5DEACF19.000A, 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=dLXYZ9Rb c=1 sm=1 tr=0 a=fHaj9vQUQVKQ4sUldAaXuQ==:117 a=fHaj9vQUQVKQ4sUldAaXuQ==:17 a=M51BFTxLslgA:10 a=Z9LDBL19FG3jgPoqjTwA:9 a=CjuIK1q_8ugA:10 a=3tTRy8xHFvmLKJ7eeIsA:9 a=B2y7HmGcmWMA:10 X-Spam-Score: 2.9 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: This patch adds `union' and `intersection' to rx. They both take zero or more charsets as arguments. A charset is either an `any' form that does not contain character classes, a `union' or `intersecti [...] Content analysis details: (2.9 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: megamailservers.eu] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 1.0 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) 1.5 FAKE_REPLY_B No description available. 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-Debbugs-Envelope-To: 37849 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.5 (+) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: This patch adds `union' and `intersection' to rx. They both take zero or more charsets as arguments. A charset is either an `any' form that does not contain character classes, a `union' or `intersecti [...] Content analysis details: (1.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: megamailservers.eu] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 1.0 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -1.0 MAILING_LIST_MULTI Multiple indicators imply a widely-seen list manager 1.5 FAKE_REPLY_B No description available. --Apple-Mail=_C688033D-9F8B-4891-B400-E7544B217FCA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii This patch adds `union' and `intersection' to rx. They both take zero or = more charsets as arguments. A charset is either an `any' form that does = not contain character classes, a `union' or `intersection' form, or a = `not' form with charset argument. Example: (rx (union (any "a-f") (any "b-m"))) =3D> "[a-m]" (rx (intersection (any "a-f") (any "b-m"))) =3D> "[b-f]" The character class limitation stems from the inability to complement or = intersect classes in general. It would be possible to partially lift = this restriction for `union'; it is clear that (rx (union (any "ab" space) (any "bc" space digit))) =3D> "[abc[:space:][:digit:]]" but it makes the facility harder to explain to the user in a way that = makes sense. Still, it could be a future extension. A `difference' operator was not included but could be added; it is = trivially defined in rx as (rx-define difference (a b) (intersection a (not b))) The names `union' and `intersection' are verbose, but should be rare = enough that it's better with something descriptive. SRE, from where the concept was taken, uses `|' and `&' respectively, = and `~' for complement, `-' for difference. --Apple-Mail=_C688033D-9F8B-4891-B400-E7544B217FCA Content-Disposition: attachment; filename=0001-Add-union-and-intersection-to-rx-bug-37849.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Add-union-and-intersection-to-rx-bug-37849.patch" Content-Transfer-Encoding: quoted-printable =46rom=203d3bc1529ae90d3cfd5605055060f14696d815c2=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Fri,=206=20Dec=202019=2022:23:57=20+0100=0A= Subject:=20[PATCH]=20Add=20`union'=20and=20`intersection'=20to=20rx=20= (bug#37849)=0A=0AThese=20character=20set=20operations,=20together=20with=20= `not'=20for=20set=0Acomplement,=20improve=20the=20compositionality=20of=20= rx,=20and=20reduce=20duplication=0Ain=20complicated=20cases.=20=20Named=20= character=20classes=20are=20not=20permitted=20in=0Aset=20operations.=0A=0A= *=20lisp/emacs-lisp/rx.el=20(rx--translate-any):=20Split=20into=20= multiple=0Afunctions.=0A(rx--foldl,=20rx--parse-any,=20rx--generate-alt,=20= rx--intervals-to-alt)=0A(rx--complement-intervals,=20= rx--intersect-intervals)=0A(rx--union-intervals,=20= rx--charset-intervals,=20rx--charset-union)=0A(rx--charset-all,=20= rx--charset-intersection,=20rx--translate-union)=0A= (rx--translate-intersection):=20New.=0A(rx--translate-not,=20= rx--translate-form,=20rx--builtin-forms):=0AAdd=20`union'=20and=20= `intersection'.=0A*=20test/lisp/emacs-lisp/rx-tests.el=20(rx-union=20= ,rx-def-in-union)=0A(rx-intersection,=20rx-def-in-intersection):=20New=20= tests.=0A*=20doc/lispref/searching.texi=20(Rx=20Constructs):=0A*=20= etc/NEWS:=0ADocument=20`union'=20and=20`intersection'.=0A---=0A=20= doc/lispref/searching.texi=20=20=20=20=20=20=20|=20=2014=20+-=0A=20= etc/NEWS=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=207=20+-=0A=20lisp/emacs-lisp/rx.el=20=20=20=20=20=20=20= =20=20=20=20=20|=20302=20+++++++++++++++++++++----------=0A=20= test/lisp/emacs-lisp/rx-tests.el=20|=20=2057=20++++++=0A=204=20files=20= changed,=20284=20insertions(+),=2096=20deletions(-)=0A=0Adiff=20--git=20= a/doc/lispref/searching.texi=20b/doc/lispref/searching.texi=0Aindex=20= 74b15cfc7f..19888e7cfa=20100644=0A---=20a/doc/lispref/searching.texi=0A= +++=20b/doc/lispref/searching.texi=0A@@=20-1214,11=20+1214,21=20@@=20Rx=20= Constructs=0A=20@item=20@code{(not=20@var{charspec})}=0A=20@cindex=20= @code{not}=20in=20rx=0A=20Match=20a=20character=20not=20included=20in=20= @var{charspec}.=20=20@var{charspec}=20can=0A-be=20an=20@code{any},=20= @code{not},=20@code{syntax}=20or=20@code{category}=20form,=20or=20a=0A= -character=20class.@*=0A+be=20an=20@code{any},=20@code{not},=20= @code{union},=20@code{intersection},=0A+@code{syntax}=20or=20= @code{category}=20form,=20or=20a=20character=20class.@*=0A=20= Corresponding=20string=20regexp:=20@samp{[^@dots{}]},=20= @samp{\S@var{code}},=0A=20@samp{\C@var{code}}=0A=20=0A+@item=20= @code{(union=20@var{charset}@dots{})}=0A+@itemx=20@code{(intersection=20= @var{charset}@dots{})}=0A+@cindex=20@code{union}=20in=20rx=0A+@cindex=20= @code{intersection}=20in=20rx=0A+Match=20a=20character=20that=20matches=20= the=20union=20or=20intersection,=0A+respectively,=20of=20the=20= @var{charset}s.=20=20Each=20@var{charset}=20can=20be=20an=0A+@code{any}=20= form=20without=20character=20classes,=20or=20a=20@code{union},=0A= +@code{intersection}=20or=20@code{not}=20form=20whose=20arguments=20are=20= also=0A+@var{charset}s.=0A+=0A=20@item=20@code{not-newline},=20= @code{nonl}=0A=20@cindex=20@code{not-newline}=20in=20rx=0A=20@cindex=20= @code{nonl}=20in=20rx=0Adiff=20--git=20a/etc/NEWS=20b/etc/NEWS=0Aindex=20= 28bcb720cd..fb95a6e704=20100644=0A---=20a/etc/NEWS=0A+++=20b/etc/NEWS=0A= @@=20-2100,9=20+2100,14=20@@=20at=20run=20time,=20instead=20of=20a=20= constant=20string.=0A=20These=20macros=20add=20new=20forms=20to=20the=20= rx=20notation.=0A=20=0A=20+++=0A-***=20'anychar'=20is=20now=20an=20alias=20= for=20'anything'=0A+***=20'anychar'=20is=20now=20an=20alias=20for=20= 'anything'.=0A=20Both=20match=20any=20single=20character;=20'anychar'=20= is=20more=20descriptive.=0A=20=0A++++=0A+***=20New=20'union'=20and=20= 'intersection'=20forms=20for=20character=20sets.=0A+These=20permit=20= composing=20character-matching=20expressions=20from=20simpler=0A+parts.=0A= +=0A=20**=20Frames=0A=20=0A=20+++=0Adiff=20--git=20= a/lisp/emacs-lisp/rx.el=20b/lisp/emacs-lisp/rx.el=0Aindex=20= 0dc6e19866..b17f44f1a7=20100644=0A---=20a/lisp/emacs-lisp/rx.el=0A+++=20= b/lisp/emacs-lisp/rx.el=0A@@=20-246,6=20+246,14=20@@=20rx--every=0A=20=20= =20=20=20(setq=20list=20(cdr=20list)))=0A=20=20=20(null=20list))=0A=20=0A= +(defun=20rx--foldl=20(f=20x=20l)=0A+=20=20"(F=20(F=20(F=20X=20L0)=20L1)=20= L2)=20...=0A+Left-fold=20the=20list=20L,=20starting=20with=20X,=20by=20= the=20binary=20function=20F."=0A+=20=20(while=20l=0A+=20=20=20=20(setq=20= x=20(funcall=20f=20x=20(car=20l)))=0A+=20=20=20=20(setq=20l=20(cdr=20= l)))=0A+=20=20x)=0A+=0A=20(defun=20rx--translate-or=20(body)=0A=20=20=20= "Translate=20an=20or-pattern=20of=20zero=20or=20more=20rx=20items.=0A=20= Return=20(REGEXP=20.=20PRECEDENCE)."=0A@@=20-343,22=20+351,11=20@@=20= rx--condense-intervals=0A=20=20=20=20=20=20=20=20=20(setq=20tail=20d)))=0A= =20=20=20=20=20intervals))=0A=20=0A-;;=20FIXME:=20Consider=20expanding=20= definitions=20inside=20(any=20...)=20and=20(not=20...),=0A-;;=20and=20= perhaps=20allow=20(any=20...)=20inside=20(any=20...).=0A-;;=20It=20would=20= be=20benefit=20composability=20(build=20a=20character=20alternative=20by=20= pieces)=0A-;;=20and=20be=20handy=20for=20obtaining=20the=20complement=20= of=20a=20defined=20set=20of=0A-;;=20characters.=20=20(See,=20for=20= example,=20python.el:421,=20`not-simple-operator'.)=0A-;;=20(Expansion=20= in=20other=20non-rx=20positions=20is=20probably=20not=20a=20good=20idea:=0A= -;;=20syntax,=20category,=20backref,=20and=20the=20integer=20parameters=20= of=20group-n,=0A-;;=20=3D,=20>=3D,=20**,=20repeat)=0A-;;=20Similar=20= effect=20could=20be=20attained=20by=20ensuring=20that=0A-;;=20(or=20(any=20= X)=20(any=20Y))=20->=20(any=20X=20Y),=20and=20find=20a=20way=20to=20= compose=20negative=0A-;;=20sets.=20=20`and'=20is=20taken,=20but=20we=20= could=20add=0A-;;=20(intersection=20(not=20(any=20X))=20(not=20(any=20= Y)))=20->=20(not=20(any=20X=20Y)).=0A-=0A-(defun=20rx--translate-any=20= (negated=20body)=0A-=20=20"Translate=20an=20(any=20...)=20construct.=20=20= Return=20(REGEXP=20.=20PRECEDENCE).=0A-If=20NEGATED,=20negate=20the=20= sense."=0A+(defun=20rx--parse-any=20(body)=0A+=20=20"Parse=20arguments=20= of=20an=20(any=20...)=20construct.=0A+Return=20(INTERVALS=20.=20= CLASSES),=20where=20INTERVALS=20is=20a=20sorted=20list=20of=0A+disjoint=20= intervals=20(each=20a=20cons=20of=20chars),=20and=20CLASSES=0A+a=20list=20= of=20named=20character=20classes=20in=20the=20order=20they=20occur=20in=20= BODY."=0A=20=20=20(let=20((classes=20nil)=0A=20=20=20=20=20=20=20=20=20= (strings=20nil)=0A=20=20=20=20=20=20=20=20=20(conses=20nil))=0A@@=20= -380,81=20+377,109=20@@=20rx--translate-any=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(or=20(memq=20class=20= classes)=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(progn=20(push=20class=20classes)=20t))))))=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20(t=20(error=20"Invalid=20rx=20= `any'=20argument:=20%s"=20arg))))=0A-=20=20=20=20(let=20((items=0A-=20=20= =20=20=20=20=20=20=20=20=20;;=20Translate=20strings=20and=20conses=20= into=20nonoverlapping=20intervals,=0A-=20=20=20=20=20=20=20=20=20=20=20= ;;=20and=20add=20classes=20as=20symbols=20at=20the=20end.=0A-=20=20=20=20= =20=20=20=20=20=20=20(append=0A-=20=20=20=20=20=20=20=20=20=20=20=20= (rx--condense-intervals=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(sort=20= (append=20conses=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(mapcan=20#'rx--string-to-intervals=20= strings))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= #'car-less-than-car))=0A-=20=20=20=20=20=20=20=20=20=20=20=20(reverse=20= classes))))=0A-=0A-=20=20=20=20=20=20;;=20Move=20lone=20]=20and=20range=20= ]-x=20to=20the=20start.=0A-=20=20=20=20=20=20(let=20((rbrac-l=20(assq=20= ?\]=20items)))=0A-=20=20=20=20=20=20=20=20(when=20rbrac-l=0A-=20=20=20=20= =20=20=20=20=20=20(setq=20items=20(cons=20rbrac-l=20(delq=20rbrac-l=20= items)))))=0A-=0A-=20=20=20=20=20=20;;=20Split=20x-]=20and=20move=20the=20= lone=20]=20to=20the=20start.=0A-=20=20=20=20=20=20(let=20((rbrac-r=20= (rassq=20?\]=20items)))=0A-=20=20=20=20=20=20=20=20(when=20(and=20= rbrac-r=20(not=20(eq=20(car=20rbrac-r)=20?\])))=0A-=20=20=20=20=20=20=20=20= =20=20(setcdr=20rbrac-r=20?\\)=0A-=20=20=20=20=20=20=20=20=20=20(setq=20= items=20(cons=20'(?\]=20.=20?\])=20items))))=0A-=0A-=20=20=20=20=20=20;;=20= Split=20,--=20(which=20would=20end=20up=20as=20,-=20otherwise).=0A-=20=20= =20=20=20=20(let=20((dash-r=20(rassq=20?-=20items)))=0A-=20=20=20=20=20=20= =20=20(when=20(eq=20(car=20dash-r)=20?,)=0A-=20=20=20=20=20=20=20=20=20=20= (setcdr=20dash-r=20?,)=0A-=20=20=20=20=20=20=20=20=20=20(setq=20items=20= (nconc=20items=20'((?-=20.=20?-))))))=0A-=0A-=20=20=20=20=20=20;;=20= Remove=20-=20(lone=20or=20at=20start=20of=20interval)=0A-=20=20=20=20=20=20= (let=20((dash-l=20(assq=20?-=20items)))=0A-=20=20=20=20=20=20=20=20(when=20= dash-l=0A-=20=20=20=20=20=20=20=20=20=20(if=20(eq=20(cdr=20dash-l)=20?-)=0A= -=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20items=20(delq=20= dash-l=20items))=20=20=20;=20Remove=20lone=20-=0A-=20=20=20=20=20=20=20=20= =20=20=20=20(setcar=20dash-l=20?.))=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20;=20Reduce=20--x=20to=20.-x=0A-=20=20=20=20=20=20=20=20=20= =20(setq=20items=20(nconc=20items=20'((?-=20.=20?-))))))=0A-=0A-=20=20=20= =20=20=20;;=20Deal=20with=20leading=20^=20and=20range=20^-x.=0A-=20=20=20= =20=20=20(when=20(and=20(consp=20(car=20items))=0A-=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(eq=20(caar=20items)=20?^)=0A-=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(cdr=20items))=0A-=20=20=20=20=20=20=20=20= ;;=20Move=20^=20and=20^-x=20to=20second=20place.=0A-=20=20=20=20=20=20=20= =20(setq=20items=20(cons=20(cadr=20items)=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(cons=20(car=20items)=20= (cddr=20items)))))=0A+=20=20=20=20(cons=20(rx--condense-intervals=0A+=20=20= =20=20=20=20=20=20=20=20=20(sort=20(append=20conses=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(mapcan=20= #'rx--string-to-intervals=20strings))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20#'car-less-than-car))=0A+=20=20=20=20=20=20=20=20=20=20= (reverse=20classes))))=0A+=0A+(defun=20rx--generate-alt=20(negated=20= intervals=20classes)=0A+=20=20"Generate=20a=20character=20alternative.=20= =20Return=20(REGEXP=20.=20PRECEDENCE).=0A+If=20NEGATED=20is=20non-nil,=20= negate=20the=20result;=20INTERVALS=20is=20a=20sorted=0A+list=20of=20= disjoint=20intervals=20and=20CLASSES=20a=20list=20of=20named=20character=0A= +classes."=0A+=20=20(let=20((items=20(append=20intervals=20classes)))=0A= +=20=20=20=20;;=20Move=20lone=20]=20and=20range=20]-x=20to=20the=20= start.=0A+=20=20=20=20(let=20((rbrac-l=20(assq=20?\]=20items)))=0A+=20=20= =20=20=20=20(when=20rbrac-l=0A+=20=20=20=20=20=20=20=20(setq=20items=20= (cons=20rbrac-l=20(delq=20rbrac-l=20items)))))=0A+=0A+=20=20=20=20;;=20= Split=20x-]=20and=20move=20the=20lone=20]=20to=20the=20start.=0A+=20=20=20= =20(let=20((rbrac-r=20(rassq=20?\]=20items)))=0A+=20=20=20=20=20=20(when=20= (and=20rbrac-r=20(not=20(eq=20(car=20rbrac-r)=20?\])))=0A+=20=20=20=20=20= =20=20=20(setcdr=20rbrac-r=20?\\)=0A+=20=20=20=20=20=20=20=20(setq=20= items=20(cons=20'(?\]=20.=20?\])=20items))))=0A+=0A+=20=20=20=20;;=20= Split=20,--=20(which=20would=20end=20up=20as=20,-=20otherwise).=0A+=20=20= =20=20(let=20((dash-r=20(rassq=20?-=20items)))=0A+=20=20=20=20=20=20= (when=20(eq=20(car=20dash-r)=20?,)=0A+=20=20=20=20=20=20=20=20(setcdr=20= dash-r=20?,)=0A+=20=20=20=20=20=20=20=20(setq=20items=20(nconc=20items=20= '((?-=20.=20?-))))))=0A+=0A+=20=20=20=20;;=20Remove=20-=20(lone=20or=20= at=20start=20of=20interval)=0A+=20=20=20=20(let=20((dash-l=20(assq=20?-=20= items)))=0A+=20=20=20=20=20=20(when=20dash-l=0A+=20=20=20=20=20=20=20=20= (if=20(eq=20(cdr=20dash-l)=20?-)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= (setq=20items=20(delq=20dash-l=20items))=20=20=20;=20Remove=20lone=20-=0A= +=20=20=20=20=20=20=20=20=20=20(setcar=20dash-l=20?.))=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20;=20Reduce=20--x=20to=20.-x=0A+=20=20=20= =20=20=20=20=20(setq=20items=20(nconc=20items=20'((?-=20.=20?-))))))=0A+=0A= +=20=20=20=20;;=20Deal=20with=20leading=20^=20and=20range=20^-x.=0A+=20=20= =20=20(when=20(and=20(consp=20(car=20items))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(eq=20(caar=20items)=20?^)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(cdr=20items))=0A+=20=20=20=20=20=20;;=20Move=20^=20= and=20^-x=20to=20second=20place.=0A+=20=20=20=20=20=20(setq=20items=20= (cons=20(cadr=20items)=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(cons=20(car=20items)=20(cddr=20items)))))=0A=20=0A= -=20=20=20=20=20=20(cond=0A-=20=20=20=20=20=20=20;;=20Empty=20set:=20if=20= negated,=20any=20char,=20otherwise=20match-nothing.=0A-=20=20=20=20=20=20= =20((null=20items)=0A-=20=20=20=20=20=20=20=20(if=20negated=0A-=20=20=20=20= =20=20=20=20=20=20=20=20(rx--translate-symbol=20'anything)=0A-=20=20=20=20= =20=20=20=20=20=20(rx--empty)))=0A-=20=20=20=20=20=20=20;;=20Single=20= non-negated=20character.=0A-=20=20=20=20=20=20=20((and=20(null=20(cdr=20= items))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(consp=20(car=20= items))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(eq=20(caar=20items)=20= (cdar=20items))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(not=20= negated))=0A-=20=20=20=20=20=20=20=20(cons=20(list=20(regexp-quote=20= (char-to-string=20(caar=20items))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20= =20=20t))=0A-=20=20=20=20=20=20=20;;=20At=20least=20one=20character=20or=20= class,=20possibly=20negated.=0A-=20=20=20=20=20=20=20(t=0A-=20=20=20=20=20= =20=20=20(cons=0A-=20=20=20=20=20=20=20=20=20(list=0A-=20=20=20=20=20=20=20= =20=20=20(concat=0A-=20=20=20=20=20=20=20=20=20=20=20"["=0A-=20=20=20=20=20= =20=20=20=20=20=20(and=20negated=20"^")=0A-=20=20=20=20=20=20=20=20=20=20= =20(mapconcat=20(lambda=20(item)=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(cond=20((symbolp=20item)=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(format=20"[:%s:]"=20item))=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((eq=20(car=20= item)=20(cdr=20item))=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(char-to-string=20(car=20= item)))=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((eq=20(1+=20(car=20item))=20(cdr=20item))=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(string=20(car=20item)=20(cdr=20item)))=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(t=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(string=20(car=20item)=20?-=20(cdr=20= item)))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20items=20nil)=0A-=20=20=20=20=20=20=20=20=20=20=20"]"))=0A-=20=20=20= =20=20=20=20=20=20t))))))=0A+=20=20=20=20(cond=0A+=20=20=20=20=20;;=20= Empty=20set:=20if=20negated,=20any=20char,=20otherwise=20match-nothing.=0A= +=20=20=20=20=20((null=20items)=0A+=20=20=20=20=20=20(if=20negated=0A+=20= =20=20=20=20=20=20=20=20=20(rx--translate-symbol=20'anything)=0A+=20=20=20= =20=20=20=20=20(rx--empty)))=0A+=20=20=20=20=20;;=20Single=20non-negated=20= character.=0A+=20=20=20=20=20((and=20(null=20(cdr=20items))=0A+=20=20=20=20= =20=20=20=20=20=20=20(consp=20(car=20items))=0A+=20=20=20=20=20=20=20=20=20= =20=20(eq=20(caar=20items)=20(cdar=20items))=0A+=20=20=20=20=20=20=20=20=20= =20=20(not=20negated))=0A+=20=20=20=20=20=20(cons=20(list=20= (regexp-quote=20(char-to-string=20(caar=20items))))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20t))=0A+=20=20=20=20=20;;=20At=20least=20one=20= character=20or=20class,=20possibly=20negated.=0A+=20=20=20=20=20(t=0A+=20= =20=20=20=20=20(cons=0A+=20=20=20=20=20=20=20(list=0A+=20=20=20=20=20=20=20= =20(concat=0A+=20=20=20=20=20=20=20=20=20"["=0A+=20=20=20=20=20=20=20=20=20= (and=20negated=20"^")=0A+=20=20=20=20=20=20=20=20=20(mapconcat=20(lambda=20= (item)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(cond=20((symbolp=20item)=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(format=20"[:%s:]"=20item))=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((eq=20(car=20item)=20(cdr=20item))=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= (char-to-string=20(car=20item)))=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((eq=20(1+=20(car=20item))=20= (cdr=20item))=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(string=20(car=20item)=20(cdr=20item)))=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(t=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(string=20(car=20item)=20?-=20(cdr=20= item)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= items=20nil)=0A+=20=20=20=20=20=20=20=20=20"]"))=0A+=20=20=20=20=20=20=20= t)))))=0A+=0A+(defun=20rx--translate-any=20(negated=20body)=0A+=20=20= "Translate=20an=20(any=20...)=20construct.=20=20Return=20(REGEXP=20.=20= PRECEDENCE).=0A+If=20NEGATED,=20negate=20the=20sense."=0A+=20=20(let=20= ((parsed=20(rx--parse-any=20body)))=0A+=20=20=20=20(rx--generate-alt=20= negated=20(car=20parsed)=20(cdr=20parsed))))=0A+=0A+(defun=20= rx--intervals-to-alt=20(negated=20intervals)=0A+=20=20"Generate=20a=20= character=20alternative=20from=20an=20interval=20set.=0A+Return=20= (REGEXP=20.=20PRECEDENCE).=0A+INTERVALS=20is=20a=20sorted=20list=20of=20= disjoint=20intervals.=0A+If=20NEGATED,=20negate=20the=20sense."=0A+=20=20= ;;=20Detect=20whether=20the=20interval=20set=20is=20better=20described=20= in=0A+=20=20;;=20complemented=20form.=20=20This=20is=20not=20just=20a=20= matter=20of=20aesthetics:=20any=0A+=20=20;;=20range=20from=20ASCII=20to=20= raw=20bytes=20will=20automatically=20exclude=20the=0A+=20=20;;=20entire=20= non-ASCII=20Unicode=20range=20by=20the=20regexp=20engine.=0A+=20=20(if=20= (rx--every=20(lambda=20(iv)=20(not=20(<=3D=20(car=20iv)=20#x3ffeff=20= (cdr=20iv))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= intervals)=0A+=20=20=20=20=20=20(rx--generate-alt=20negated=20intervals=20= nil)=0A+=20=20=20=20(rx--generate-alt=0A+=20=20=20=20=20(not=20negated)=20= (rx--complement-intervals=20intervals)=20nil)))=0A+=0A+;;=20FIXME:=20= Consider=20turning=20`not'=20into=20a=20variadic=20operator,=20following=20= SRE:=0A+;;=20(not=20A=20B)=20=3D=20(not=20(union=20A=20B))=20=3D=20= (intersection=20(not=20A)=20(not=20B)),=20and=0A+;;=20(not)=20=3D=20= anychar.=0A+;;=20Maybe=20allow=20singleton=20characters=20as=20= arguments.=0A=20=0A=20(defun=20rx--translate-not=20(negated=20body)=0A=20= =20=20"Translate=20a=20(not=20...)=20construct.=20=20Return=20(REGEXP=20= .=20PRECEDENCE).=0A@@=20-472,10=20+497,14=20@@=20rx--translate-not=0A=20=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=20(rx--translate-category=20(not=20negated)=20(cdr=20= arg)))=0A=20=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=20= negated)=20(cdr=20arg))))))=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=20arg)))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20('union=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(rx--translate-union=20=20=20=20(not=20negated)=20(cdr=20= arg)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20('intersection=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-intersection=20(not=20= negated)=20(cdr=20arg))))))=0A=20=20=20=20=20=20((let=20((class=20(cdr=20= (assq=20arg=20rx--char-classes))))=0A=20=20=20=20=20=20=20=20=20(and=20= class=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=20=20=20=20=20= =20=20(rx--generate-alt=20(not=20negated)=20nil=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=20negated=20= 'word-boundary=20'not-word-boundary)))=0A@@=20-484,6=20+513,91=20@@=20= rx--translate-not=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-not=20negated=20(list=20expanded)))))=0A=20=20=20=20=20=20= (t=20(error=20"Illegal=20argument=20to=20rx=20`not':=20%S"=20arg)))))=0A=20= =0A+(defun=20rx--complement-intervals=20(intervals)=0A+=20=20"Complement=20= of=20the=20interval=20list=20INTERVALS."=0A+=20=20(let=20((compl=20nil)=0A= +=20=20=20=20=20=20=20=20(c=200))=0A+=20=20=20=20(dolist=20(iv=20= intervals)=0A+=20=20=20=20=20=20(when=20(<=20c=20(car=20iv))=0A+=20=20=20= =20=20=20=20=20(push=20(cons=20c=20(1-=20(car=20iv)))=20compl))=0A+=20=20= =20=20=20=20(setq=20c=20(1+=20(cdr=20iv))))=0A+=20=20=20=20(when=20(<=20= c=20(max-char))=0A+=20=20=20=20=20=20(push=20(cons=20c=20(max-char))=20= compl))=0A+=20=20=20=20(nreverse=20compl)))=0A+=0A+(defun=20= rx--intersect-intervals=20(ivs-a=20ivs-b)=0A+=20=20"Intersection=20of=20= the=20interval=20lists=20IVS-A=20and=20IVS-B."=0A+=20=20(let=20((isect=20= nil))=0A+=20=20=20=20(while=20(and=20ivs-a=20ivs-b)=0A+=20=20=20=20=20=20= (let=20((a=20(car=20ivs-a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20(b=20= (car=20ivs-b)))=0A+=20=20=20=20=20=20=20=20(cond=0A+=20=20=20=20=20=20=20= =20=20((<=20(cdr=20a)=20(car=20b))=20(setq=20ivs-a=20(cdr=20ivs-a)))=0A+=20= =20=20=20=20=20=20=20=20((>=20(car=20a)=20(cdr=20b))=20(setq=20ivs-b=20= (cdr=20ivs-b)))=0A+=20=20=20=20=20=20=20=20=20(t=0A+=20=20=20=20=20=20=20= =20=20=20(push=20(cons=20(max=20(car=20a)=20(car=20b))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(min=20(cdr=20a)=20= (cdr=20b)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20isect)=0A= +=20=20=20=20=20=20=20=20=20=20(setq=20ivs-a=20(cdr=20ivs-a))=0A+=20=20=20= =20=20=20=20=20=20=20(setq=20ivs-b=20(cdr=20ivs-b))=0A+=20=20=20=20=20=20= =20=20=20=20(cond=20((<=20(cdr=20a)=20(cdr=20b))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(push=20(cons=20(1+=20(cdr=20a))=20(cdr=20= b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20ivs-b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((>=20(cdr=20= a)=20(cdr=20b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (push=20(cons=20(1+=20(cdr=20b))=20(cdr=20a))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20ivs-a)))))))=0A+=20=20=20=20= (nreverse=20isect)))=0A+=0A+(defun=20rx--union-intervals=20(ivs-a=20= ivs-b)=0A+=20=20"Union=20of=20the=20interval=20lists=20IVS-A=20and=20= IVS-B."=0A+=20=20(rx--complement-intervals=0A+=20=20=20= (rx--intersect-intervals=0A+=20=20=20=20(rx--complement-intervals=20= ivs-a)=0A+=20=20=20=20(rx--complement-intervals=20ivs-b))))=0A+=0A= +(defun=20rx--charset-intervals=20(charset)=0A+=20=20"Return=20a=20= sorted=20list=20of=20non-adjacent=20disjoint=20intervals=20from=20= CHARSET.=0A+CHARSET=20is=20any=20expression=20allowed=20in=20a=20= character=20set=20expression:=0A+either=20`any'=20(no=20classes=20= permitted),=20or=20`not',=20`union'=20or=20`intersection'=0A+forms=20= whose=20arguments=20are=20charsets."=0A+=20=20(pcase=20charset=0A+=20=20=20= =20(`(,(or=20'any=20'in=20'char)=20.=20,body)=0A+=20=20=20=20=20(let=20= ((parsed=20(rx--parse-any=20body)))=0A+=20=20=20=20=20=20=20(when=20(cdr=20= parsed)=0A+=20=20=20=20=20=20=20=20=20(error=0A+=20=20=20=20=20=20=20=20=20= =20"Character=20class=20not=20permitted=20in=20set=20operations:=20%S"=0A= +=20=20=20=20=20=20=20=20=20=20(cadr=20parsed)))=0A+=20=20=20=20=20=20=20= (car=20parsed)))=0A+=20=20=20=20(`(not=20,x)=20(rx--complement-intervals=20= (rx--charset-intervals=20x)))=0A+=20=20=20=20(`(union=20.=20,xs)=20= (rx--charset-union=20xs))=0A+=20=20=20=20(`(intersection=20.=20,xs)=20= (rx--charset-intersection=20xs))=0A+=20=20=20=20(_=20(let=20((expanded=20= (rx--expand-def=20charset)))=0A+=20=20=20=20=20=20=20=20=20(if=20= expanded=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--charset-intervals=20expanded)=0A+=20=20=20=20=20=20=20=20=20=20=20= (error=20"Bad=20character=20set:=20%S"=20charset))))))=0A+=0A+(defun=20= rx--charset-union=20(charsets)=0A+=20=20"Union=20of=20CHARSETS,=20as=20a=20= set=20of=20intervals."=0A+=20=20(rx--foldl=20#'rx--union-intervals=20nil=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20(mapcar=20= #'rx--charset-intervals=20charsets)))=0A+=0A+(defconst=20rx--charset-all=20= (list=20(cons=200=20(max-char))))=0A+=0A+(defun=20= rx--charset-intersection=20(charsets)=0A+=20=20"Intersection=20of=20= CHARSETS,=20as=20a=20set=20of=20intervals."=0A+=20=20(rx--foldl=20= #'rx--intersect-intervals=20rx--charset-all=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20(mapcar=20#'rx--charset-intervals=20charsets)))=0A+=0A= +(defun=20rx--translate-union=20(negated=20body)=0A+=20=20"Translate=20a=20= (union=20...)=20construct.=20=20Return=20(REGEXP=20.=20PRECEDENCE).=0A= +If=20NEGATED,=20negate=20the=20sense."=0A+=20=20(rx--intervals-to-alt=20= negated=20(rx--charset-union=20body)))=0A+=0A+(defun=20= rx--translate-intersection=20(negated=20body)=0A+=20=20"Translate=20an=20= (intersection=20...)=20construct.=20=20Return=20(REGEXP=20.=20= PRECEDENCE).=0A+If=20NEGATED,=20negate=20the=20sense."=0A+=20=20= (rx--intervals-to-alt=20negated=20(rx--charset-intersection=20body)))=0A= +=0A=20(defun=20rx--atomic-regexp=20(item)=0A=20=20=20"ITEM=20is=20= (REGEXP=20.=20PRECEDENCE);=20return=20a=20regexp=20of=20precedence=20t."=0A= =20=20=20(if=20(eq=20(cdr=20item)=20t)=0A@@=20-862,6=20+976,8=20@@=20= rx--translate-form=0A=20=20=20=20=20=20=20((or=20'any=20'in=20'char)=20=20= =20=20=20=20(rx--translate-any=20nil=20body))=0A=20=20=20=20=20=20=20= ('not-char=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-any=20t=20body))=0A=20=20=20=20=20=20=20('not=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-not=20nil=20= body))=0A+=20=20=20=20=20=20('union=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(rx--translate-union=20nil=20body))=0A+=20=20=20=20=20=20= ('intersection=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-intersection=20nil=20body))=0A=20=0A=20=20=20=20=20=20=20= ('repeat=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-repeat=20body))=0A=20=20=20=20=20=20=20('=3D=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-=3D=20= body))=0A@@=20-920,7=20+1036,7=20@@=20rx--translate-form=0A=20=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'(seq=20sequence=20:=20and=20= or=20|=20any=20in=20char=20not-char=20not=0A+=20=20'(seq=20sequence=20:=20= and=20or=20|=20any=20in=20char=20not-char=20not=20union=20intersection=0A= =20=20=20=20=20repeat=20=3D=20>=3D=20**=0A=20=20=20=20=20zero-or-more=20= 0+=20*=0A=20=20=20=20=20one-or-more=201+=20+=0Adiff=20--git=20= a/test/lisp/emacs-lisp/rx-tests.el=20b/test/lisp/emacs-lisp/rx-tests.el=0A= index=2026e39f8c8e..fdf8db61df=20100644=0A---=20= a/test/lisp/emacs-lisp/rx-tests.el=0A+++=20= b/test/lisp/emacs-lisp/rx-tests.el=0A@@=20-274,6=20+274,63=20@@=20rx-not=0A= =20=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=20"[[:ascii:]][^a-z]")))=0A=20=0A+(ert-deftest=20rx-union=20()=0A+=20= =20(should=20(equal=20(rx=20(union))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20"\\`a\\`"))=0A+=20=20(should=20(equal=20(rx=20(union=20= (any=20"ba")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[ab]"))=0A+=20=20(should=20(equal=20(rx=20(union=20(any=20"a-f")=20(any=20= "c-k"=20?y)=20(any=20?r=20"x-z")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20"[a-krx-z]"))=0A+=20=20(should=20(equal=20(rx=20(union=20= (not=20(any=20"a-m"))=20(not=20(any=20"f-p"))))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20"[^f-m]"))=0A+=20=20(should=20(equal=20(rx=20= (union=20(any=20"e-m")=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"[^a-dn-z]"))=0A+=20=20(should=20(equal=20= (rx=20(union=20(not=20(any=20"g-r"))=20(not=20(any=20"t"))))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20"[^z-a]"))=0A+=20=20(should=20= (equal=20(rx=20(not=20(union=20(not=20(any=20"g-r"))=20(not=20(any=20= "t")))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\`a\\`"))=0A+=20=20(should=20(equal=20(rx=20(union=20(union=20(any=20= "a-f")=20(any=20"u-z"))=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(any=20"g-r")))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20"[a-ru-z]"))=0A+=20=20(should=20(equal=20= (rx=20(union=20(intersection=20(any=20"c-z")=20(any=20"a-g"))=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= (not=20(any=20"a-k"))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20"[^abh-k]")))=0A+=0A+(ert-deftest=20rx-def-in-union=20()=0A+=20=20= (rx-let=20((a=20(any=20"badc"))=0A+=20=20=20=20=20=20=20=20=20=20=20(b=20= (union=20a=20(any=20"def"))))=0A+=20=20=20=20(should=20(equal(rx=20= (union=20b=20(any=20"q")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20"[a-fq]"))))=0A+=0A+(ert-deftest=20rx-intersection=20()=0A+=20=20= (should=20(equal=20(rx=20(intersection))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"[^z-a]"))=0A+=20=20(should=20(equal=20(rx=20= (intersection=20(any=20"ba")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"[ab]"))=0A+=20=20(should=20(equal=20(rx=20(intersection=20= (any=20"a-j"=20"u-z")=20(any=20"c-k"=20?y)=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(any=20"a-i"=20"x-z")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"[c-iy]"))=0A+=20=20(should=20(equal=20(rx=20(intersection=20(not=20= (any=20"a-m"))=20(not=20(any=20"f-p"))))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"[^a-p]"))=0A+=20=20(should=20(equal=20(rx=20= (intersection=20(any=20"a-z")=20(not=20(any=20"g-q"))))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20"[a-fr-z]"))=0A+=20=20(should=20= (equal=20(rx=20(intersection=20(any=20"a-d")=20(any=20"e")))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20"\\`a\\`"))=0A+=20=20(should=20= (equal=20(rx=20(not=20(intersection=20(any=20"a-d")=20(any=20"e"))))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"[^z-a]"))=0A+=20=20= (should=20(equal=20(rx=20(intersection=20(any=20"d-u")=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(intersection=20(any=20"e-z")=20(any=20"a-m"))))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"[e-m]"))=0A+=20=20(should=20= (equal=20(rx=20(intersection=20(union=20(any=20"a-f")=20(any=20"f-t"))=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(any=20"e-w")))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20"[e-t]")))=0A+=0A+(ert-deftest=20= rx-def-in-intersection=20()=0A+=20=20(rx-let=20((a=20(any=20"a-g"))=0A+=20= =20=20=20=20=20=20=20=20=20=20(b=20(intersection=20a=20(any=20"d-j"))))=0A= +=20=20=20=20(should=20(equal(rx=20(intersection=20b=20(any=20"e-k")))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"[e-g]"))))=0A+=0A= =20(ert-deftest=20rx-group=20()=0A=20=20=20(should=20(equal=20(rx=20= (group=20nonl)=20(submatch=20"x")=0A=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(group-n=203=20"y")=20(submatch-n=2013=20"z")=20= (backref=201))=0A--=20=0A2.21.0=20(Apple=20Git-122.2)=0A=0A= --Apple-Mail=_C688033D-9F8B-4891-B400-E7544B217FCA-- From debbugs-submit-bounces@debbugs.gnu.org Mon Dec 09 06:04:47 2019 Received: (at 37849) by debbugs.gnu.org; 9 Dec 2019 11:04:47 +0000 Received: from localhost ([127.0.0.1]:52684 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ieGqN-0004bc-Ce for submit@debbugs.gnu.org; Mon, 09 Dec 2019 06:04:47 -0500 Received: from mail73c50.megamailservers.eu ([91.136.10.83]:43432 helo=mail92c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ieGqL-0004bT-7e for 37849@debbugs.gnu.org; Mon, 09 Dec 2019 06:04:46 -0500 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1575889483; bh=+KgMNTIxhb316eTOXXClTL9HkyILJB+woUw/PAEGxhs=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=hPg7TLWJ9uAGuEAdBXJs7mFNpVYT2BWMZsV2jrIccqRYDFD/MB9ydyyHj8g1LEZ2e BUZQN1zv+0wlmbN0M2eRpxPTEsdziqVbN02qcoUEgrcBJ4255wldy8MI5Ud4ZyRbU2 GmY4nOdxPLo1xRZVIaa9Qm1PdROcQBpuTllQ2Fnw= Feedback-ID: mattiase@acm.or Received: from stanniol.lan (c-6f4fe655.032-75-73746f71.bbcust.telenor.se [85.230.79.111]) (authenticated bits=0) by mail92c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id xB9B4e0b021480; Mon, 9 Dec 2019 11:04:42 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Subject: Re: bug#37849: composable character alternatives in rx From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= In-Reply-To: Date: Mon, 9 Dec 2019 12:04:40 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: References: To: 37849@debbugs.gnu.org X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0212.5DEE2A4B.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=RJbN4Lq+ c=1 sm=1 tr=0 a=fHaj9vQUQVKQ4sUldAaXuQ==:117 a=fHaj9vQUQVKQ4sUldAaXuQ==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=ElsIJCL--iEsu_lAR9QA:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 0.3 (/) X-Debbugs-Envelope-To: 37849 Cc: Eli Zaretskii 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 (/) Eli, as a matter of protocol: assuming the union/intersection patch = meets no opposition, can it be pushed to master? It is self-contained = and should not affect anything outside rx. From debbugs-submit-bounces@debbugs.gnu.org Mon Dec 09 08:36:39 2019 Received: (at 37849) by debbugs.gnu.org; 9 Dec 2019 13:36:39 +0000 Received: from localhost ([127.0.0.1]:52776 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ieJDL-0002J6-5H for submit@debbugs.gnu.org; Mon, 09 Dec 2019 08:36:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:43236) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ieJDK-0002Is-1i for 37849@debbugs.gnu.org; Mon, 09 Dec 2019 08:36:38 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]:33019) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ieJDD-0004Av-Of; Mon, 09 Dec 2019 08:36:31 -0500 Received: from [176.228.60.248] (port=2656 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1ieJDC-0003Jf-Gy; Mon, 09 Dec 2019 08:36:31 -0500 Date: Mon, 09 Dec 2019 15:36:15 +0200 Message-Id: <83immpd3jk.fsf@gnu.org> From: Eli Zaretskii To: Mattias =?utf-8?Q?Engdeg=C3=A5rd?= In-reply-to: (message from Mattias =?utf-8?Q?Engdeg=C3=A5rd?= on Mon, 9 Dec 2019 12:04:40 +0100) Subject: Re: bug#37849: composable character alternatives in rx References: MIME-version: 1.0 Content-type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 37849 Cc: 37849@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: -3.3 (---) > From: Mattias EngdegÄrd > Date: Mon, 9 Dec 2019 12:04:40 +0100 > Cc: Eli Zaretskii > > Eli, as a matter of protocol: assuming the union/intersection patch meets no opposition, can it be pushed to master? It is self-contained and should not affect anything outside rx. It's a new feature, so yes, assuming that you've verified it passes all the tests and cannot possibly interfere with any existing code. Thanks. From debbugs-submit-bounces@debbugs.gnu.org Tue Dec 10 16:39:43 2019 Received: (at 37849) by debbugs.gnu.org; 10 Dec 2019 21:39:43 +0000 Received: from localhost ([127.0.0.1]:56707 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ienEN-0000nv-15 for submit@debbugs.gnu.org; Tue, 10 Dec 2019 16:39:43 -0500 Received: from mail75c50.megamailservers.eu ([91.136.10.85]:45930 helo=mail92c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ienEK-0000nk-H0 for 37849@debbugs.gnu.org; Tue, 10 Dec 2019 16:39:41 -0500 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1576013978; bh=ZgVtmWaw0N7kjI3sAZaO/XQvqjM7MDnX/tvxgpwGIAA=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=p89BIU48UR8VB0Br1m4/4aQRKbVWWwVBFmXq1uYjfB2rTTQWmj/3bJXYS45CYTdrQ 1VhcqbzThjjZAUPQt8GBvO7GOaovzaDKj5ml29NttL8tTYNbEl4Ub4eKiXBsSoI/24 SPpDdE6DhSDgdU72hVgK6OVpwhq73o4EBwMttRQE= Feedback-ID: mattiase@acm.or Received: from stanniol.lan (c-6f4fe655.032-75-73746f71.bbcust.telenor.se [85.230.79.111]) (authenticated bits=0) by mail92c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id xBALdaqu011766; Tue, 10 Dec 2019 21:39:38 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Subject: Re: bug#37849: composable character alternatives in rx From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= In-Reply-To: <83immpd3jk.fsf@gnu.org> Date: Tue, 10 Dec 2019 22:39:35 +0100 Content-Transfer-Encoding: 7bit Message-Id: <61EF2B41-9B48-4694-BDDB-D1ED66309DC1@acm.org> References: <83immpd3jk.fsf@gnu.org> To: Eli Zaretskii X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B020A.5DF0109A.003C, 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=RJbN4Lq+ c=1 sm=1 tr=0 a=fHaj9vQUQVKQ4sUldAaXuQ==:117 a=fHaj9vQUQVKQ4sUldAaXuQ==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=141-EEKQ1Ove4T2_unYA:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 0.3 (/) X-Debbugs-Envelope-To: 37849 Cc: 37849@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: -0.7 (/) Thank you, now pushed. From debbugs-submit-bounces@debbugs.gnu.org Fri Dec 13 07:36:22 2019 Received: (at 37849-done) by debbugs.gnu.org; 13 Dec 2019 12:36:22 +0000 Received: from localhost ([127.0.0.1]:33147 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ifkBC-0006Wc-HG for submit@debbugs.gnu.org; Fri, 13 Dec 2019 07:36:22 -0500 Received: from mail1452c50.megamailservers.eu ([91.136.14.52]:37172 helo=mail266c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ifkB8-0006WK-AQ for 37849-done@debbugs.gnu.org; Fri, 13 Dec 2019 07:36:21 -0500 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1576240565; bh=zvLqZhnOvzENhKnfsaw1rg+VBXGQKHVZdNkvU0Faa1g=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=U1tkOmCpFrlQmDA0r4SgH77qbcUe2tZFYSnQGIwFAe0FiHxbv5++5C2pl9ZBJSQAV 9UWuYQv3R8W5Tgio+Z+A0SvEdlbGGDO36VAQcFhZ+A0Gth/SO+yrLhpBxCDBIR29t9 XxVCvEfmHQQqQS5Gtx0vm6o4Nnag3i+IGPqtJhVs= Feedback-ID: mattiase@acm.or Received: from stanniol.lan (c-6f4fe655.032-75-73746f71.bbcust.telenor.se [85.230.79.111]) (authenticated bits=0) by mail266c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id xBDCZhva019512; Fri, 13 Dec 2019 12:36:05 +0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Subject: Re: bug#37849: composable character alternatives in rx From: =?utf-8?Q?Mattias_Engdeg=C3=A5rd?= In-Reply-To: <61EF2B41-9B48-4694-BDDB-D1ED66309DC1@acm.org> Date: Fri, 13 Dec 2019 13:35:42 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: References: <83immpd3jk.fsf@gnu.org> <61EF2B41-9B48-4694-BDDB-D1ED66309DC1@acm.org> To: Stefan Monnier X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B020F.5DF385B5.003A, 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=PNJxBsiC c=1 sm=1 tr=0 a=fHaj9vQUQVKQ4sUldAaXuQ==:117 a=fHaj9vQUQVKQ4sUldAaXuQ==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=kj9zAlcOel0A:10 a=M51BFTxLslgA:10 a=hPPfrGLNHUItjIo_gXwA:9 a=CjuIK1q_8ugA:10 X-Spam-Score: 1.4 (+) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: As suggested by Stefan Monnier, 'union' was replaced with plain 'or' for character sets as well. A minor usability improvement has been pushed to master as well: characters and single-char strings no longer have to be wrapped in (any...), so (not (any ?a)) can now be written (not ?a). Content analysis details: (1.4 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: megamailservers.eu] 1.0 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-Debbugs-Envelope-To: 37849-done Cc: 37849-done@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: -0.0 (/) As suggested by Stefan Monnier, 'union' was replaced with plain 'or' for = character sets as well. A minor usability improvement has been pushed to master as well: = characters and single-char strings no longer have to be wrapped in = (any...), so (not (any ?a)) can now be written (not ?a). From unknown Fri Jun 20 07:13:29 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Sat, 11 Jan 2020 12:24:05 +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