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#37440: [PATCH] New rx implementation with extension constructs Date: Wed, 25 Sep 2019 14:33:46 +0200 Message-ID: <70CE6E54-A80E-42EA-A356-D66506533145@acm.org> References: <958a595d-41f1-f2ea-186c-672e783316ba@cs.ucla.edu> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_ED516277-A780-48D5-ABD4-A7754848202D" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="209254"; mail-complaints-to="usenet@blaine.gmane.org" Cc: 37440@debbugs.gnu.org To: Paul Eggert Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Sep 25 14:35:22 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 1iD6Vs-000sGZ-Ux for geb-bug-gnu-emacs@m.gmane.org; Wed, 25 Sep 2019 14:35:21 +0200 Original-Received: from localhost ([::1]:49408 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iD6Vr-00031t-Ht for geb-bug-gnu-emacs@m.gmane.org; Wed, 25 Sep 2019 08:35:19 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:56088) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iD6Vc-0002qJ-EI for bug-gnu-emacs@gnu.org; Wed, 25 Sep 2019 08:35:06 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iD6Vb-0005Hg-7i for bug-gnu-emacs@gnu.org; Wed, 25 Sep 2019 08:35:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:60372) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iD6Va-0005HU-3V for bug-gnu-emacs@gnu.org; Wed, 25 Sep 2019 08:35:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1iD6VZ-0000IJ-UF for bug-gnu-emacs@gnu.org; Wed, 25 Sep 2019 08:35:01 -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: Wed, 25 Sep 2019 12:35:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 37440 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 37440-submit@debbugs.gnu.org id=B37440.15694148491064 (code B ref 37440); Wed, 25 Sep 2019 12:35:01 +0000 Original-Received: (at 37440) by debbugs.gnu.org; 25 Sep 2019 12:34:09 +0000 Original-Received: from localhost ([127.0.0.1]:40961 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iD6Uj-0000H6-BY for submit@debbugs.gnu.org; Wed, 25 Sep 2019 08:34:09 -0400 Original-Received: from mail1430c50.megamailservers.eu ([91.136.14.30]:57048 helo=mail118c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iD6Uh-0000Ga-21 for 37440@debbugs.gnu.org; Wed, 25 Sep 2019 08:34:08 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1569414829; bh=eRfAqhmwE1Vt/Gim0vyR8xxZ9K2ae0xd7BYvTNkGGZE=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=jo3clS7jvOAq3onkTsIF5ve8djFoV/MsXaFgl72S+aDkKCSrQppjJFVbwfE2RR4Mv HVA5mRJjZVJbwKCQdtqTO7CzrCk5drpa5KJwokD74uT9aspKjRDFgfjBd9EXczWj1U bWBAm2Q0O58yVAOVBZRwDolgcg/1P5QLShKo7EjY= Feedback-ID: mattiase@acm.or Original-Received: from [192.168.0.4] ([188.150.171.71]) (authenticated bits=0) by mail118c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id x8PCXk8w006977; Wed, 25 Sep 2019 12:33:48 +0000 In-Reply-To: <958a595d-41f1-f2ea-186c-672e783316ba@cs.ucla.edu> X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B0209.5D8B5EAD.005B, 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=DaRpVclW c=1 sm=1 tr=0 a=SF+I6pRkHZhrawxbOkkvaA==:117 a=SF+I6pRkHZhrawxbOkkvaA==:17 a=jpOVt7BSZ2e4Z31A5e1TngXxSK0=:19 a=M51BFTxLslgA:10 a=v-eAyER-efrZmlKSB7MA:9 a=CjuIK1q_8ugA:10 a=FugrI5Wx0j-mM50IAi0A:9 a=B2y7HmGcmWMA:10 a=fIZI3ytsdTQQ6une4GMA:9 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:167153 Archived-At: --Apple-Mail=_ED516277-A780-48D5-ABD4-A7754848202D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii 24 sep. 2019 kl. 19.55 skrev Paul Eggert : >=20 > I tried the proposed patches with current Emacs master on Fedora 30 = x86-64 and got a test failure as shown in the attached file.=20 Thank you! Those failures only occur when running test loaded from a = byte-compiled file -- I suppose you used TEST_LOAD_EL=3Dno. First, the unibyte and multibyte forms of a string like "\326" print the = same but aren't equal: (string-to-multibyte "\326") =3D> "\326" (equal (string-to-multibyte "\326") "\326") =3D> nil This means that if a multibyte string ends up as a constant in = byte-compiled code, surprise, it may become a unibyte value when loaded. = The test had to be made to work both interpreted and compiled. = Fortunately the regexp engine was recently fixed with respect to raw = bytes, making its semantics invariant for strings with the same print = representation, so this is not a problem with the rx implementation. The second item of interest was that `rx-define', since it relies on = `eval-and-compile', doesn't expand to code when macroexpanded. I don't = know if it will be a problem in practice. The test now uses an auxiliary = function as work-around. Updated patches attached. --Apple-Mail=_ED516277-A780-48D5-ABD4-A7754848202D Content-Disposition: attachment; filename=0001-New-rx-implementation.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-New-rx-implementation.patch" Content-Transfer-Encoding: quoted-printable =46rom=200eb84f9a8e378e0a1a14065915129edc060d0722=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Sun,=2015=20Sep=202019=2016:11:09=20+0200=0A= Subject:=20[PATCH=201/2]=20New=20rx=20implementation=0A=0A*=20= lisp/emacs-lisp/rx.el:=0A*=20test/lisp/emacs-lisp/rx-tests.el:=0A*=20= doc/lispref/searching.texi=20(Rx=20Constructs):=0ARewrite=20rx=20for=20= correctness,=20clarity,=20and=20performance.=20=20The=20new=0A= implementation=20retains=20full=20compatibility=20and=20has=20more=20= comprehensive=0Atests.=0A=0A*=20lisp/emacs-lisp/re-builder.el=20= (reb-rx-font-lock-keywords):=0AAdapt=20to=20changes=20in=20internal=20= variables=20in=20rx.el.=0A---=0A=20doc/lispref/searching.texi=20=20=20=20= =20=20=20|=20=20=20=204=20+-=0A=20lisp/emacs-lisp/re-builder.el=20=20=20=20= |=20=20=20=209=20+-=0A=20lisp/emacs-lisp/rx.el=20=20=20=20=20=20=20=20=20= =20=20=20|=201809=20++++++++++++++----------------=0A=20= test/lisp/emacs-lisp/rx-tests.el=20|=20=20336=20++++--=0A=204=20files=20= changed,=201091=20insertions(+),=201067=20deletions(-)=0A=0Adiff=20--git=20= a/doc/lispref/searching.texi=20b/doc/lispref/searching.texi=0Aindex=20= 1286b63446..21b1f7b68b=20100644=0A---=20a/doc/lispref/searching.texi=0A= +++=20b/doc/lispref/searching.texi=0A@@=20-1044,11=20+1044,9=20@@=20Rx=20= Constructs=0A=20=0A=20The=20various=20forms=20in=20@code{rx}=20regexps=20= are=20described=20below.=20=20The=0A=20shorthand=20@var{rx}=20represents=20= any=20@code{rx}=20form,=20and=20@var{rx}@dots{}=0A-means=20one=20or=20= more=20@code{rx}=20forms.=20=20Where=20the=20corresponding=20string=0A= +means=20zero=20or=20more=20@code{rx}=20forms.=20=20Where=20the=20= corresponding=20string=0A=20regexp=20syntax=20is=20given,=20@var{A},=20= @var{B},=20@dots{}=20are=20string=20regexp=0A=20subexpressions.=0A-@c=20= With=20the=20new=20implementation=20of=20rx,=20this=20can=20be=20changed=20= from=0A-@c=20'one=20or=20more'=20to=20'zero=20or=20more'.=0A=20=0A=20= @subsubheading=20Literals=0A=20=0Adiff=20--git=20= a/lisp/emacs-lisp/re-builder.el=20b/lisp/emacs-lisp/re-builder.el=0A= index=20961d26a721..1054f1453b=20100644=0A---=20= a/lisp/emacs-lisp/re-builder.el=0A+++=20b/lisp/emacs-lisp/re-builder.el=0A= @@=20-816,13=20+816,12=20@@=20reb-mark-non-matching-parenthesis=0A=20=0A=20= (require=20'rx)=0A=20(defconst=20reb-rx-font-lock-keywords=0A-=20=20(let=20= ((constituents=20(mapcar=20(lambda=20(rec)=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= (symbol-name=20(car=20rec)))=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=20rx-constituents))=0A-=20=20= =20=20=20=20=20=20(syntax=20(mapcar=20(lambda=20(rec)=20(symbol-name=20= (car=20rec)))=20rx-syntax))=0A+=20=20(let=20((constituents=20(mapcar=20= #'symbol-name=20rx--builtin-forms))=0A+=20=20=20=20=20=20=20=20(syntax=20= (mapcar=20(lambda=20(rec)=20(symbol-name=20(car=20rec)))=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= rx--syntax-codes))=0A=20=20=20=20=20=20=20=20=20(categories=20(mapcar=20= (lambda=20(rec)=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(symbol-name=20(car=20rec)))=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= =20rx-categories)))=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=20rx--categories)))=0A=20=20=20=20=20`(=0A= =20=20=20=20=20=20=20(,(concat=20"("=20(regexp-opt=20(list=20= "rx-to-string")=20t)=20"[[:space:]]")=0A=20=20=20=20=20=20=20=20(1=20= font-lock-function-name-face))=0Adiff=20--git=20a/lisp/emacs-lisp/rx.el=20= b/lisp/emacs-lisp/rx.el=0Aindex=20249529e54e..9b3419e1c8=20100644=0A---=20= a/lisp/emacs-lisp/rx.el=0A+++=20b/lisp/emacs-lisp/rx.el=0A@@=20-1,11=20= +1,7=20@@=0A-;;;=20rx.el=20---=20sexp=20notation=20for=20regular=20= expressions=20=20-*-=20lexical-binding:=20t=20-*-=0A+;;;=20rx.el=20---=20= S-exp=20notation=20for=20regexps=20=20=20=20=20=20=20=20=20=20=20--*-=20= lexical-binding:=20t=20-*-=0A=20=0A=20;;=20Copyright=20(C)=202001-2019=20= Free=20Software=20Foundation,=20Inc.=0A=20=0A-;;=20Author:=20Gerd=20= Moellmann=20=0A-;;=20Maintainer:=20emacs-devel@gnu.org=0A= -;;=20Keywords:=20strings,=20regexps,=20extensions=0A-=0A=20;;=20This=20= file=20is=20part=20of=20GNU=20Emacs.=0A=20=0A=20;;=20GNU=20Emacs=20is=20= free=20software:=20you=20can=20redistribute=20it=20and/or=20modify=0A@@=20= -23,937=20+19,824=20@@=0A=20=0A=20;;;=20Commentary:=0A=20=0A-;;=20This=20= is=20another=20implementation=20of=20sexp-form=20regular=20expressions.=0A= -;;=20It=20was=20unfortunately=20written=20without=20being=20aware=20of=20= the=20Sregex=0A-;;=20package=20coming=20with=20Emacs,=20but=20as=20= things=20stand,=20Rx=20completely=0A-;;=20covers=20all=20regexp=20= features,=20which=20Sregex=20doesn't,=20doesn't=20suffer=0A-;;=20from=20= the=20bugs=20mentioned=20in=20the=20commentary=20section=20of=20Sregex,=20= and=0A-;;=20uses=20a=20nicer=20syntax=20(IMHO,=20of=20course=20:-).=0A-=0A= -;;=20This=20significantly=20extended=20version=20of=20the=20original,=20= is=20almost=0A-;;=20compatible=20with=20Sregex.=20=20The=20only=20= incompatibility=20I=20(fx)=20know=20of=20is=0A-;;=20that=20the=20= `repeat'=20form=20can't=20have=20multiple=20regexp=20args.=0A-=0A-;;=20= Now=20alternative=20forms=20are=20provided=20for=20a=20degree=20of=20= compatibility=0A-;;=20with=20Olin=20Shivers'=20attempted=20definitive=20= SRE=20notation.=20=20SRE=20forms=0A-;;=20not=20catered=20for=20include:=20= dsm,=20uncase,=20w/case,=20w/nocase,=20,@,=0A-;;=20,,=20(word=20= ...),=20word+,=20posix-string,=20and=20character=20class=20forms.=0A-;;=20= Some=20forms=20are=20inconsistent=20with=20SRE,=20either=20for=20= historical=20reasons=0A-;;=20or=20because=20of=20the=20implementation=20= --=20simple=20translation=20into=20Emacs=0A-;;=20regexp=20strings.=20=20= These=20include:=20any,=20word.=20=20Also,=20case-sensitivity=0A-;;=20= and=20greediness=20are=20controlled=20by=20variables=20external=20to=20= the=20regexp,=0A-;;=20and=20you=20need=20to=20feed=20the=20forms=20to=20= the=20`posix-'=20functions=20to=20get=0A-;;=20SRE's=20POSIX=20semantics.=20= =20There=20are=20probably=20more=20difficulties.=0A-=0A-;;=20Rx=20= translates=20a=20sexp=20notation=20for=20regular=20expressions=20into=20= the=0A-;;=20usual=20string=20notation.=20=20The=20translation=20can=20be=20= done=20at=20compile-time=0A-;;=20by=20using=20the=20`rx'=20macro.=20=20= The=20`regexp'=20and=20`literal'=20forms=20accept=0A-;;=20non-constant=20= expressions,=20in=20which=20case=20`rx'=20will=20translate=20to=20a=0A= -;;=20`concat'=20expression.=20=20Translation=20can=20be=20done=20fully=20= at=20run=20time=20by=0A-;;=20calling=20function=20`rx-to-string'.=20=20= See=20the=20documentation=20of=20`rx'=20for=0A-;;=20a=20complete=20= description=20of=20the=20sexp=20notation.=0A-;;=0A-;;=20Some=20examples=20= of=20string=20regexps=20and=20their=20sexp=20counterparts:=0A-;;=0A-;;=20= "^[a-z]*"=0A-;;=20(rx=20line-start=20(0+=20(in=20"a-z")))=0A-;;=0A-;;=20= "\n[^=20\t]"=0A-;;=20(rx=20?\n=20(not=20(in=20"=20\t")))=0A-;;=0A-;;=20= "\\*\\*\\*=20EOOH=20\\*\\*\\*\n"=0A-;;=20(rx=20"***=20EOOH=20***\n")=0A= -;;=0A-;;=20"\\<\\(catch\\|finally\\)\\>[^_]"=0A-;;=20(rx=20word-start=20= (submatch=20(or=20"catch"=20"finally"))=20word-end=0A-;;=20=20=20=20=20= (not=20(in=20?_)))=0A-;;=0A-;;=20"[=20\t\n]*:\\($\\|[^:]+\\)"=0A-;;=20= (rx=20(*=20(in=20"=20\t\n"))=20":"=0A-;;=20=20=20=20=20(submatch=20(or=20= line-end=20(+=20(not=20(in=20?:))))))=0A-;;=0A-;;=20= "^content-transfer-encoding:\\(?:\n?[\t=20= ]\\)*quoted-printable\\(?:\n?[\t=20]\\)*"=0A-;;=20(rx=20line-start=0A-;;=20= =20=20=20=20"content-transfer-encoding:"=0A-;;=20=20=20=20=20(*=20(?=20= ?\n)=20(in=20"=20\t"))=0A-;;=20=20=20=20=20"quoted-printable"=0A-;;=20=20= =20=20=20(*=20(?=20?\n)=20(in=20"=20\t")))=0A-;;=0A-;;=20(concat=20= "^\\(?:"=20something-else=20"\\)")=0A-;;=20(rx=20line-start=20(regexp=20= something-else))=0A-;;=0A-;;=20(regexp-opt=20'(STRING1=20STRING2=20...))=0A= -;;=20(rx=20(or=20STRING1=20STRING2=20...)),=20or=20in=20other=20words,=20= `or'=20automatically=0A-;;=20calls=20`regexp-opt'=20as=20needed.=0A-;;=0A= -;;=20"^;;\\s-*\n\\|^\n"=0A-;;=20(rx=20(or=20(seq=20line-start=20";;"=20= (0+=20space)=20?\n)=0A-;;=20=20=20=20=20=20=20=20=20(seq=20line-start=20= ?\n)))=0A+;;=20This=20facility=20allows=20writing=20regexps=20in=20a=20= sexp-based=20language=0A+;;=20instead=20of=20strings.=20=20Regexps=20in=20= the=20`rx'=20notation=20are=20easier=20to=0A+;;=20read,=20write=20and=20= maintain;=20they=20can=20be=20indented=20and=20commented=20in=20a=0A+;;=20= natural=20way,=20and=20are=20easily=20composed=20by=20program=20code.=0A= +;;=20The=20translation=20to=20string=20regexp=20is=20done=20by=20a=20= macro=20and=20does=20not=0A+;;=20incur=20any=20extra=20processing=20= during=20run=20time.=20=20Example:=0A=20;;=0A-;;=20"\\$[I]d:=20[^=20]+=20= \\([^=20]+\\)=20"=0A-;;=20(rx=20"$Id:=20"=0A-;;=20=20=20=20=20(1+=20(not=20= (in=20"=20")))=0A-;;=20=20=20=20=20"=20"=0A-;;=20=20=20=20=20(submatch=20= (1+=20(not=20(in=20"=20"))))=0A-;;=20=20=20=20=20"=20")=0A+;;=20=20(rx=20= bos=20(or=20(not=20(any=20"^"))=0A+;;=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(seq=20"^"=20(or=20"=20*"=20"["))))=0A=20;;=0A-;;=20= "\\\\\\\\\\[\\w+"=0A-;;=20(rx=20"\\\\["=20(1+=20word))=0A-;;=0A-;;=20= etc.=0A-=0A-;;;=20History:=0A+;;=20=3D>=20"\\`\\(?:[^^]\\|\\^\\(?:=20= \\*\\|\\[\\)\\)"=0A=20;;=0A+;;=20The=20notation=20is=20much=20influenced=20= by=20and=20retains=20some=20compatibility=20with=0A+;;=20Olin=20= Shivers's=20SRE,=20with=20concessions=20to=20Emacs=20regexp=20= peculiarities,=0A+;;=20and=20the=20older=20Emacs=20package=20Sregex.=0A=20= =0A=20;;;=20Code:=0A=20=0A-(require=20'cl-lib)=0A-(require=20'cl-extra)=0A= -=0A-;;=20FIXME:=20support=20macros.=0A-=0A-(defvar=20rx-constituents=20=20= =20=20=20=20=20=20=20=20=20=20=20=20;Not=20`const'=20because=20some=20= modes=20extend=20it.=0A-=20=20'((and=09=09.=20(rx-and=200=20nil))=0A-=20=20= =20=20(seq=09=09.=20and)=09=09;=20SRE=0A-=20=20=20=20(:=09=09=09.=20and)=09= =09;=20SRE=0A-=20=20=20=20(sequence=09=09.=20and)=09=09;=20sregex=0A-=20=20= =20=20(or=09=09=09.=20(rx-or=200=20nil))=0A-=20=20=20=20(|=09=09=09.=20= or)=09=09;=20SRE=0A-=20=20=20=20(not-newline=09.=20".")=0A-=20=20=20=20= (nonl=09=09.=20not-newline)=09;=20SRE=0A-=20=20=20=20(anything=09=09.=20= (rx-anything=200=20nil))=0A-=20=20=20=20(any=09=09.=20(rx-any=201=20nil=20= rx-check-any))=20;=20inconsistent=20with=20SRE=0A-=20=20=20=20(any=09=09= .=20".")=20=20=20=20=20=20=20=20=20=20;=20sregex=0A-=20=20=20=20(in=09=09= =09.=20any)=0A-=20=20=20=20(char=09=09.=20any)=09=09;=20sregex=0A-=20=20=20= =20(not-char=09=09.=20(rx-not-char=201=20nil=20rx-check-any))=20;=20= sregex=0A-=20=20=20=20(not=09=09.=20(rx-not=201=201=20rx-check-not))=0A-=20= =20=20=20(repeat=09=09.=20(rx-repeat=202=20nil))=0A-=20=20=20=20(=3D=09=09= =09.=20(rx-=3D=202=20nil))=09=20=20=20;=20SRE=0A-=20=20=20=20(>=3D=09=09=09= .=20(rx->=3D=202=20nil))=20=20=20;=20SRE=0A-=20=20=20=20(**=09=09=09.=20= (rx-**=202=20nil))=20=20=20;=20SRE=0A-=20=20=20=20(submatch=09=09.=20= (rx-submatch=201=20nil))=20;=20SRE=0A-=20=20=20=20(group=09=09.=20= submatch)=20=20=20=20=20;=20sregex=0A-=20=20=20=20(submatch-n=09=09.=20= (rx-submatch-n=202=20nil))=0A-=20=20=20=20(group-n=09=09.=20submatch-n)=0A= -=20=20=20=20(zero-or-more=09.=20(rx-kleene=201=20nil))=0A-=20=20=20=20= (one-or-more=09.=20(rx-kleene=201=20nil))=0A-=20=20=20=20(zero-or-one=09= .=20(rx-kleene=201=20nil))=0A-=20=20=20=20(\?=09=09=09.=20zero-or-one)=09= ;=20SRE=0A-=20=20=20=20(\??=09=09.=20zero-or-one)=0A-=20=20=20=20(*=09=09= =09.=20zero-or-more)=09;=20SRE=0A-=20=20=20=20(*?=09=09=09.=20= zero-or-more)=0A-=20=20=20=20(0+=09=09=09.=20zero-or-more)=0A-=20=20=20=20= (+=09=09=09.=20one-or-more)=09;=20SRE=0A-=20=20=20=20(+?=09=09=09.=20= one-or-more)=0A-=20=20=20=20(1+=09=09=09.=20one-or-more)=0A-=20=20=20=20= (optional=09=09.=20zero-or-one)=0A-=20=20=20=20(opt=09=09.=20= zero-or-one)=09;=20sregex=0A-=20=20=20=20(minimal-match=09.=20(rx-greedy=20= 1=201))=0A-=20=20=20=20(maximal-match=09.=20(rx-greedy=201=201))=0A-=20=20= =20=20(backref=09=09.=20(rx-backref=201=201=20rx-check-backref))=0A-=20=20= =20=20(line-start=09=09.=20"^")=0A-=20=20=20=20(bol=09=09.=20line-start)=09= ;=20SRE=0A-=20=20=20=20(line-end=09=09.=20"$")=0A-=20=20=20=20(eol=09=09= .=20line-end)=09;=20SRE=0A-=20=20=20=20(string-start=09.=20"\\`")=0A-=20=20= =20=20(bos=09=09.=20string-start)=09;=20SRE=0A-=20=20=20=20(bot=09=09.=20= string-start)=09;=20sregex=0A-=20=20=20=20(string-end=09=09.=20"\\'")=0A= -=20=20=20=20(eos=09=09.=20string-end)=09;=20SRE=0A-=20=20=20=20(eot=09=09= .=20string-end)=09;=20sregex=0A-=20=20=20=20(buffer-start=09.=20"\\`")=0A= -=20=20=20=20(buffer-end=09=09.=20"\\'")=0A-=20=20=20=20(point=09=09.=20= "\\=3D")=0A-=20=20=20=20(word-start=09=09.=20"\\<")=0A-=20=20=20=20(bow=09= =09.=20word-start)=09;=20SRE=0A-=20=20=20=20(word-end=09=09.=20"\\>")=0A= -=20=20=20=20(eow=09=09.=20word-end)=09;=20SRE=0A-=20=20=20=20= (word-boundary=09.=20"\\b")=0A-=20=20=20=20(not-word-boundary=09.=20= "\\B")=09;=20sregex=0A-=20=20=20=20(symbol-start=20=20=20=20=20=20=20.=20= "\\_<")=0A-=20=20=20=20(symbol-end=20=20=20=20=20=20=20=20=20.=20"\\_>")=0A= -=20=20=20=20(syntax=09=09.=20(rx-syntax=201=201))=0A-=20=20=20=20= (not-syntax=09=09.=20(rx-not-syntax=201=201))=20;=20sregex=0A-=20=20=20=20= (category=09=09.=20(rx-category=201=201=20rx-check-category))=0A-=20=20=20= =20(eval=09=09.=20(rx-eval=201=201))=0A-=20=20=20=20(literal=09=09.=20= (rx-literal=201=201=20stringp))=0A-=20=20=20=20(regexp=09=09.=20= (rx-regexp=201=201=20stringp))=0A-=20=20=20=20(regex=09=09.=20regexp)=20=20= =20=20=20=20=20;=20sregex=0A-=20=20=20=20(digit=09=09.=20"[[:digit:]]")=0A= -=20=20=20=20(numeric=09=09.=20digit)=09;=20SRE=0A-=20=20=20=20(num=09=09= .=20digit)=09;=20SRE=0A-=20=20=20=20(control=09=09.=20"[[:cntrl:]]")=20;=20= SRE=0A-=20=20=20=20(cntrl=09=09.=20control)=09=20;=20SRE=0A-=20=20=20=20= (hex-digit=09=09.=20"[[:xdigit:]]")=20;=20SRE=0A-=20=20=20=20(hex=09=09.=20= hex-digit)=09=20=20;=20SRE=0A-=20=20=20=20(xdigit=09=09.=20hex-digit)=09=20= =20;=20SRE=0A-=20=20=20=20(blank=09=09.=20"[[:blank:]]")=20=20;=20SRE=0A= -=20=20=20=20(graphic=09=09.=20"[[:graph:]]")=20=20;=20SRE=0A-=20=20=20=20= (graph=09=09.=20graphic)=09=20=20;=20SRE=0A-=20=20=20=20(printing=09=09.=20= "[[:print:]]")=20=20;=20SRE=0A-=20=20=20=20(print=09=09.=20printing)=09=20= =20;=20SRE=0A-=20=20=20=20(alphanumeric=09.=20"[[:alnum:]]")=20=20;=20= SRE=0A-=20=20=20=20(alnum=09=09.=20alphanumeric)=09=20=20;=20SRE=0A-=20=20= =20=20(letter=09=09.=20"[[:alpha:]]")=0A-=20=20=20=20(alphabetic=09=09.=20= letter)=09;=20SRE=0A-=20=20=20=20(alpha=09=09.=20letter)=09;=20SRE=0A-=20= =20=20=20(ascii=09=09.=20"[[:ascii:]]")=20;=20SRE=0A-=20=20=20=20= (nonascii=09=09.=20"[[:nonascii:]]")=0A-=20=20=20=20(lower=09=09.=20= "[[:lower:]]")=20;=20SRE=0A-=20=20=20=20(lower-case=09=09.=20lower)=09=20= ;=20SRE=0A-=20=20=20=20(punctuation=09.=20"[[:punct:]]")=20;=20SRE=0A-=20= =20=20=20(punct=09=09.=20punctuation)=09=20;=20SRE=0A-=20=20=20=20(space=09= =09.=20"[[:space:]]")=20;=20SRE=0A-=20=20=20=20(whitespace=09=09.=20= space)=09=20;=20SRE=0A-=20=20=20=20(white=09=09.=20space)=09=20;=20SRE=0A= -=20=20=20=20(upper=09=09.=20"[[:upper:]]")=20;=20SRE=0A-=20=20=20=20= (upper-case=09=09.=20upper)=09=20;=20SRE=0A-=20=20=20=20(word=09=09.=20= "[[:word:]]")=09=20;=20inconsistent=20with=20SRE=0A-=20=20=20=20= (wordchar=09=09.=20word)=09=09=20;=20sregex=0A-=20=20=20=20(not-wordchar=09= .=20"\\W"))=0A-=20=20"Alist=20of=20sexp=20form=20regexp=20constituents.=0A= -Each=20element=20of=20the=20alist=20has=20the=20form=20(SYMBOL=20.=20= DEFN).=0A-SYMBOL=20is=20a=20valid=20constituent=20of=20sexp=20regular=20= expressions.=0A-If=20DEFN=20is=20a=20string,=20SYMBOL=20is=20translated=20= into=20DEFN.=0A-If=20DEFN=20is=20a=20symbol,=20use=20the=20definition=20= of=20DEFN,=20recursively.=0A-Otherwise,=20DEFN=20must=20be=20a=20list=20= (FUNCTION=20MIN-ARGS=20MAX-ARGS=20PREDICATE).=0A-FUNCTION=20is=20used=20= to=20produce=20code=20for=20SYMBOL.=20=20MIN-ARGS=20and=20MAX-ARGS=0A= -are=20the=20minimum=20and=20maximum=20number=20of=20arguments=20the=20= function-form=0A-sexp=20constituent=20SYMBOL=20may=20have=20in=20sexp=20= regular=20expressions.=0A-MAX-ARGS=20nil=20means=20no=20limit.=20=20= PREDICATE,=20if=20specified,=20means=20that=0A-all=20arguments=20must=20= satisfy=20PREDICATE.")=0A-=0A-=0A-(defconst=20rx-syntax=0A-=20=20= '((whitespace=09=09.=20?-)=0A-=20=20=20=20(punctuation=09.=20?.)=0A-=20=20= =20=20(word=09=09.=20?w)=0A-=20=20=20=20(symbol=09=09.=20?_)=0A-=20=20=20= =20(open-parenthesis=09.=20?\()=0A-=20=20=20=20(close-parenthesis=09.=20= ?\))=0A-=20=20=20=20(expression-prefix=09.=20?\')=0A-=20=20=20=20= (string-quote=09.=20?\")=0A-=20=20=20=20(paired-delimiter=09.=20?$)=0A-=20= =20=20=20(escape=09=09.=20?\\)=0A-=20=20=20=20(character-quote=09.=20?/)=0A= -=20=20=20=20(comment-start=09.=20?<)=0A-=20=20=20=20(comment-end=09.=20= ?>)=0A-=20=20=20=20(string-delimiter=09.=20?|)=0A-=20=20=20=20= (comment-delimiter=09.=20?!))=0A-=20=20"Alist=20mapping=20Rx=20syntax=20= symbols=20to=20syntax=20characters.=0A-Each=20entry=20has=20the=20form=20= (SYMBOL=20.=20CHAR),=20where=20SYMBOL=20is=20a=20valid=0A-symbol=20in=20= `(syntax=20SYMBOL)',=20and=20CHAR=20is=20the=20syntax=20character=0A= -corresponding=20to=20SYMBOL,=20as=20it=20would=20be=20used=20with=20\\s=20= or=20\\S=20in=0A-regular=20expressions.")=0A-=0A-=0A-(defconst=20= rx-categories=0A-=20=20'((space-for-indent=20=20=20=20=20=20=20=20=20=20=20= .=20?\s)=0A-=20=20=20=20(base=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20.=20?.)=0A-=20=20=20=20(consonant=09=09=09.=20= ?0)=0A-=20=20=20=20(base-vowel=09=09=09.=20?1)=0A-=20=20=20=20= (upper-diacritical-mark=09.=20?2)=0A-=20=20=20=20(lower-diacritical-mark=09= .=20?3)=0A-=20=20=20=20(tone-mark=09=09=09.=20?4)=0A-=20=20=20=20(symbol=09= =09=09.=20?5)=0A-=20=20=20=20(digit=09=09=09.=20?6)=0A-=20=20=20=20= (vowel-modifying-diacritical-mark=20.=20?7)=0A-=20=20=20=20(vowel-sign=09= =09=09.=20?8)=0A-=20=20=20=20(semivowel-lower=09=09.=20?9)=0A-=20=20=20=20= (not-at-end-of-line=09=09.=20?<)=0A-=20=20=20=20= (not-at-beginning-of-line=09.=20?>)=0A-=20=20=20=20= (alpha-numeric-two-byte=09.=20?A)=0A-=20=20=20=20(chinese-two-byte=09=09= .=20?C)=0A-=20=20=20=20(chinse-two-byte=09=09.=20?C)=20;;=20A=20typo=20= in=20Emacs=2021.1-24.3.=0A-=20=20=20=20(greek-two-byte=09=09.=20?G)=0A-=20= =20=20=20(japanese-hiragana-two-byte=20.=20?H)=0A-=20=20=20=20= (indian-two-byte=09=09.=20?I)=0A-=20=20=20=20(japanese-katakana-two-byte=20= .=20?K)=0A-=20=20=20=20(strong-left-to-right=20=20=20=20=20=20=20.=20?L)=0A= -=20=20=20=20(korean-hangul-two-byte=09.=20?N)=0A-=20=20=20=20= (strong-right-to-left=20=20=20=20=20=20=20.=20?R)=0A-=20=20=20=20= (cyrillic-two-byte=09=09.=20?Y)=0A-=20=20=20=20(combining-diacritic=09.=20= ?^)=0A-=20=20=20=20(ascii=09=09=09.=20?a)=0A-=20=20=20=20(arabic=09=09=09= .=20?b)=0A-=20=20=20=20(chinese=09=09=09.=20?c)=0A-=20=20=20=20(ethiopic=09= =09=09.=20?e)=0A-=20=20=20=20(greek=09=09=09.=20?g)=0A-=20=20=20=20= (korean=09=09=09.=20?h)=0A-=20=20=20=20(indian=09=09=09.=20?i)=0A-=20=20=20= =20(japanese=09=09=09.=20?j)=0A-=20=20=20=20(japanese-katakana=09=09.=20= ?k)=0A-=20=20=20=20(latin=09=09=09.=20?l)=0A-=20=20=20=20(lao=09=09=09.=20= ?o)=0A-=20=20=20=20(tibetan=09=09=09.=20?q)=0A-=20=20=20=20= (japanese-roman=09=09.=20?r)=0A-=20=20=20=20(thai=09=09=09.=20?t)=0A-=20=20= =20=20(vietnamese=09=09=09.=20?v)=0A-=20=20=20=20(hebrew=09=09=09.=20?w)=0A= -=20=20=20=20(cyrillic=09=09=09.=20?y)=0A-=20=20=20=20(can-break=09=09=09= .=20?|))=0A-=20=20"Alist=20mapping=20symbols=20to=20category=20= characters.=0A-Each=20entry=20has=20the=20form=20(SYMBOL=20.=20CHAR),=20= where=20SYMBOL=20is=20a=20valid=0A-symbol=20in=20`(category=20SYMBOL)',=20= and=20CHAR=20is=20the=20category=20character=0A-corresponding=20to=20= SYMBOL,=20as=20it=20would=20be=20used=20with=20`\\c'=20or=20`\\C'=20in=0A= -regular=20expression=20strings.")=0A-=0A-=0A-(defvar=20rx-greedy-flag=20= t=0A-=20=20"Non-nil=20means=20produce=20greedy=20regular=20expressions=20= for=20`zero-or-one',=0A-`zero-or-more',=20and=20`one-or-more'.=20=20= Dynamically=20bound.")=0A-=0A-(defvar=20rx--compile-to-lisp=20nil=0A-=20=20= "Nil=20means=20return=20a=20regexp=20as=20a=20string.=0A-Non-nil=20means=20= we=20may=20return=20a=20lisp=20form=20which=20produces=20a=0A-string=20= (used=20for=20`rx'=20macro).")=0A-=0A-(defun=20rx-info=20(op=20head)=0A-=20= =20"Return=20parsing/code=20generation=20info=20for=20OP.=0A-If=20OP=20= is=20the=20space=20character=20ASCII=2032,=20return=20info=20for=20the=20= symbol=20`?'.=0A-If=20OP=20is=20the=20character=20`?',=20return=20info=20= for=20the=20symbol=20`??'.=0A-See=20also=20`rx-constituents'.=0A-If=20= HEAD=20is=20non-nil,=20then=20OP=20is=20the=20head=20of=20a=20sexp,=20= otherwise=20it's=0A-a=20standalone=20symbol."=0A-=20=20(cond=20((eq=20op=20= ?=20)=20(setq=20op=20'\?))=0A-=09((eq=20op=20??)=20(setq=20op=20'\??)))=0A= -=20=20(let=20(old-op)=0A-=20=20=20=20(while=20(and=20(not=20(null=20= op))=20(symbolp=20op))=0A-=20=20=20=20=20=20(setq=20old-op=20op)=0A-=20=20= =20=20=20=20(setq=20op=20(cdr=20(assq=20op=20rx-constituents)))=0A-=20=20= =20=20=20=20(when=20(if=20head=20(stringp=20op)=20(consp=20op))=0A-=20=20= =20=20=20=20=20=20;;=20We=20found=20something=20but=20of=20the=20wrong=20= kind.=20=20Let's=20look=20for=20an=0A-=20=20=20=20=20=20=20=20;;=20= alternate=20definition=20for=20the=20other=20case.=0A-=20=20=20=20=20=20=20= =20(let=20((new-op=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cdr=20= (assq=20old-op=20(cdr=20(memq=20(assq=20old-op=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=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20rx-constituents))))))=0A= -=20=20=20=20=20=20=20=20=20=20(if=20(and=20new-op=20(not=20(if=20head=20= (stringp=20new-op)=20(consp=20new-op))))=0A-=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(setq=20op=20new-op))))))=0A-=20=20op)=0A-=0A-=0A-(defun=20= rx-check=20(form)=0A-=20=20"Check=20FORM=20according=20to=20its=20car's=20= parsing=20info."=0A-=20=20(unless=20(listp=20form)=0A-=20=20=20=20(error=20= "rx=20`%s'=20needs=20argument(s)"=20form))=0A-=20=20(let*=20((rx=20= (rx-info=20(car=20form)=20'head))=0A-=09=20(nargs=20(1-=20(length=20= form)))=0A-=09=20(min-args=20(nth=201=20rx))=0A-=09=20(max-args=20(nth=20= 2=20rx))=0A-=09=20(type-pred=20(nth=203=20rx)))=0A-=20=20=20=20(when=20= (and=20(not=20(null=20min-args))=0A-=09=20=20=20=20=20=20=20(<=20nargs=20= min-args))=0A-=20=20=20=20=20=20(error=20"rx=20form=20`%s'=20requires=20= at=20least=20%d=20args"=0A-=09=20=20=20=20=20(car=20form)=20min-args))=0A= -=20=20=20=20(when=20(and=20(not=20(null=20max-args))=0A-=09=20=20=20=20=20= =20=20(>=20nargs=20max-args))=0A-=20=20=20=20=20=20(error=20"rx=20form=20= `%s'=20accepts=20at=20most=20%d=20args"=0A-=09=20=20=20=20=20(car=20= form)=20max-args))=0A-=20=20=20=20(when=20type-pred=0A-=20=20=20=20=20=20= (dolist=20(sub-form=20(cdr=20form))=0A-=09(unless=20(funcall=20type-pred=20= sub-form)=0A-=09=20=20(error=20"rx=20form=20`%s'=20requires=20args=20= satisfying=20`%s'"=0A-=09=09=20(car=20form)=20type-pred))))))=0A-=0A-=0A= -(defun=20rx-group-if=20(regexp=20group)=0A-=20=20"Put=20shy=20groups=20= around=20REGEXP=20if=20seemingly=20necessary=20when=20GROUP=0A-is=20= non-nil."=0A+;;=20The=20`rx--translate...'=20functions=20below=20return=20= (REGEXP=20.=20PRECEDENCE),=0A+;;=20where=20REGEXP=20is=20a=20list=20of=20= string=20expressions=20that=20will=20be=0A+;;=20concatenated=20into=20a=20= regexp,=20and=20PRECEDENCE=20is=20one=20of=0A+;;=0A+;;=20=20t=20=20=20=20= --=20can=20be=20used=20as=20argument=20to=20postfix=20operators=20(eg.=20= "a")=0A+;;=20=20seq=20=20--=20can=20be=20concatenated=20in=20sequence=20= with=20other=20seq=20or=20higher=20(eg.=20"ab")=0A+;;=20=20lseq=20--=20= can=20be=20concatenated=20to=20the=20left=20of=20rseq=20or=20higher=20= (eg.=20"^a")=0A+;;=20=20rseq=20--=20can=20be=20concatenated=20to=20the=20= right=20of=20lseq=20or=20higher=20(eg.=20"a$")=0A+;;=20=20nil=20=20--=20= can=20only=20be=20used=20in=20alternatives=20(eg.=20"a\\|b")=0A+;;=0A+;;=20= They=20form=20a=20lattice:=0A+;;=0A+;;=20=20=20=20=20=20=20=20=20=20=20t=20= =20=20=20=20=20=20=20=20=20highest=20precedence=0A+;;=20=20=20=20=20=20=20= =20=20=20=20|=0A+;;=20=20=20=20=20=20=20=20=20=20seq=0A+;;=20=20=20=20=20= =20=20=20=20/=20=20=20\=0A+;;=20=20=20=20=20=20lseq=20=20=20rseq=0A+;;=20= =20=20=20=20=20=20=20=20\=20=20=20/=0A+;;=20=20=20=20=20=20=20=20=20=20= nil=20=20=20=20=20=20=20=20=20lowest=20precedence=0A+=0A+=0A+(defconst=20= rx--char-classes=0A+=20=20'((digit=20=20=20=20=20=20=20=20=20.=20digit)=0A= +=20=20=20=20(numeric=20=20=20=20=20=20=20.=20digit)=0A+=20=20=20=20(num=20= =20=20=20=20=20=20=20=20=20=20.=20digit)=0A+=20=20=20=20(control=20=20=20= =20=20=20=20.=20cntrl)=0A+=20=20=20=20(cntrl=20=20=20=20=20=20=20=20=20.=20= cntrl)=0A+=20=20=20=20(hex-digit=20=20=20=20=20.=20xdigit)=0A+=20=20=20=20= (hex=20=20=20=20=20=20=20=20=20=20=20.=20xdigit)=0A+=20=20=20=20(xdigit=20= =20=20=20=20=20=20=20.=20xdigit)=0A+=20=20=20=20(blank=20=20=20=20=20=20=20= =20=20.=20blank)=0A+=20=20=20=20(graphic=20=20=20=20=20=20=20.=20graph)=0A= +=20=20=20=20(graph=20=20=20=20=20=20=20=20=20.=20graph)=0A+=20=20=20=20= (printing=20=20=20=20=20=20.=20print)=0A+=20=20=20=20(print=20=20=20=20=20= =20=20=20=20.=20print)=0A+=20=20=20=20(alphanumeric=20=20.=20alnum)=0A+=20= =20=20=20(alnum=20=20=20=20=20=20=20=20=20.=20alnum)=0A+=20=20=20=20= (letter=20=20=20=20=20=20=20=20.=20alpha)=0A+=20=20=20=20(alphabetic=20=20= =20=20.=20alpha)=0A+=20=20=20=20(alpha=20=20=20=20=20=20=20=20=20.=20= alpha)=0A+=20=20=20=20(ascii=20=20=20=20=20=20=20=20=20.=20ascii)=0A+=20=20= =20=20(nonascii=20=20=20=20=20=20.=20nonascii)=0A+=20=20=20=20(lower=20=20= =20=20=20=20=20=20=20.=20lower)=0A+=20=20=20=20(lower-case=20=20=20=20.=20= lower)=0A+=20=20=20=20(punctuation=20=20=20.=20punct)=0A+=20=20=20=20= (punct=20=20=20=20=20=20=20=20=20.=20punct)=0A+=20=20=20=20(space=20=20=20= =20=20=20=20=20=20.=20space)=0A+=20=20=20=20(whitespace=20=20=20=20.=20= space)=0A+=20=20=20=20(white=20=20=20=20=20=20=20=20=20.=20space)=0A+=20=20= =20=20(upper=20=20=20=20=20=20=20=20=20.=20upper)=0A+=20=20=20=20= (upper-case=20=20=20=20.=20upper)=0A+=20=20=20=20(word=20=20=20=20=20=20=20= =20=20=20.=20word)=0A+=20=20=20=20(wordchar=20=20=20=20=20=20.=20word)=0A= +=20=20=20=20(unibyte=20=20=20=20=20=20=20.=20unibyte)=0A+=20=20=20=20= (multibyte=20=20=20=20=20.=20multibyte))=0A+=20=20"Alist=20mapping=20rx=20= symbols=20to=20character=20classes.=0A+Most=20of=20the=20names=20are=20= from=20SRE.")=0A+=0A+(defvar=20rx-constituents=20nil=0A+=20=20"Alist=20= of=20old-style=20rx=20extensions,=20for=20compatibility.=0A+=0A+Each=20= element=20is=20(SYMBOL=20.=20DEF).=0A+=0A+If=20DEF=20is=20a=20symbol,=20= then=20SYMBOL=20is=20an=20alias=20of=20DEF.=0A+=0A+If=20DEF=20is=20a=20= string,=20then=20SYMBOL=20is=20a=20plain=20rx=20symbol=20defined=20as=20= the=0A+=20=20=20regexp=20string=20DEF.=0A+=0A+If=20DEF=20is=20a=20list=20= on=20the=20form=20(FUN=20MIN-ARGS=20MAX-ARGS=20PRED),=20then=0A+=20=20=20= SYMBOL=20is=20an=20rx=20form=20with=20at=20least=20MIN-ARGS=20and=20at=20= most=0A+=20=20=20MAX-ARGS=20arguments.=20=20If=20MAX-ARGS=20is=20nil,=20= then=20there=20is=20no=20upper=20limit.=0A+=20=20=20FUN=20is=20a=20= function=20taking=20the=20entire=20rx=20form=20as=20single=20argument=0A= +=20=20=20and=20returning=20the=20translated=20regexp=20string.=0A+=20=20= =20If=20PRED=20is=20non-nil,=20it=20is=20a=20predicate=20that=20all=20= actual=20arguments=20must=0A+=20=20=20satisfy.")=0A+=0A+;;=20TODO:=20= Additions=20to=20consider:=0A+;;=20-=20A=20better=20name=20for=20= `anything',=20like=20`any-char'=20or=20`anychar'.=0A+;;=20-=20A=20name=20= for=20(or),=20maybe=20`unmatchable'.=0A+;;=20-=20A=20construct=20like=20= `or'=20but=20without=20the=20match=20order=20guarantee,=0A+;;=20=20=20= maybe=20`unordered-or'.=20=20Useful=20for=20composition=20or=20= generation=20of=0A+;;=20=20=20alternatives;=20permits=20more=20effective=20= use=20of=20regexp-opt.=0A+=0A+(defun=20rx--translate-symbol=20(sym)=0A+=20= =20"Translate=20an=20rx=20symbol.=20=20Return=20(REGEXP=20.=20= PRECEDENCE)."=0A+=20=20(pcase=20sym=0A+=20=20=20=20;;=20Use=20`list'=20= instead=20of=20a=20quoted=20list=20to=20wrap=20the=20strings=20here,=0A+=20= =20=20=20;;=20since=20the=20return=20value=20may=20be=20mutated.=0A+=20=20= =20=20((or=20'nonl=20'not-newline=20'any)=20(cons=20(list=20".")=20t))=0A= +=20=20=20=20('anything=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(rx--translate-form=20'(or=20nonl=20"\n")))=0A+=20=20=20=20((or=20= 'bol=20'line-start)=20=20=20=20=20=20=20=20(cons=20(list=20"^")=20= 'lseq))=0A+=20=20=20=20((or=20'eol=20'line-end)=20=20=20=20=20=20=20=20=20= =20(cons=20(list=20"$")=20'rseq))=0A+=20=20=20=20((or=20'bos=20= 'string-start=20'bot=20'buffer-start)=20(cons=20(list=20"\\`")=20t))=0A+=20= =20=20=20((or=20'eos=20'string-end=20=20=20'eot=20'buffer-end)=20=20=20= (cons=20(list=20"\\'")=20t))=0A+=20=20=20=20('point=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(list=20"\\=3D")=20= t))=0A+=20=20=20=20((or=20'bow=20'word-start)=20=20=20=20=20=20=20=20= (cons=20(list=20"\\<")=20t))=0A+=20=20=20=20((or=20'eow=20'word-end)=20=20= =20=20=20=20=20=20=20=20(cons=20(list=20"\\>")=20t))=0A+=20=20=20=20= ('word-boundary=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cons=20= (list=20"\\b")=20t))=0A+=20=20=20=20('not-word-boundary=20=20=20=20=20=20= =20=20=20=20=20(cons=20(list=20"\\B")=20t))=0A+=20=20=20=20= ('symbol-start=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cons=20= (list=20"\\_<")=20t))=0A+=20=20=20=20('symbol-end=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(cons=20(list=20"\\_>")=20t))=0A+=20=20=20=20= ('not-wordchar=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cons=20= (list=20"\\W")=20t))=0A+=20=20=20=20(_=0A+=20=20=20=20=20(cond=0A+=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(and=20class=20(cons=20(list=20(concat=20"[[:"=20= (symbol-name=20class)=20":]]"))=20t))))=0A+=0A+=20=20=20=20=20=20;;=20= For=20compatibility=20with=20old=20rx.=0A+=20=20=20=20=20=20((let=20= ((entry=20(assq=20sym=20rx-constituents)))=0A+=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(while=20= (and=20entry=20(not=20(stringp=20(cdr=20entry))))=0A+=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(if=20(symbolp=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= =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= (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;;=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(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(cdr=20(memq=20entry=20rx-constituents))))))=0A+=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(cons=20(list=20(cdr=20entry))=20nil))))=0A+=20=20=20=20=20=20= (t=20(error=20"Unknown=20rx=20symbol=20`%s'"=20sym))))))=0A+=0A+(defun=20= rx--enclose=20(left-str=20rexp=20right-str)=0A+=20=20"Bracket=20REXP=20= by=20LEFT-STR=20and=20RIGHT-STR."=0A+=20=20(append=20(list=20left-str)=20= rexp=20(list=20right-str)))=0A+=0A+(defun=20rx--bracket=20(rexp)=0A+=20=20= (rx--enclose=20"\\(?:"=20rexp=20"\\)"))=0A+=0A+(defun=20rx--sequence=20= (left=20right)=0A+=20=20"Return=20the=20sequence=20(concatenation)=20of=20= two=20translated=20items,=0A+each=20on=20the=20form=20(REGEXP=20.=20= PRECEDENCE),=20returning=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20;;=20= Concatenation=20rules:=0A+=20=20;;=20=20seq=20=20++=20seq=20=20->=20seq=0A= +=20=20;;=20=20lseq=20++=20seq=20=20->=20lseq=0A+=20=20;;=20=20seq=20=20= ++=20rseq=20->=20rseq=0A+=20=20;;=20=20lseq=20++=20rseq=20->=20nil=0A+=20= =20(cond=20((not=20(car=20left))=20right)=0A+=20=20=20=20=20=20=20=20= ((not=20(car=20right))=20left)=0A+=20=20=20=20=20=20=20=20(t=0A+=20=20=20= =20=20=20=20=20=20(let=20((l=20(if=20(memq=20(cdr=20left)=20'(nil=20= rseq))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(cons=20(rx--bracket=20(car=20left))=20t)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20left))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(r=20(if=20(memq=20(cdr=20right)=20'(nil=20lseq))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cons=20= (rx--bracket=20(car=20right))=20t)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20right)))=0A+=20=20=20=20=20=20=20=20=20=20=20= (cons=20(append=20(car=20l)=20(car=20r))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(if=20(eq=20(cdr=20l)=20'lseq)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(eq=20(cdr=20r)=20= 'rseq)=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=20nil=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ;=20lseq=20++=20rseq=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20'lseq)=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20;=20lseq=20++=20seq=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(if=20(eq=20(cdr=20r)=20'rseq)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20'rseq=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20;=20seq=20++=20rseq=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20'seq)))))))=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20;=20seq=20++=20seq=0A+=0A+(defun=20= rx--translate-seq=20(body)=0A+=20=20"Translate=20a=20sequence=20of=20one=20= or=20more=20rx=20items.=20=20Return=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20= (if=20body=0A+=20=20=20=20=20=20(let*=20((items=20(mapcar=20= #'rx--translate=20body))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (result=20(car=20items)))=0A+=20=20=20=20=20=20=20=20(dolist=20(item=20= (cdr=20items))=0A+=20=20=20=20=20=20=20=20=20=20(setq=20result=20= (rx--sequence=20result=20item)))=0A+=20=20=20=20=20=20=20=20result)=0A+=20= =20=20=20(cons=20nil=20'seq)))=0A+=0A+(defun=20rx--empty=20()=0A+=20=20= "Regexp=20that=20never=20matches=20anything."=0A+=20=20(cons=20(list=20= regexp-unmatchable)=20'seq))=0A+=0A+;;=20`cl-every'=20replacement=20to=20= avoid=20bootstrapping=20problems.=0A+(defun=20rx--every=20(pred=20list)=0A= +=20=20"Whether=20PRED=20is=20true=20for=20every=20element=20of=20LIST."=0A= +=20=20(while=20(and=20list=20(funcall=20pred=20(car=20list)))=0A+=20=20=20= =20(setq=20list=20(cdr=20list)))=0A+=20=20(null=20list))=0A+=0A+(defun=20= rx--translate-or=20(body)=0A+=20=20"Translate=20an=20or-pattern=20of=20= one=20of=20more=20rx=20items.=0A+Return=20(REGEXP=20.=20PRECEDENCE)."=0A= +=20=20;;=20FIXME:=20Possible=20improvements:=0A+=20=20;;=0A+=20=20;;=20= -=20Turn=20single=20characters=20to=20strings:=20(or=20?a=20?b)=20->=20= (or=20"a"=20"b"),=0A+=20=20;;=20=20=20so=20that=20they=20can=20be=20= candidates=20for=20regexp-opt.=0A+=20=20;;=0A+=20=20;;=20-=20Translate=20= compile-time=20strings=20(`eval'=20forms),=20again=20for=20regexp-opt.=0A= +=20=20;;=0A+=20=20;;=20-=20Flatten=20sub-patterns=20first:=20(or=20(or=20= A=20B)=20(or=20C=20D))=20->=20(or=20A=20B=20C=20D)=0A+=20=20;;=20=20=20= in=20order=20to=20improve=20effectiveness=20of=20regexp-opt.=0A+=20=20;;=20= =20=20This=20would=20also=20help=20composability.=0A+=20=20;;=0A+=20=20= ;;=20-=20Use=20associativity=20to=20run=20regexp-opt=20on=20contiguous=20= subsets=20of=20arguments=0A+=20=20;;=20=20=20if=20not=20all=20of=20them=20= are=20strings.=20=20Example:=0A+=20=20;;=20=20=20(or=20(+=20digit)=20= "CHARLIE"=20"CHAN"=20(+=20blank))=0A+=20=20;;=20=20=20->=20(or=20(+=20= digit)=20(or=20"CHARLIE"=20"CHAN")=20(+=20blank))=0A+=20=20;;=0A+=20=20= ;;=20-=20Fuse=20patterns=20into=20a=20single=20character=20alternative=20= if=20they=20fit.=0A+=20=20;;=20=20=20regexp-opt=20will=20do=20that=20if=20= all=20are=20strings,=20but=20we=20want=20to=20do=20that=20for:=0A+=20=20= ;;=20=20=20=20=20*=20symbols=20that=20expand=20to=20classes:=20space,=20= alpha,=20...=0A+=20=20;;=20=20=20=20=20*=20character=20alternatives:=20= (any=20...)=0A+=20=20;;=20=20=20=20=20*=20(syntax=20S),=20for=20some=20S=20= (whitespace,=20word)=0A+=20=20;;=20=20=20so=20that=20(or=20"@"=20"%"=20= digit=20(any=20"A-Z"=20space)=20(syntax=20word))=0A+=20=20;;=20=20=20=20=20= =20=20=20->=20(any=20"@"=20"%"=20digit=20"A-Z"=20space=20word)=0A+=20=20= ;;=20=20=20=20=20=20=20=20->=20"[A-Z@%[:digit:][:space:][:word:]]"=0A+=20= =20;;=0A+=20=20;;=20Problem:=20If=20a=20subpattern=20is=20carefully=20= written=20to=20to=20be=0A+=20=20;;=20optimisable=20by=20regexp-opt,=20= how=20do=20we=20prevent=20the=20transforms=0A+=20=20;;=20above=20from=20= destroying=20that=20property?=0A+=20=20;;=20Example:=20(or=20"a"=20(or=20= "abc"=20"abd"=20"abe"))=0A=20=20=20(cond=0A-=20=20=20;;=20for=20some=20= repetition=0A-=20=20=20((eq=20group=20'*)=20(if=20(rx-atomic-p=20regexp)=20= (setq=20group=20nil)))=0A-=20=20=20;;=20for=20concatenation=0A-=20=20=20= ((eq=20group=20':)=0A-=20=20=20=20(if=20(rx-atomic-p=0A-=20=20=20=20=20=20= =20=20=20(if=20(and=20(stringp=20regexp)=0A-=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(string-match=0A-=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20= "\\(?:[?*+]\\??\\|\\\\{[0-9]*,?[0-9]*\\\\}\\)\\'"=20regexp))=0A-=09=20=20= =20=20=20(substring=20regexp=200=20(match-beginning=200))=0A-=09=20=20=20= regexp))=0A-=09(setq=20group=20nil)))=0A-=20=20=20;;=20for=20OR=0A-=20=20= =20((eq=20group=20'|)=20(setq=20group=20nil))=0A-=20=20=20;;=20do=20= anyway=0A-=20=20=20((eq=20group=20t))=0A-=20=20=20((rx-atomic-p=20regexp=20= t)=20(setq=20group=20nil)))=0A-=20=20(cond=20((and=20group=20(stringp=20= regexp))=0A-=20=20=20=20=20=20=20=20=20(concat=20"\\(?:"=20regexp=20= "\\)"))=0A-=20=20=20=20=20=20=20=20(group=20`("\\(?:"=20,@regexp=20= "\\)"))=0A-=20=20=20=20=20=20=20=20(t=20regexp)))=0A-=0A-=0A-(defvar=20= rx-parent)=0A-;;=20dynamically=20bound=20in=20some=20functions.=0A-=0A-=0A= -(defun=20rx-and=20(form)=0A-=20=20"Parse=20and=20produce=20code=20from=20= FORM.=0A-FORM=20is=20of=20the=20form=20`(and=20FORM1=20...)'."=0A-=20=20= (rx-check=20form)=0A-=20=20(rx-group-if=0A-=20=20=20(rx--subforms=20(cdr=20= form)=20':)=0A-=20=20=20(and=20(memq=20rx-parent=20'(*=20t))=20= rx-parent)))=0A-=0A-=0A-(defun=20rx-or=20(form)=0A-=20=20"Parse=20and=20= produce=20code=20from=20FORM,=20which=20is=20`(or=20FORM1=20...)'."=0A-=20= =20(rx-check=20form)=0A-=20=20(rx-group-if=0A-=20=20=20(cond=0A-=20=20=20= =20((null=20(cdr=20form))=20regexp-unmatchable)=0A-=20=20=20=20= ((cl-every=20#'stringp=20(cdr=20form))=0A-=20=20=20=20=20(regexp-opt=20= (cdr=20form)=20nil=20t))=0A-=20=20=20=20(t=20(rx--subforms=20(cdr=20= form)=20'|=20"\\|")))=0A-=20=20=20(and=20(memq=20rx-parent=20'(:=20*=20= t))=20rx-parent)))=0A-=0A-=0A-(defun=20rx-anything=20(form)=0A-=20=20= "Match=20any=20character."=0A-=20=20(if=20(consp=20form)=0A-=20=20=20=20=20= =20(error=20"rx=20`anything'=20syntax=20error:=20%s"=20form))=0A-=20=20= (rx-or=20(list=20'or=20'not-newline=20?\n)))=0A-=0A-=0A-(defun=20= rx-any-delete-from-range=20(char=20ranges)=0A-=20=20"Delete=20by=20side=20= effect=20character=20CHAR=20from=20RANGES.=0A-Only=20both=20edges=20of=20= each=20range=20is=20checked."=0A-=20=20(let=20(m)=0A-=20=20=20=20(cond=0A= -=20=20=20=20=20((memq=20char=20ranges)=20(setq=20ranges=20(delq=20char=20= ranges)))=0A-=20=20=20=20=20((setq=20m=20(assq=20char=20ranges))=0A-=20=20= =20=20=20=20(if=20(eq=20(1+=20char)=20(cdr=20m))=0A-=09=20=20(setcar=20= (memq=20m=20ranges)=20(1+=20char))=0A-=09(setcar=20m=20(1+=20char))))=0A= -=20=20=20=20=20((setq=20m=20(rassq=20char=20ranges))=0A-=20=20=20=20=20=20= (if=20(eq=20(1-=20char)=20(car=20m))=0A-=09=20=20(setcar=20(memq=20m=20= ranges)=20(1-=20char))=0A-=09(setcdr=20m=20(1-=20char)))))=0A-=20=20=20=20= ranges))=0A-=0A-=0A-(defun=20rx-any-condense-range=20(args)=0A-=20=20= "Condense=20by=20side=20effect=20ARGS=20as=20range=20for=20Rx=20`any'."=0A= -=20=20(let=20(str=0A-=09l)=0A-=20=20=20=20;;=20set=20STR=20list=20of=20= all=20strings=0A-=20=20=20=20;;=20set=20L=20list=20of=20all=20ranges=0A-=20= =20=20=20(mapc=20(lambda=20(e)=20(cond=20((stringp=20e)=20(push=20e=20= str))=0A-=09=09=09=20=20=20=20((numberp=20e)=20(push=20(cons=20e=20e)=20= l))=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;;=20Ranges=20between=20ASCII=20and=20raw=20bytes=20= are=20split,=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;;=20to=20prevent=20accidental=20inclusion=20= of=20Unicode=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;;=20characters=20later=20on.=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= ((and=20(<=3D=20(car=20e)=20#x7f)=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(>=3D=20= (cdr=20e)=20#x3fff80))=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(push=20(cons=20(car=20e)=20#x7f)=20= l)=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(push=20(cons=20#x3fff80=20(cdr=20e))=20l))=0A-=09=09=09= =20=20=20=20(t=20(push=20e=20l))))=0A-=09=20=20args)=0A-=20=20=20=20;;=20= condense=20overlapped=20ranges=20in=20L=0A-=20=20=20=20(let=20((tail=20= (setq=20l=20(sort=20l=20#'car-less-than-car)))=0A-=09=20=20d)=0A-=20=20=20= =20=20=20(while=20(setq=20d=20(cdr=20tail))=0A-=09(if=20(>=3D=20(cdar=20= tail)=20(1-=20(caar=20d)))=0A-=09=20=20=20=20(progn=0A-=09=20=20=20=20=20= =20(setcdr=20(car=20tail)=20(max=20(cdar=20tail)=20(cdar=20d)))=0A-=09=20= =20=20=20=20=20(setcdr=20tail=20(cdr=20d)))=0A-=09=20=20(setq=20tail=20= d))))=0A-=20=20=20=20;;=20Separate=20small=20ranges=20to=20single=20= number,=20and=20delete=20dups.=0A-=20=20=20=20(nconc=0A-=20=20=20=20=20= (apply=20#'nconc=0A-=09=20=20=20=20(mapcar=20(lambda=20(e)=0A-=09=09=20=20= =20=20=20=20(cond=0A-=09=09=20=20=20=20=20=20=20((=3D=20(car=20e)=20(cdr=20= e))=20(list=20(car=20e)))=0A-=09=09=20=20=20=20=20=20=20((=3D=20(1+=20= (car=20e))=20(cdr=20e))=20(list=20(car=20e)=20(cdr=20e)))=0A-=09=09=20=20= =20=20=20=20=20((list=20e))))=0A-=09=09=20=20=20=20l))=0A-=20=20=20=20=20= (delete-dups=20str))))=0A-=0A-=0A-(defun=20rx-check-any-string=20(str)=0A= -=20=20"Turn=20the=20`any'=20argument=20string=20STR=20into=20a=20list=20= of=20characters.=0A-The=20original=20order=20is=20not=20preserved.=20=20= Ranges,=20\"A-Z\",=20become=20pairs,=20(?A=20.=20?Z)."=0A+=20=20=20= ((null=20body)=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ;=20No=20items:=20a=20never-matching=20regexp.=0A+=20=20=20=20= (rx--empty))=0A+=20=20=20((null=20(cdr=20body))=20=20=20=20=20=20=20=20=20= =20=20=20=20=20;=20Single=20item.=0A+=20=20=20=20(rx--translate=20(car=20= body)))=0A+=20=20=20((rx--every=20#'stringp=20body)=20=20=20=20=20;=20= All=20strings.=0A+=20=20=20=20(cons=20(list=20(regexp-opt=20body=20nil=20= t))=0A+=20=20=20=20=20=20=20=20=20=20t))=0A+=20=20=20(t=0A+=20=20=20=20= (cons=20(append=20(car=20(rx--translate=20(car=20body)))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(mapcan=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=20=20=20= =20(cons=20"\\|"=20(car=20(rx--translate=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(cdr=20= body)))=0A+=20=20=20=20=20=20=20=20=20=20nil))))=0A+=0A+(defun=20= rx--string-to-intervals=20(str)=0A+=20=20"Decode=20STR=20as=20intervals:=20= A-Z=20becomes=20(?A=20.=20?Z),=20and=20the=20single=0A+character=20X=20= becomes=20(?X=20.=20?X).=20=20Return=20the=20intervals=20in=20a=20list."=0A= +=20=20;;=20We=20could=20just=20do=20string-to-multibyte=20on=20the=20= string=20and=20work=20with=0A+=20=20;;=20that=20instead=20of=20this=20= `decode-char'=20workaround.=0A=20=20=20(let=20((decode-char=0A-=20=20=20=20= =20=20=20=20=20;;=20Make=20sure=20raw=20bytes=20are=20decoded=20as=20= such,=20to=20avoid=20confusion=20with=0A-=20=20=20=20=20=20=20=20=20;;=20= U+0080..U+00FF.=0A=20=20=20=20=20=20=20=20=20=20(if=20= (multibyte-string-p=20str)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= #'identity=0A-=20=20=20=20=20=20=20=20=20=20=20(lambda=20(c)=20(if=20(<=3D= =20#x80=20c=20#xff)=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(+=20c=20#x3fff00)=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=20c))))=0A+=20=20=20=20= =20=20=20=20=20=20=20#'unibyte-char-to-multibyte))=0A=20=20=20=20=20=20=20= =20=20(len=20(length=20str))=0A=20=20=20=20=20=20=20=20=20(i=200)=0A-=20=20= =20=20=20=20=20=20(ret=20nil))=0A-=20=20=20=20(if=20(=3D=200=20len)=0A-=20= =20=20=20=20=20=20=20(error=20"String=20arg=20for=20Rx=20`any'=20must=20= not=20be=20empty"))=0A+=20=20=20=20=20=20=20=20(intervals=20nil))=0A=20=20= =20=20=20(while=20(<=20i=20len)=0A=20=20=20=20=20=20=20(cond=20((and=20= (<=20i=20(-=20len=202))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(=3D=20(aref=20str=20(+=20i=201))=20?-))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(=3D=20(aref=20str=20(1+=20i))=20?-))=0A=20= =20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Range.=0A=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(let=20((start=20(funcall=20decode-char=20(aref=20= str=20i)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (end=20=20=20(funcall=20decode-char=20(aref=20str=20(+=20i=202)))))=0A-=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(cond=20((<=20start=20end)=20= (push=20(cons=20start=20end)=20ret))=0A-=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20((=3D=20start=20end)=20(push=20start=20= ret))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cond=20((and=20= (<=3D=20start=20#x7f)=20(>=3D=20end=20#x3fff80))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Ranges=20between=20= ASCII=20and=20raw=20bytes=20are=20split=20to=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20;;=20avoid=20having=20them=20= absorb=20Unicode=20characters=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20;;=20caught=20in-between.=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(push=20(cons=20start=20= #x7f)=20intervals)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(push=20(cons=20#x3fff80=20end)=20intervals))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((<=3D=20start=20= end)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (push=20(cons=20start=20end)=20intervals))=0A=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(error=20"Rx=20character=20range=20= `%c-%c'=20is=20reversed"=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=20start=20end)))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(error=20"Invalid=20= rx=20`any'=20range:=20%s"=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(substring=20str=20i=203))))=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20i=20(+=20i=20= 3))))=0A=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;;=20Single=20character.=0A-=20=20=20=20=20=20=20=20= =20=20=20=20=20(push=20(funcall=20decode-char=20(aref=20str=20i))=20ret)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((char=20(funcall=20= decode-char=20(aref=20str=20i))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(push=20(cons=20char=20char)=20intervals))=0A=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(setq=20i=20(+=20i=201)))))=0A-=20=20=20=20ret))=0A= -=0A-=0A-(defun=20rx-check-any=20(arg)=0A-=20=20=20"Check=20arg=20ARG=20= for=20Rx=20`any'."=0A-=20=20=20(cond=0A-=20=20=20=20((integerp=20arg)=20= (list=20arg))=0A-=20=20=20=20((symbolp=20arg)=0A-=20=20=20=20=20(let=20= ((translation=20(condition-case=20nil=0A-=09=09=09=20=20=20=20(rx-form=20= arg)=0A-=09=09=09=20=20(error=20nil))))=0A-=20=20=20=20=20=20=20(if=20= (or=20(null=20translation)=0A-=09=20=20=20=20=20=20=20(null=20= (string-match=20"\\`\\[\\[:[-a-z]+:\\]\\]\\'"=20translation)))=0A-=09=20=20= =20(error=20"Invalid=20char=20class=20`%s'=20in=20Rx=20`any'"=20arg))=0A= -=20=20=20=20=20=20=20(list=20(substring=20translation=201=20-1))))=20;=20= strip=20outer=20brackets=0A-=20=20=20=20((and=20(characterp=20(car-safe=20= arg))=20(characterp=20(cdr-safe=20arg)))=0A-=20=20=20=20=20(unless=20(<=3D= =20(car=20arg)=20(cdr=20arg))=0A-=20=20=20=20=20=20=20(error=20"Rx=20= character=20range=20`%c-%c'=20is=20reversed"=0A-=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(car=20arg)=20(cdr=20arg)))=0A-=20=20=20=20=20(list=20= arg))=0A-=20=20=20=20((stringp=20arg)=20(rx-check-any-string=20arg))=0A-=20= =20=20=20((error=0A-=20=20=20=20=20=20"rx=20`any'=20requires=20string,=20= character,=20char=20pair=20or=20char=20class=20args"))))=0A-=0A-=0A= -(defun=20rx-any=20(form)=0A-=20=20"Parse=20and=20produce=20code=20from=20= FORM,=20which=20is=20`(any=20ARG=20...)'.=0A-ARG=20is=20optional."=0A-=20= =20(rx-check=20form)=0A-=20=20(let*=20((args=20(rx-any-condense-range=0A= -=09=09(apply=0A-=09=09=20#'nconc=0A-=09=09=20(mapcar=20#'rx-check-any=20= (cdr=20form)))))=0A-=09=20m=0A-=09=20s)=0A-=20=20=20=20(cond=0A-=20=20=20= =20=20;;=20single=20close=20bracket=0A-=20=20=20=20=20;;=09=20=3D>=20= "[]...-]"=20or=20"[]...--.]"=0A-=20=20=20=20=20((memq=20?\]=20args)=0A-=20= =20=20=20=20=20;;=20set=20]=20at=20the=20beginning=0A-=20=20=20=20=20=20= (setq=20args=20(cons=20?\]=20(delq=20?\]=20args)))=0A-=20=20=20=20=20=20= ;;=20set=20-=20at=20the=20end=0A-=20=20=20=20=20=20(if=20(or=20(memq=20= ?-=20args)=20(assq=20?-=20args))=0A-=09=20=20(setq=20args=20(nconc=20= (rx-any-delete-from-range=20?-=20args)=0A-=09=09=09=20=20=20=20(list=20= ?-)))))=0A-=20=20=20=20=20;;=20close=20bracket=20starts=20a=20range=0A-=20= =20=20=20=20;;=20=20=3D>=20"[]-....-]"=20or=20"[]-.--....]"=0A-=20=20=20=20= =20((setq=20m=20(assq=20?\]=20args))=0A-=20=20=20=20=20=20;;=20bring=20= it=20to=20the=20beginning=0A-=20=20=20=20=20=20(setq=20args=20(cons=20m=20= (delq=20m=20args)))=0A-=20=20=20=20=20=20(cond=20((memq=20?-=20args)=0A-=09= =20=20=20=20=20;;=20to=20the=20end=0A-=09=20=20=20=20=20(setq=20args=20= (nconc=20(delq=20?-=20args)=20(list=20?-))))=0A-=09=20=20=20=20((setq=20= m=20(assq=20?-=20args))=0A-=09=20=20=20=20=20;;=20next=20to=20the=20= bracket's=20range,=20make=20the=20second=20range=0A-=09=20=20=20=20=20= (setcdr=20args=20(cons=20m=20(delq=20m=20(cdr=20args)))))))=0A-=20=20=20=20= =20;;=20bracket=20in=20the=20end=20range=0A-=20=20=20=20=20;;=09=20=3D>=20= "[]...-]"=0A-=20=20=20=20=20((setq=20m=20(rassq=20?\]=20args))=0A-=20=20=20= =20=20=20;;=20set=20]=20at=20the=20beginning=0A-=20=20=20=20=20=20(setq=20= args=20(cons=20?\]=20(rx-any-delete-from-range=20?\]=20args)))=0A-=20=20=20= =20=20=20;;=20set=20-=20at=20the=20end=0A-=20=20=20=20=20=20(if=20(or=20= (memq=20?-=20args)=20(assq=20?-=20args))=0A-=09=20=20(setq=20args=20= (nconc=20(rx-any-delete-from-range=20?-=20args)=0A-=09=09=09=20=20=20=20= (list=20?-)))))=0A-=20=20=20=20=20;;=20{no=20close=20bracket=20appears}=0A= -=20=20=20=20=20;;=0A-=20=20=20=20=20;;=20bring=20single=20bar=20to=20= the=20beginning=0A-=20=20=20=20=20((memq=20?-=20args)=0A-=20=20=20=20=20=20= (setq=20args=20(cons=20?-=20(delq=20?-=20args))))=0A-=20=20=20=20=20;;=20= bar=20start=20a=20range,=20bring=20it=20to=20the=20beginning=0A-=20=20=20= =20=20((setq=20m=20(assq=20?-=20args))=0A-=20=20=20=20=20=20(setq=20args=20= (cons=20m=20(delq=20m=20args))))=0A-=20=20=20=20=20;;=0A-=20=20=20=20=20= ;;=20hat=20at=20the=20beginning?=0A-=20=20=20=20=20((or=20(eq=20(car=20= args)=20?^)=20(eq=20(car-safe=20(car=20args))=20?^))=0A-=20=20=20=20=20=20= (setq=20args=20(if=20(cdr=20args)=0A-=09=09=20=20=20=20=20`(,(cadr=20= args)=20,(car=20args)=20,@(cddr=20args))=0A-=09=09=20=20=20(nconc=20= (rx-any-delete-from-range=20?^=20args)=0A-=09=09=09=20=20(list=20= ?^))))))=0A-=20=20=20=20;;=20some=201-char?=0A-=20=20=20=20(if=20(and=20= (null=20(cdr=20args))=20(numberp=20(car=20args))=0A-=09=20=20=20=20=20= (or=20(=3D=201=20(length=0A-=09=09=20=20=20=20=20=20=20(setq=20s=20= (regexp-quote=20(string=20(car=20args))))))=0A-=09=09=20(and=20(equal=20= (car=20args)=20?^)=20;;=20unnecessary=20predicate?=0A-=09=09=20=20=20=20=20= =20(null=20(eq=20rx-parent=20'!)))))=0A-=09s=0A-=20=20=20=20=20=20= (concat=20"["=0A-=09=20=20=20=20=20=20(mapconcat=0A-=09=20=20=20=20=20=20= =20(lambda=20(e)=20(cond=0A-=09=09=09=20=20=20=20((numberp=20e)=20= (string=20e))=0A-=09=09=09=20=20=20=20((consp=20e)=0A-=09=09=09=20=20=20=20= =20(if=20(and=20(=3D=20(1+=20(car=20e))=20(cdr=20e))=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=20=20=20;;=20rx-any-condense-range=20should=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=20=20=20;;=20prevent=20this=20case=20from=20happening.=0A= -=09=09=09=09=20=20=20=20=20=20(null=20(memq=20(car=20e)=20'(?\]=20?-)))=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=20=20=20(null=20(memq=20(cdr=20e)=20= '(?\]=20?-))))=0A-=09=09=09=09=20(string=20(car=20e)=20(cdr=20e))=0A-=09=09= =09=20=20=20=20=20=20=20(string=20(car=20e)=20?-=20(cdr=20e))))=0A-=09=09= =09=20=20=20=20(e)))=0A-=09=20=20=20=20=20=20=20args=0A-=09=20=20=20=20=20= =20=20nil)=0A-=09=20=20=20=20=20=20"]"))))=0A-=0A-=0A-(defun=20= rx-check-not=20(arg)=0A-=20=20"Check=20arg=20ARG=20for=20Rx=20`not'."=0A= -=20=20(unless=20(or=20(and=20(symbolp=20arg)=0A-=09=09=20=20=20= (string-match=20"\\`\\[\\[:[-a-z]+:\\]\\]\\'"=0A-=09=09=09=09=20= (condition-case=20nil=0A-=09=09=09=09=20=20=20=20=20(rx-form=20arg)=0A-=09= =09=09=09=20=20=20(error=20""))))=0A-=09=20=20=20=20=20=20(eq=20arg=20= 'word-boundary)=0A-=09=20=20=20=20=20=20(and=20(consp=20arg)=0A-=09=09=20= =20=20(memq=20(car=20arg)=20'(not=20any=20in=20syntax=20category))))=0A-=20= =20=20=20(error=20"rx=20`not'=20syntax=20error:=20%s"=20arg))=0A-=20=20= t)=0A-=0A-=0A-(defun=20rx-not=20(form)=0A-=20=20"Parse=20and=20produce=20= code=20from=20FORM.=20=20FORM=20is=20`(not=20...)'."=0A-=20=20(rx-check=20= form)=0A-=20=20(let=20((result=20(rx-form=20(cadr=20form)=20'!))=0A-=09= case-fold-search)=0A-=20=20=20=20(cond=20((string-match=20"\\`\\[\\^"=20= result)=0A-=09=20=20=20(cond=0A-=09=20=20=20=20((equal=20result=20"[^]")=20= "[^^]")=0A-=09=20=20=20=20((and=20(=3D=20(length=20result)=204)=20(null=20= (eq=20rx-parent=20'!)))=0A-=09=20=20=20=20=20(regexp-quote=20(substring=20= result=202=203)))=0A-=09=20=20=20=20((concat=20"["=20(substring=20result=20= 2)))))=0A-=09=20=20((eq=20?\[=20(aref=20result=200))=0A-=09=20=20=20= (concat=20"[^"=20(substring=20result=201)))=0A-=09=20=20((string-match=20= "\\`\\\\[scbw]"=20result)=0A-=09=20=20=20(concat=20(upcase=20(substring=20= result=200=202))=0A-=09=09=20=20=20(substring=20result=202)))=0A-=09=20=20= ((string-match=20"\\`\\\\[SCBW]"=20result)=0A-=09=20=20=20(concat=20= (downcase=20(substring=20result=200=202))=0A-=09=09=20=20=20(substring=20= result=202)))=0A-=09=20=20(t=0A-=09=20=20=20(concat=20"[^"=20result=20= "]")))))=0A-=0A-=0A-(defun=20rx-not-char=20(form)=0A-=20=20"Parse=20and=20= produce=20code=20from=20FORM.=20=20FORM=20is=20`(not-char=20...)'."=0A-=20= =20(rx-check=20form)=0A-=20=20(rx-not=20`(not=20(in=20,@(cdr=20form)))))=0A= -=0A-=0A-(defun=20rx-not-syntax=20(form)=0A-=20=20"Parse=20and=20produce=20= code=20from=20FORM.=20=20FORM=20is=20`(not-syntax=20SYNTAX)'."=0A-=20=20= (rx-check=20form)=0A-=20=20(rx-not=20`(not=20(syntax=20,@(cdr=20= form)))))=0A-=0A-=0A-(defun=20rx-trans-forms=20(form=20&optional=20skip)=0A= -=20=20"If=20FORM's=20length=20is=20greater=20than=20two,=20transform=20= it=20to=20length=20two.=0A-A=20form=20(HEAD=20REST=20...)=20becomes=20= (HEAD=20(and=20REST=20...)).=0A-If=20SKIP=20is=20non-nil,=20allow=20that=20= number=20of=20items=20after=20the=20head,=20i.e.=0A-`(=3D=20N=20REST=20= ...)'=20becomes=20`(=3D=20N=20(and=20REST=20...))'=20if=20SKIP=20is=20= 1."=0A-=20=20(unless=20skip=20(setq=20skip=200))=0A-=20=20(let=20((tail=20= (nthcdr=20(1+=20skip)=20form)))=0A-=20=20=20=20(if=20(=3D=20(length=20= tail)=201)=0A-=09form=0A-=20=20=20=20=20=20(let=20((form=20= (copy-sequence=20form)))=0A-=09(setcdr=20(nthcdr=20skip=20form)=20(list=20= (cons=20'and=20tail)))=0A-=09form))))=0A-=0A-=0A-(defun=20rx-=3D=20= (form)=0A-=20=20"Parse=20and=20produce=20code=20from=20FORM=20`(=3D=20N=20= ...)'."=0A-=20=20(rx-check=20form)=0A-=20=20(setq=20form=20= (rx-trans-forms=20form=201))=0A-=20=20(unless=20(and=20(integerp=20(nth=20= 1=20form))=0A-=09=20=20=20=20=20=20=20(>=20(nth=201=20form)=200))=0A-=20=20= =20=20(error=20"rx=20`=3D'=20requires=20positive=20integer=20first=20= arg"))=0A-=20=20(let=20((subform=20(rx-form=20(nth=202=20form)=20'*)))=0A= -=20=20=20=20(if=20(stringp=20subform)=0A-=20=20=20=20=20=20=20=20= (format=20"%s\\{%d\\}"=20subform=20(nth=201=20form))=0A-=20=20=20=20=20=20= `(,@subform=20,(format=20"\\{%d\\}"=20(nth=201=20form))))))=0A-=0A-=0A= -(defun=20rx->=3D=20(form)=0A-=20=20"Parse=20and=20produce=20code=20from=20= FORM=20`(>=3D=20N=20...)'."=0A-=20=20(rx-check=20form)=0A-=20=20(setq=20= form=20(rx-trans-forms=20form=201))=0A-=20=20(unless=20(and=20(integerp=20= (nth=201=20form))=0A-=09=20=20=20=20=20=20=20(>=20(nth=201=20form)=200))=0A= -=20=20=20=20(error=20"rx=20`>=3D'=20requires=20positive=20integer=20= first=20arg"))=0A-=20=20(let=20((subform=20(rx-form=20(nth=202=20form)=20= '*)))=0A-=20=20=20=20(if=20(stringp=20subform)=0A-=20=20=20=20=20=20=20=20= (format=20"%s\\{%d,\\}"=20subform=20(nth=201=20form))=0A-=20=20=20=20=20=20= `(,@subform=20,(format=20"\\{%d,\\}"=20(nth=201=20form))))))=0A-=0A-=0A= -(defun=20rx-**=20(form)=0A-=20=20"Parse=20and=20produce=20code=20from=20= FORM=20`(**=20N=20M=20...)'."=0A-=20=20(rx-check=20form)=0A-=20=20= (rx-form=20(cons=20'repeat=20(cdr=20(rx-trans-forms=20form=202)))=20'*))=0A= -=0A-=0A-(defun=20rx-repeat=20(form)=0A-=20=20"Parse=20and=20produce=20= code=20from=20FORM.=0A-FORM=20is=20either=20`(repeat=20N=20FORM1)'=20or=20= `(repeat=20N=20M=20FORMS...)'."=0A-=20=20(rx-check=20form)=0A-=20=20(if=20= (>=20(length=20form)=204)=0A-=20=20=20=20=20=20(setq=20form=20= (rx-trans-forms=20form=202)))=0A-=20=20(if=20(null=20(nth=202=20form))=0A= -=20=20=20=20=20=20(setq=20form=20(cons=20(nth=200=20form)=20(cons=20= (nth=201=20form)=20(nthcdr=203=20form)))))=0A-=20=20(cond=20((=3D=20= (length=20form)=203)=0A-=09=20(unless=20(and=20(integerp=20(nth=201=20= form))=0A-=09=09=20=20=20=20=20=20(>=20(nth=201=20form)=200))=0A-=09=20=20= =20(error=20"rx=20`repeat'=20requires=20positive=20integer=20first=20= arg"))=0A-=20=20=20=20=20=20=20=20=20(let=20((subform=20(rx-form=20(nth=20= 2=20form)=20'*)))=0A-=20=20=20=20=20=20=20=20=20=20=20(if=20(stringp=20= subform)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(format=20= "%s\\{%d\\}"=20subform=20(nth=201=20form))=0A-=20=20=20=20=20=20=20=20=20= =20=20=20=20`(,@subform=20,(format=20"\\{%d\\}"=20(nth=201=20form))))))=0A= -=09((or=20(not=20(integerp=20(nth=202=20form)))=0A-=09=20=20=20=20=20(<=20= (nth=202=20form)=200)=0A-=09=20=20=20=20=20(not=20(integerp=20(nth=201=20= form)))=0A-=09=20=20=20=20=20(<=20(nth=201=20form)=200)=0A-=09=20=20=20=20= =20(<=20(nth=202=20form)=20(nth=201=20form)))=0A-=09=20(error=20"rx=20= `repeat'=20range=20error"))=0A-=09(t=0A-=20=20=20=20=20=20=20=20=20(let=20= ((subform=20(rx-form=20(nth=203=20form)=20'*)))=0A-=20=20=20=20=20=20=20=20= =20=20=20(if=20(stringp=20subform)=0A-=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(format=20"%s\\{%d,%d\\}"=20subform=20(nth=201=20form)=20(nth=20= 2=20form))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20`(,@subform=20= ,(format=20"\\{%d,%d\\}"=20(nth=201=20form)=20(nth=202=20form))))))))=0A= -=0A-=0A-(defun=20rx-submatch=20(form)=0A-=20=20"Parse=20and=20produce=20= code=20from=20FORM,=20which=20is=20`(submatch=20...)'."=0A-=20=20(let=20= ((subforms=20(rx--subforms=20(cdr=20form)=20':)))=0A-=20=20=20=20(if=20= (stringp=20subforms)=0A-=20=20=20=20=20=20=20=20(concat=20"\\("=20= subforms=20"\\)")=0A-=20=20=20=20=20=20`("\\("=20,@subforms=20"\\)"))))=0A= -=0A-(defun=20rx-submatch-n=20(form)=0A-=20=20"Parse=20and=20produce=20= code=20from=20FORM,=20which=20is=20`(submatch-n=20N=20...)'."=0A-=20=20= (let=20((n=20(nth=201=20form))=0A-=20=20=20=20=20=20=20=20(subforms=20= (rx--subforms=20(cddr=20form)=20':)))=0A-=20=20=20=20(unless=20(and=20= (integerp=20n)=20(>=20n=200))=0A-=20=20=20=20=20=20(error=20"rx=20= `submatch-n'=20argument=20must=20be=20positive"))=0A-=20=20=20=20(if=20= (stringp=20subforms)=0A-=20=20=20=20=20=20=20=20(concat=20"\\(?"=20= (number-to-string=20n)=20":"=20subforms=20"\\)")=0A-=20=20=20=20=20=20= `("\\(?"=20,(number-to-string=20n)=20":"=20,@subforms=20"\\)"))))=0A-=0A= -(defun=20rx-backref=20(form)=0A-=20=20"Parse=20and=20produce=20code=20= from=20FORM,=20which=20is=20`(backref=20N)'."=0A-=20=20(rx-check=20form)=0A= -=20=20(format=20"\\%d"=20(nth=201=20form)))=0A-=0A-(defun=20= rx-check-backref=20(arg)=0A-=20=20"Check=20arg=20ARG=20for=20Rx=20= `backref'."=0A-=20=20(or=20(and=20(integerp=20arg)=20(>=3D=20arg=201)=20= (<=3D=20arg=209))=0A-=20=20=20=20=20=20(error=20"rx=20`backref'=20= requires=20numeric=201<=3Darg<=3D9:=20%s"=20arg)))=0A-=0A-(defun=20= rx-kleene=20(form)=0A-=20=20"Parse=20and=20produce=20code=20from=20FORM.=0A= -FORM=20is=20`(OP=20FORM1)',=20where=20OP=20is=20one=20of=20the=20= `zero-or-one',=0A-`zero-or-more'=20etc.=20=20operators.=0A-If=20OP=20is=20= one=20of=20`*',=20`+',=20`?',=20produce=20a=20greedy=20regexp.=0A-If=20= OP=20is=20one=20of=20`*?',=20`+?',=20`??',=20produce=20a=20non-greedy=20= regexp.=0A-If=20OP=20is=20anything=20else,=20produce=20a=20greedy=20= regexp=20if=20`rx-greedy-flag'=0A-is=20non-nil."=0A-=20=20(rx-check=20= form)=0A-=20=20(setq=20form=20(rx-trans-forms=20form))=0A-=20=20(let=20= ((suffix=20(cond=20((memq=20(car=20form)=20'(*=20+=20\?=20?\s))=20"")=0A= -=09=09=20=20=20=20=20=20((memq=20(car=20form)=20'(*?=20+?=20\??=20??))=20= "?")=0A-=09=09=20=20=20=20=20=20(rx-greedy-flag=20"")=0A-=09=09=20=20=20=20= =20=20(t=20"?")))=0A-=09(op=20(cond=20((memq=20(car=20form)=20'(*=20*?=20= 0+=20zero-or-more))=20"*")=0A-=09=09=20=20((memq=20(car=20form)=20'(+=20= +?=201+=20one-or-more))=20=20"+")=0A-=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(t=20"?")))=0A-=20=20=20=20=20=20=20=20(subform=20= (rx-form=20(cadr=20form)=20'*)))=0A-=20=20=20=20(rx-group-if=0A-=20=20=20= =20=20(if=20(stringp=20subform)=0A-=20=20=20=20=20=20=20=20=20(concat=20= subform=20op=20suffix)=0A-=20=20=20=20=20=20=20`(,@subform=20,(concat=20= op=20suffix)))=0A-=20=20=20=20=20(and=20(memq=20rx-parent=20'(t=20*))=20= rx-parent))))=0A-=0A-=0A-(defun=20rx-atomic-p=20(r=20&optional=20lax)=0A= -=20=20"Return=20non-nil=20if=20regexp=20string=20R=20is=20atomic.=0A-An=20= atomic=20regexp=20R=20is=20one=20such=20that=20a=20suffix=20operator=0A= -appended=20to=20R=20will=20apply=20to=20all=20of=20R.=20=20For=20= example,=20\"a\"=0A-\"[abc]\"=20and=20\"\\(ab\\|ab*c\\)\"=20are=20atomic=20= and=20\"ab\",=0A-\"[ab]c\",=20and=20\"ab\\|ab*c\"=20are=20not=20atomic.=0A= -=0A-This=20function=20may=20return=20false=20negatives,=20but=20it=20= will=20not=0A-return=20false=20positives.=20=20It=20is=20nevertheless=20= useful=20in=0A-situations=20where=20an=20efficiency=20shortcut=20can=20= be=20taken=20only=20if=20a=0A-regexp=20is=20atomic.=20=20The=20function=20= can=20be=20improved=20to=20detect=0A-more=20cases=20of=20atomic=20= regexps.=20=20Presently,=20this=20function=0A-detects=20the=20following=20= categories=20of=20atomic=20regexp;=0A-=0A-=20=20a=20group=20or=20shy=20= group:=20=20\\(...\\)=0A-=20=20a=20character=20class:=20=20=20=20=20= [...]=0A-=20=20a=20single=20character:=20=20=20=20a=0A-=0A-On=20the=20= other=20hand,=20false=20negatives=20will=20be=20returned=20for=0A= -regexps=20that=20are=20atomic=20but=20end=20in=20operators,=20such=20as=0A= -\"a+\".=20=20I=20think=20these=20are=20rare.=20=20Probably=20such=20= cases=20could=0A-be=20detected=20without=20much=20effort.=20=20A=20= guarantee=20of=20no=20false=0A-negatives=20would=20require=20a=20= theoretic=20specification=20of=20the=20set=0A-of=20all=20atomic=20= regexps."=0A-=20=20(if=20(and=20rx--compile-to-lisp=0A-=20=20=20=20=20=20= =20=20=20=20=20(not=20(stringp=20r)))=0A-=20=20=20=20=20=20nil=20;;=20= Runtime=20value,=20we=20must=20assume=20non-atomic.=0A-=20=20=20=20(let=20= ((l=20(length=20r)))=0A+=20=20=20=20intervals))=0A+=0A+(defun=20= rx--condense-intervals=20(intervals)=0A+=20=20"Merge=20adjacent=20and=20= overlapping=20intervals=20by=20mutation,=20preserving=20the=20order.=0A= +INTERVALS=20is=20a=20list=20of=20(START=20.=20END)=20with=20START=20=E2=89= =A4=20END,=20sorted=20by=20START."=0A+=20=20(let=20((tail=20intervals)=0A= +=20=20=20=20=20=20=20=20d)=0A+=20=20=20=20(while=20(setq=20d=20(cdr=20= tail))=0A+=20=20=20=20=20=20(if=20(>=3D=20(cdar=20tail)=20(1-=20(caar=20= d)))=0A+=20=20=20=20=20=20=20=20=20=20(progn=0A+=20=20=20=20=20=20=20=20=20= =20=20=20(setcdr=20(car=20tail)=20(max=20(cdar=20tail)=20(cdar=20d)))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20(setcdr=20tail=20(cdr=20d)))=0A+=20=20= =20=20=20=20=20=20(setq=20tail=20d)))=0A+=20=20=20=20intervals))=0A+=0A= +(defun=20rx--translate-any=20(negated=20body)=0A+=20=20"Translate=20an=20= (any=20...)=20construct.=20=20Return=20(REGEXP=20.=20PRECEDENCE).=0A+If=20= NEGATED,=20negate=20the=20sense."=0A+=20=20(let=20((classes=20nil)=0A+=20= =20=20=20=20=20=20=20(strings=20nil)=0A+=20=20=20=20=20=20=20=20(conses=20= nil))=0A+=20=20=20=20;;=20Collect=20strings,=20conses=20and=20= characters,=20and=20classes=20in=20separate=20bins.=0A+=20=20=20=20= (dolist=20(arg=20body)=0A+=20=20=20=20=20=20(cond=20((stringp=20arg)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20(push=20arg=20strings))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20((and=20(consp=20arg)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(characterp=20(car=20arg))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(characterp=20(cdr=20arg))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(<=3D=20(car=20arg)=20= (cdr=20arg)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Copy=20the=20= cons,=20in=20case=20we=20need=20to=20modify=20it.=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20(push=20(cons=20(car=20arg)=20(cdr=20arg))=20conses))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20((characterp=20arg)=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20(push=20(cons=20arg=20arg)=20conses))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20((and=20(symbolp=20arg)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=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=20=20=20=20=20=20=20=20=20= =20=20=20(and=20class=20(push=20class=20classes)))))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20(t=20(error=20"Invalid=20rx=20`any'=20argument:=20%s"=20= arg))))=0A+=20=20=20=20(let=20((items=0A+=20=20=20=20=20=20=20=20=20=20=20= ;;=20Translate=20strings=20and=20conses=20into=20nonoverlapping=20= intervals,=0A+=20=20=20=20=20=20=20=20=20=20=20;;=20and=20add=20classes=20= as=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=20strings))=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=20classes))))=0A+=0A+=20=20=20=20=20=20;;=20= Move=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=20= rbrac-l=20(delq=20rbrac-l=20items)))))=0A+=0A+=20=20=20=20=20=20;;=20= Split=20x-]=20and=20move=20the=20lone=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=20rbrac-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=20items=20(cons=20'(?\]=20.=20?\])=20items))))=0A+=0A+=20= =20=20=20=20=20;;=20Split=20,--=20(which=20would=20end=20up=20as=20,-=20= otherwise).=0A+=20=20=20=20=20=20(let=20((dash-r=20(rassq=20?-=20= items)))=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;;=20Remove=20-=20(lone=20or=20at=20start=20of=20= interval)=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=20dash-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=20dash-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^=20= and=20range=20^-x.=0A+=20=20=20=20=20=20(when=20(and=20(consp=20(car=20= items))=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=20= second=20place.=0A+=20=20=20=20=20=20=20=20(setq=20items=20(cons=20(cadr=20= items)=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+=0A=20=20=20= =20=20=20=20(cond=0A-=20=20=20=20=20=20=20((<=3D=20l=201))=0A-=20=20=20=20= =20=20=20((=3D=20l=202)=20(=3D=20(aref=20r=200)=20?\\))=0A-=20=20=20=20=20= =20=20((=3D=20l=203)=20(string-match=20= "\\`\\(?:\\\\[cCsS_]\\|\\[[^^]\\]\\)"=20r))=0A-=20=20=20=20=20=20=20= ((null=20lax)=0A-=20=20=20=20=20=20=20=20(cond=0A-=20=20=20=20=20=20=20=20= =20((string-match=20"\\`\\[\\^?]?\\(?:\\[:[a-z]+:]\\|[^]]\\)*]\\'"=20r))=0A= -=20=20=20=20=20=20=20=20=20((string-match=20= "\\`\\\\(\\(?:[^\\]\\|\\\\[^)]\\)*\\\\)\\'"=20r))))))))=0A-=0A-=0A= -(defun=20rx-syntax=20(form)=0A-=20=20"Parse=20and=20produce=20code=20= from=20FORM,=20which=20is=20`(syntax=20SYMBOL)'."=0A-=20=20(rx-check=20= form)=0A-=20=20(let*=20((sym=20(cadr=20form))=0A-=09=20(syntax=20(cdr=20= (assq=20sym=20rx-syntax))))=0A+=20=20=20=20=20=20=20;;=20Empty=20set:=20= if=20negated,=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+=0A+(defun=20rx--translate-not=20(negated=20= body)=0A+=20=20"Translate=20a=20(not=20...)=20construct.=20=20Return=20= (REGEXP=20.=20PRECEDENCE).=0A+If=20NEGATED,=20negate=20the=20sense=20= (thus=20making=20it=20positive)."=0A+=20=20(unless=20(and=20body=20(null=20= (cdr=20body)))=0A+=20=20=20=20(error=20"rx=20`not'=20form=20takes=20= exactly=20one=20argument"))=0A+=20=20(let=20((arg=20(car=20body)))=0A+=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((eq=20arg=20'word-boundary)=0A= +=20=20=20=20=20=20(rx--translate-symbol=0A+=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+=0A+(defun=20rx--atomic-regexp=20= (item)=0A+=20=20"ITEM=20is=20(REGEXP=20.=20PRECEDENCE);=20return=20a=20= regexp=20of=20precedence=20t."=0A+=20=20(if=20(eq=20(cdr=20item)=20t)=0A= +=20=20=20=20=20=20(car=20item)=0A+=20=20=20=20(rx--bracket=20(car=20= item))))=0A+=0A+(defun=20rx--translate-counted-repetition=20(min-count=20= max-count=20body)=0A+=20=20(let=20((operand=20(rx--translate-seq=20= body)))=0A+=20=20=20=20(if=20(car=20operand)=0A+=20=20=20=20=20=20=20=20= (cons=20(append=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--atomic-regexp=20operand)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(list=20(concat=20"\\{"=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(number-to-string=20min-count)=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(cond=20((null=20max-count)=20",")=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((<=20min-count=20max-count)=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=20= (concat=20","=20(number-to-string=20max-count))))=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= "\\}")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20t)=0A+=20=20=20=20=20= =20operand)))=0A+=0A+(defun=20rx--check-repeat-arg=20(name=20min-args=20= body)=0A+=20=20(unless=20(>=3D=20(length=20body)=20min-args)=0A+=20=20=20= =20(error=20"rx=20`%s'=20requires=20at=20least=20%d=20argument%s"=0A+=20=20= =20=20=20=20=20=20=20=20=20name=20min-args=20(if=20(=3D=20min-args=201)=20= ""=20"s")))=0A+=20=20;;=20There=20seems=20to=20be=20no=20reason=20to=20= disallow=20zero=20counts.=0A+=20=20(unless=20(natnump=20(car=20body))=0A= +=20=20=20=20(error=20"rx=20`%s'=20first=20argument=20must=20be=20= nonnegative"=20name)))=0A+=0A+(defun=20rx--translate-bounded-repetition=20= (name=20body)=0A+=20=20(let=20((min-count=20(car=20body))=0A+=20=20=20=20= =20=20=20=20(max-count=20(cadr=20body))=0A+=20=20=20=20=20=20=20=20= (items=20(cddr=20body)))=0A+=20=20=20=20(unless=20(and=20(natnump=20= min-count)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (natnump=20max-count)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(<=3D=20min-count=20max-count))=0A+=20=20=20=20=20=20(error=20"rx=20= `%s'=20range=20error"=20name))=0A+=20=20=20=20= (rx--translate-counted-repetition=20min-count=20max-count=20items)))=0A+=0A= +(defun=20rx--translate-repeat=20(body)=0A+=20=20(rx--check-repeat-arg=20= 'repeat=202=20body)=0A+=20=20(if=20(=3D=20(length=20body)=202)=0A+=20=20=20= =20=20=20(rx--translate-counted-repetition=20(car=20body)=20(car=20body)=20= (cdr=20body))=0A+=20=20=20=20(rx--translate-bounded-repetition=20'repeat=20= body)))=0A+=0A+(defun=20rx--translate-**=20(body)=0A+=20=20= (rx--check-repeat-arg=20'**=202=20body)=0A+=20=20= (rx--translate-bounded-repetition=20'**=20body))=0A+=0A+(defun=20= rx--translate->=3D=20(body)=0A+=20=20(rx--check-repeat-arg=20'>=3D=201=20= body)=0A+=20=20(rx--translate-counted-repetition=20(car=20body)=20nil=20= (cdr=20body)))=0A+=0A+(defun=20rx--translate-=3D=20(body)=0A+=20=20= (rx--check-repeat-arg=20'=3D=201=20body)=0A+=20=20= (rx--translate-counted-repetition=20(car=20body)=20(car=20body)=20(cdr=20= body)))=0A+=0A+(defvar=20rx--greedy=20t)=0A+=0A+(defun=20= rx--translate-rep=20(op-string=20greedy=20body)=0A+=20=20"Translate=20a=20= repetition;=20OP-STRING=20is=20one=20of=20\"*\",=20\"+\"=20or=20\"?\".=0A= +GREEDY=20is=20a=20boolean.=20=20Return=20(REGEXP=20.=20PRECEDENCE)."=0A= +=20=20(let=20((operand=20(rx--translate-seq=20body)))=0A+=20=20=20=20= (if=20(car=20operand)=0A+=20=20=20=20=20=20=20=20(cons=20(append=20= (rx--atomic-regexp=20operand)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(list=20(concat=20op-string=20(unless=20greedy=20= "?"))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20The=20result=20= has=20precedence=20seq=20to=20avoid=20(?=20(*=20"a"))=20->=20"a*?"=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20'seq)=0A+=20=20=20=20=20=20= operand)))=0A+=0A+(defun=20rx--control-greedy=20(greedy=20body)=0A+=20=20= "Translate=20the=20sequence=20BODY=20with=20greediness=20GREEDY.=0A= +Return=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20(let=20((rx--greedy=20= greedy))=0A+=20=20=20=20(rx--translate-seq=20body)))=0A+=0A+(defun=20= rx--translate-group=20(body)=0A+=20=20"Translate=20the=20`group'=20form.=20= =20Return=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20(cons=20(rx--enclose=20= "\\("=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (car=20(rx--translate-seq=20body))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20"\\)")=0A+=20=20=20=20=20=20=20=20t))=0A+=0A= +(defun=20rx--translate-group-n=20(body)=0A+=20=20"Translate=20the=20= `group-n'=20form.=20=20Return=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20= (unless=20(and=20(integerp=20(car=20body))=20(>=20(car=20body)=200))=0A+=20= =20=20=20(error=20"rx=20`group-n'=20requires=20a=20positive=20number=20= as=20first=20argument"))=0A+=20=20(cons=20(rx--enclose=20(concat=20= "\\(?"=20(number-to-string=20(car=20body))=20":")=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(car=20(rx--translate-seq=20= (cdr=20body)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"\\)")=0A+=20=20=20=20=20=20=20=20t))=0A+=0A+(defun=20= rx--translate-backref=20(body)=0A+=20=20"Translate=20the=20`backref'=20= form.=20=20Return=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20(unless=20(and=20= (=3D=20(length=20body)=201)=20(integerp=20(car=20body))=20(<=3D=201=20= (car=20body)=209))=0A+=20=20=20=20(error=20"rx=20`backref'=20requires=20= an=20argument=20in=20the=20range=201..9"))=0A+=20=20(cons=20(list=20"\\"=20= (number-to-string=20(car=20body)))=20t))=0A+=0A+(defconst=20= rx--syntax-codes=0A+=20=20'((whitespace=20=20=20=20=20=20=20=20=20.=20= ?-)=20=20=20=20=20=20=20=20=20=20=20;=20SPC=20also=20accepted=0A+=20=20=20= =20(punctuation=20=20=20=20=20=20=20=20.=20?.)=0A+=20=20=20=20(word=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20.=20?w)=20=20=20=20=20=20=20=20=20= =20=20;=20W=20also=20accepted=0A+=20=20=20=20(symbol=20=20=20=20=20=20=20= =20=20=20=20=20=20.=20?_)=0A+=20=20=20=20(open-parenthesis=20=20=20.=20= ?\()=0A+=20=20=20=20(close-parenthesis=20=20.=20?\))=0A+=20=20=20=20= (expression-prefix=20=20.=20?\')=0A+=20=20=20=20(string-quote=20=20=20=20= =20=20=20.=20?\")=0A+=20=20=20=20(paired-delimiter=20=20=20.=20?$)=0A+=20= =20=20=20(escape=20=20=20=20=20=20=20=20=20=20=20=20=20.=20?\\)=0A+=20=20= =20=20(character-quote=20=20=20=20.=20?/)=0A+=20=20=20=20(comment-start=20= =20=20=20=20=20.=20?<)=0A+=20=20=20=20(comment-end=20=20=20=20=20=20=20=20= .=20?>)=0A+=20=20=20=20(string-delimiter=20=20=20.=20?|)=0A+=20=20=20=20= (comment-delimiter=20=20.=20?!)))=0A+=0A+(defun=20rx--translate-syntax=20= (negated=20body)=0A+=20=20"Translate=20the=20`syntax'=20form.=20=20= Return=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20(unless=20(and=20body=20= (null=20(cdr=20body)))=0A+=20=20=20=20(error=20"rx=20`syntax'=20form=20= takes=20exactly=20one=20argument"))=0A+=20=20(let*=20((sym=20(car=20= body))=0A+=20=20=20=20=20=20=20=20=20(syntax=20(cdr=20(assq=20sym=20= rx--syntax-codes))))=0A=20=20=20=20=20(unless=20syntax=0A-=20=20=20=20=20= =20;;=20Try=20sregex=20compatibility.=0A=20=20=20=20=20=20=20(cond=0A-=20= =20=20=20=20=20=20((characterp=20sym)=20(setq=20syntax=20sym))=0A+=20=20=20= =20=20=20=20;;=20Syntax=20character=20directly=20(sregex=20= compatibility)=0A+=20=20=20=20=20=20=20((and=20(characterp=20sym)=20= (rassq=20sym=20rx--syntax-codes))=0A+=20=20=20=20=20=20=20=20(setq=20= syntax=20sym))=0A+=20=20=20=20=20=20=20;;=20Syntax=20character=20as=20= symbol=20(sregex=20compatibility)=0A=20=20=20=20=20=20=20=20((symbolp=20= sym)=0A=20=20=20=20=20=20=20=20=20(let=20((name=20(symbol-name=20sym)))=0A= -=20=20=20=20=20=20=20=20=20=20(if=20(=3D=201=20(length=20name))=0A-=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(setq=20syntax=20(aref=20name=20= 0))))))=0A+=20=20=20=20=20=20=20=20=20=20(when=20(=3D=20(length=20name)=20= 1)=0A+=20=20=20=20=20=20=20=20=20=20=20=20(let=20((char=20= (string-to-char=20name)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (when=20(rassq=20char=20rx--syntax-codes)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(setq=20syntax=20char)))))))=0A=20=20=20=20=20=20=20= (unless=20syntax=0A-=09(error=20"Unknown=20rx=20syntax=20`%s'"=20sym)))=0A= -=20=20=20=20(format=20"\\s%c"=20syntax)))=0A-=0A-=0A-(defun=20= rx-check-category=20(form)=0A-=20=20"Check=20the=20argument=20FORM=20of=20= a=20`(category=20FORM)'."=0A-=20=20(unless=20(or=20(integerp=20form)=0A-=09= =20=20=20=20=20=20(cdr=20(assq=20form=20rx-categories)))=0A-=20=20=20=20= (error=20"Unknown=20category=20`%s'"=20form))=0A-=20=20t)=0A-=0A-=0A= -(defun=20rx-category=20(form)=0A-=20=20"Parse=20and=20produce=20code=20= from=20FORM,=20which=20is=20`(category=20SYMBOL)'."=0A-=20=20(rx-check=20= form)=0A-=20=20(let=20((char=20(if=20(integerp=20(cadr=20form))=0A-=09=09= =20=20(cadr=20form)=0A-=09=09(cdr=20(assq=20(cadr=20form)=20= rx-categories)))))=0A-=20=20=20=20(format=20"\\c%c"=20char)))=0A-=0A-=0A= -(defun=20rx-eval=20(form)=0A-=20=20"Parse=20and=20produce=20code=20from=20= FORM,=20which=20is=20`(eval=20FORM)'."=0A-=20=20(rx-check=20form)=0A-=20=20= (rx-form=20(eval=20(cadr=20form))=20rx-parent))=0A-=0A-=0A-(defun=20= rx-greedy=20(form)=0A-=20=20"Parse=20and=20produce=20code=20from=20FORM.=0A= -If=20FORM=20is=20`(minimal-match=20FORM1)',=20non-greedy=20versions=20= of=20`*',=0A-`+',=20and=20`?'=20operators=20will=20be=20used=20in=20= FORM1.=20=20If=20FORM=20is=0A-`(maximal-match=20FORM1)',=20greedy=20= operators=20will=20be=20used."=0A-=20=20(rx-check=20form)=0A-=20=20(let=20= ((rx-greedy-flag=20(eq=20(car=20form)=20'maximal-match)))=0A-=20=20=20=20= (rx-form=20(cadr=20form)=20rx-parent)))=0A-=0A-=0A-(defun=20rx-regexp=20= (form)=0A-=20=20"Parse=20and=20produce=20code=20from=20FORM,=20which=20= is=20`(regexp=20STRING)'."=0A-=20=20(cond=20((stringp=20(cadr=20form))=0A= -=20=20=20=20=20=20=20=20=20(rx-group-if=20(cadr=20form)=20rx-parent))=0A= -=20=20=20=20=20=20=20=20(rx--compile-to-lisp=0A-=20=20=20=20=20=20=20=20= =20;;=20Always=20group=20non-string=20forms,=20since=20we=20can't=20be=20= sure=20they=0A-=20=20=20=20=20=20=20=20=20;;=20are=20atomic.=0A-=20=20=20= =20=20=20=20=20=20(rx-group-if=20(cdr=20form)=20t))=0A-=20=20=20=20=20=20= =20=20(t=20(rx-check=20form))))=0A-=0A-(defun=20rx-literal=20(form)=0A-=20= =20"Parse=20and=20produce=20code=20from=20FORM,=20which=20is=20`(literal=20= STRING-EXP)'."=0A-=20=20(cond=20((stringp=20(cadr=20form))=0A-=20=20=20=20= =20=20=20=20=20;;=20This=20is=20allowed,=20but=20makes=20little=20sense,=20= you=20could=20just=0A-=20=20=20=20=20=20=20=20=20;;=20use=20STRING=20= directly.=0A-=20=20=20=20=20=20=20=20=20(rx-group-if=20(regexp-quote=20= (cadr=20form))=20rx-parent))=0A-=20=20=20=20=20=20=20=20= (rx--compile-to-lisp=0A-=20=20=20=20=20=20=20=20=20(rx-group-if=20= `((regexp-quote=20,(cadr=20form)))=20rx-parent))=0A-=20=20=20=20=20=20=20= =20(t=20(rx-check=20form))))=0A-=0A-(defun=20rx-form=20(form=20&optional=20= parent)=0A-=20=20"Parse=20and=20produce=20code=20for=20regular=20= expression=20FORM.=0A-FORM=20is=20a=20regular=20expression=20in=20sexp=20= form.=0A-PARENT=20shows=20which=20type=20of=20expression=20calls=20and=20= controls=20putting=20of=0A-shy=20groups=20around=20the=20result=20and=20= some=20more=20in=20other=20functions."=0A-=20=20(let=20((rx-parent=20= parent))=0A-=20=20=20=20(cond=0A-=20=20=20=20=20((stringp=20form)=0A-=20=20= =20=20=20=20(rx-group-if=20(regexp-quote=20form)=0A-=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(if=20(and=20(eq=20parent=20'*)=20(<=20= 1=20(length=20form)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20parent)))=0A-=20=20=20=20=20((integerp=20form)=0A-=20= =20=20=20=20=20(regexp-quote=20(char-to-string=20form)))=0A-=20=20=20=20=20= ((symbolp=20form)=0A-=20=20=20=20=20=20(let=20((info=20(rx-info=20form=20= nil)))=0A-=20=20=20=20=20=20=20=20(cond=20((stringp=20info)=0A-=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20info)=0A-=20=20=20=20=20=20=20=20=20=20=20= =20=20=20((null=20info)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (error=20"Unknown=20rx=20form=20`%s'"=20form))=0A-=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= (funcall=20(nth=200=20info)=20form)))))=0A-=20=20=20=20=20((consp=20= form)=0A-=20=20=20=20=20=20(let=20((info=20(rx-info=20(car=20form)=20= 'head)))=0A-=20=20=20=20=20=20=20=20(unless=20(consp=20info)=0A-=20=20=20= =20=20=20=20=20=20=20(error=20"Unknown=20rx=20form=20`%s'"=20(car=20= form)))=0A-=20=20=20=20=20=20=20=20(funcall=20(nth=200=20info)=20form)))=0A= -=20=20=20=20=20(t=0A-=20=20=20=20=20=20(error=20"rx=20syntax=20error=20= at=20`%s'"=20form)))))=0A-=0A-(defun=20rx--subforms=20(subforms=20= &optional=20parent=20separator)=0A-=20=20"Produce=20code=20for=20regular=20= expressions=20SUBFORMS.=0A-SUBFORMS=20is=20a=20list=20of=20regular=20= expression=20sexps.=0A-PARENT=20controls=20grouping,=20as=20in=20= `rx-form'.=0A-Insert=20SEPARATOR=20between=20the=20code=20from=20each=20= of=20SUBFORMS."=0A-=20=20(if=20(null=20(cdr=20subforms))=0A-=20=20=20=20=20= =20;;=20Zero=20or=20one=20forms,=20no=20need=20for=20grouping.=0A-=20=20=20= =20=20=20(and=20subforms=20(rx-form=20(car=20subforms)))=0A-=20=20=20=20= (let=20((listify=20(lambda=20(x)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(if=20(listp=20x)=20(copy-sequence=20x)=0A-=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20= x)))))=0A-=20=20=20=20=20=20(setq=20subforms=20(mapcar=20(lambda=20(x)=20= (rx-form=20x=20parent))=20subforms))=0A-=20=20=20=20=20=20(cond=20((or=20= (not=20rx--compile-to-lisp)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(cl-every=20#'stringp=20subforms))=0A-=20=20=20=20=20=20=20=20=20= =20=20=20=20(mapconcat=20#'identity=20subforms=20separator))=0A-=20=20=20= =20=20=20=20=20=20=20=20=20(separator=0A-=20=20=20=20=20=20=20=20=20=20=20= =20=20(nconc=20(funcall=20listify=20(car=20subforms))=0A-=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(mapcan=20(lambda=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=20=20=20=20=20= =20=20=20(cons=20separator=20(funcall=20listify=20x)))=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= (cdr=20subforms))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20(t=20(mapcan=20= listify=20subforms))))))=0A+=20=20=20=20=20=20=20=20(error=20"Unknown=20= rx=20syntax=20name=20`%s'"=20sym)))=0A+=20=20=20=20(cons=20(list=20= (string=20?\\=20(if=20negated=20?S=20?s)=20syntax))=0A+=20=20=20=20=20=20= =20=20=20=20t)))=0A+=0A+(defconst=20rx--categories=0A+=20=20= '((space-for-indent=20=20=20=20=20=20=20=20=20=20=20.=20?\s)=0A+=20=20=20= =20(base=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20.=20?.)=0A+=20=20=20=20(consonant=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20.=20?0)=0A+=20=20=20=20(base-vowel=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20.=20?1)=0A+=20=20=20=20= (upper-diacritical-mark=20=20=20=20=20.=20?2)=0A+=20=20=20=20= (lower-diacritical-mark=20=20=20=20=20.=20?3)=0A+=20=20=20=20(tone-mark=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20?4)=0A+=20=20=20=20= (symbol=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20= ?5)=0A+=20=20=20=20(digit=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20.=20?6)=0A+=20=20=20=20= (vowel-modifying-diacritical-mark=20.=20?7)=0A+=20=20=20=20(vowel-sign=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20?8)=0A+=20=20=20=20= (semivowel-lower=20=20=20=20=20=20=20=20=20=20=20=20.=20?9)=0A+=20=20=20=20= (not-at-end-of-line=20=20=20=20=20=20=20=20=20.=20?<)=0A+=20=20=20=20= (not-at-beginning-of-line=20=20=20.=20?>)=0A+=20=20=20=20= (alpha-numeric-two-byte=20=20=20=20=20.=20?A)=0A+=20=20=20=20= (chinese-two-byte=20=20=20=20=20=20=20=20=20=20=20.=20?C)=0A+=20=20=20=20= (chinse-two-byte=20=20=20=20=20=20=20=20=20=20=20=20.=20?C)=20=20=20;=20= A=20typo=20in=20Emacs=2021.1-24.3.=0A+=20=20=20=20(greek-two-byte=20=20=20= =20=20=20=20=20=20=20=20=20=20.=20?G)=0A+=20=20=20=20= (japanese-hiragana-two-byte=20.=20?H)=0A+=20=20=20=20(indian-two-byte=20=20= =20=20=20=20=20=20=20=20=20=20.=20?I)=0A+=20=20=20=20= (japanese-katakana-two-byte=20.=20?K)=0A+=20=20=20=20= (strong-left-to-right=20=20=20=20=20=20=20.=20?L)=0A+=20=20=20=20= (korean-hangul-two-byte=20=20=20=20=20.=20?N)=0A+=20=20=20=20= (strong-right-to-left=20=20=20=20=20=20=20.=20?R)=0A+=20=20=20=20= (cyrillic-two-byte=20=20=20=20=20=20=20=20=20=20.=20?Y)=0A+=20=20=20=20= (combining-diacritic=20=20=20=20=20=20=20=20.=20?^)=0A+=20=20=20=20= (ascii=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= .=20?a)=0A+=20=20=20=20(arabic=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20.=20?b)=0A+=20=20=20=20(chinese=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20.=20?c)=0A+=20=20=20=20(ethiopic=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20?e)=0A+=20=20=20=20= (greek=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= .=20?g)=0A+=20=20=20=20(korean=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20.=20?h)=0A+=20=20=20=20(indian=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20.=20?i)=0A+=20=20=20=20(japanese=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20?j)=0A+=20=20=20=20= (japanese-katakana=20=20=20=20=20=20=20=20=20=20.=20?k)=0A+=20=20=20=20= (latin=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= .=20?l)=0A+=20=20=20=20(lao=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20.=20?o)=0A+=20=20=20=20(tibetan=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20?q)=0A+=20=20=20=20= (japanese-roman=20=20=20=20=20=20=20=20=20=20=20=20=20.=20?r)=0A+=20=20=20= =20(thai=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(vietnamese=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20.=20?v)=0A+=20=20=20=20(hebrew=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20.=20?w)=0A+=20=20=20=20(cyrillic=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20?y)=0A+=20=20=20=20= (can-break=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20.=20= ?|)))=0A+=0A+(defun=20rx--translate-category=20(negated=20body)=0A+=20=20= "Translate=20the=20`category'=20form.=20=20Return=20(REGEXP=20.=20= PRECEDENCE)."=0A+=20=20(unless=20(and=20body=20(null=20(cdr=20body)))=0A= +=20=20=20=20(error=20"rx=20`category'=20form=20takes=20exactly=20one=20= argument"))=0A+=20=20(let*=20((arg=20(car=20body))=0A+=20=20=20=20=20=20=20= =20=20(category=0A+=20=20=20=20=20=20=20=20=20=20(cond=20((symbolp=20= arg)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((cat=20= (assq=20arg=20rx--categories)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(unless=20cat=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(error=20"Unknown=20rx=20category=20`%s'"=20= arg))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cdr=20= cat)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((characterp=20= arg)=20arg)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(t=20= (error=20"Invalid=20rx=20`category'=20argument=20`%s'"=20arg)))))=0A+=20=20= =20=20(cons=20(list=20(string=20?\\=20(if=20negated=20?C=20?c)=20= category))=0A+=20=20=20=20=20=20=20=20=20=20t)))=0A+=0A+(defvar=20= rx--delayed-evaluation=20nil=0A+=20=20"Whether=20to=20allow=20certain=20= forms=20to=20be=20evaluated=20at=20runtime.")=0A+=0A+(defun=20= rx--translate-literal=20(body)=0A+=20=20"Translate=20the=20`literal'=20= form.=20=20Return=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20(unless=20(and=20= body=20(null=20(cdr=20body)))=0A+=20=20=20=20(error=20"rx=20`literal'=20= form=20takes=20exactly=20one=20argument"))=0A+=20=20(let=20((arg=20(car=20= body)))=0A+=20=20=20=20(cond=20((stringp=20arg)=0A+=20=20=20=20=20=20=20=20= =20=20=20(cons=20(list=20(regexp-quote=20arg))=20(if=20(=3D=20(length=20= arg)=201)=20t=20'seq)))=0A+=20=20=20=20=20=20=20=20=20=20= (rx--delayed-evaluation=0A+=20=20=20=20=20=20=20=20=20=20=20(cons=20= (list=20(list=20'regexp-quote=20arg))=20'seq))=0A+=20=20=20=20=20=20=20=20= =20=20(t=20(error=20"rx=20`literal'=20form=20with=20non-string=20= argument")))))=0A+=0A+(defun=20rx--translate-eval=20(body)=0A+=20=20= "Translate=20the=20`eval'=20form.=20=20Return=20(REGEXP=20.=20= PRECEDENCE)."=0A+=20=20(unless=20(and=20body=20(null=20(cdr=20body)))=0A= +=20=20=20=20(error=20"rx=20`eval'=20form=20takes=20exactly=20one=20= argument"))=0A+=20=20(rx--translate=20(eval=20(car=20body))))=0A+=0A= +(defvar=20rx--regexp-atomic-regexp=20nil)=0A+=0A+(defun=20= rx--translate-regexp=20(body)=0A+=20=20"Translate=20the=20`regexp'=20= form.=20=20Return=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20(unless=20(and=20= body=20(null=20(cdr=20body)))=0A+=20=20=20=20(error=20"rx=20`regexp'=20= form=20takes=20exactly=20one=20argument"))=0A+=20=20(let=20((arg=20(car=20= body)))=0A+=20=20=20=20(cond=20((stringp=20arg)=0A+=20=20=20=20=20=20=20=20= =20=20=20;;=20Generate=20the=20regexp=20when=20needed,=20since=20rx=20= isn't=0A+=20=20=20=20=20=20=20=20=20=20=20;;=20necessarily=20present=20= in=20the=20byte-compilation=20environment.=0A+=20=20=20=20=20=20=20=20=20= =20=20(unless=20rx--regexp-atomic-regexp=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20(setq=20rx--regexp-atomic-regexp=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20;;=20Match=20atomic=20(precedence=20t)=20= regexps:=20may=20give=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20;;=20false=20negatives=20but=20no=20false=20positives,=20= assuming=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20= the=20target=20string=20is=20syntactically=20correct.=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(rx-to-string=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20'(seq=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20bos=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(or=20(seq=20"["=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(opt=20"^")=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(opt=20"]")=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(or=20(seq=20"[:"=20(+=20(any=20"a-z"))=20":]")=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=20=20=20(not=20(any=20"]"))))=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"]")=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=20anything=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(seq=20"\\"=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(or=20anything=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(seq=20(any=20"sScC_")=20anything)=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(seq=20"("=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=20=20=20= =20=20(*=20(or=20(not=20(any=20"\\"))=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=20= =20=20=20=20=20=20=20=20=20=20=20(seq=20"\\"=20(not=20(any=20")")))))=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=20=20=20=20=20"\\)"))))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20eos)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20t)))=0A+=20=20=20=20=20=20= =20=20=20=20=20(cons=20(list=20arg)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(if=20(string-match-p=20rx--regexp-atomic-regexp=20arg)=20= t=20nil)))=0A+=20=20=20=20=20=20=20=20=20=20(rx--delayed-evaluation=0A+=20= =20=20=20=20=20=20=20=20=20=20(cons=20(list=20arg)=20nil))=0A+=20=20=20=20= =20=20=20=20=20=20(t=20(error=20"rx=20`regexp'=20form=20with=20= non-string=20argument")))))=0A+=0A+(defun=20rx--translate-compat-form=20= (def=20form)=0A+=20=20"Translate=20a=20compatibility=20form=20from=20= `rx-constituents'.=0A+DEF=20is=20the=20definition=20tuple.=20=20Return=20= (REGEXP=20.=20PRECEDENCE)."=0A+=20=20(let*=20((fn=20(nth=200=20def))=0A+=20= =20=20=20=20=20=20=20=20(min-args=20(nth=201=20def))=0A+=20=20=20=20=20=20= =20=20=20(max-args=20(nth=202=20def))=0A+=20=20=20=20=20=20=20=20=20= (predicate=20(nth=203=20def))=0A+=20=20=20=20=20=20=20=20=20(nargs=20(1-=20= (length=20form))))=0A+=20=20=20=20(when=20(<=20nargs=20min-args)=0A+=20=20= =20=20=20=20(error=20"The=20`%s'=20form=20takes=20at=20least=20%d=20= argument(s)"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(car=20form)=20= min-args))=0A+=20=20=20=20(when=20(and=20max-args=20(>=20nargs=20= max-args))=0A+=20=20=20=20=20=20(error=20"The=20`%s'=20form=20takes=20at=20= most=20%d=20argument(s)"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(car=20= form)=20max-args))=0A+=20=20=20=20(when=20(and=20predicate=20(not=20= (rx--every=20predicate=20(cdr=20form))))=0A+=20=20=20=20=20=20(error=20= "The=20`%s'=20form=20requires=20arguments=20satisfying=20`%s'"=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20(car=20form)=20predicate))=0A+=20=20=20=20= (let=20((regexp=20(funcall=20fn=20form)))=0A+=20=20=20=20=20=20(unless=20= (stringp=20regexp)=0A+=20=20=20=20=20=20=20=20(error=20"The=20`%s'=20= form=20did=20not=20expand=20to=20a=20string"=20(car=20form)))=0A+=20=20=20= =20=20=20(cons=20(list=20regexp)=20nil))))=0A+=0A+(defun=20= rx--translate-form=20(form)=0A+=20=20"Translate=20an=20rx=20form=20(list=20= structure).=20=20Return=20(REGEXP=20.=20PRECEDENCE)."=0A+=20=20(let=20= ((body=20(cdr=20form)))=0A+=20=20=20=20(pcase=20(car=20form)=0A+=20=20=20= =20=20=20((or=20'seq=20:=20'and=20'sequence)=20(rx--translate-seq=20= body))=0A+=20=20=20=20=20=20((or=20'or=20'|)=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(rx--translate-or=20body))=0A+=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('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('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+=0A+=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= ('=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=20body))=0A+=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(rx--translate->=3D=20= body))=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(rx--translate-**=20body))=0A+=0A+=20=20=20=20=20= =20((or=20'zero-or-more=20'0+)=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-rep=20"*"=20rx--greedy=20body))=0A+=20=20=20=20=20=20((or=20= 'one-or-more=20'1+)=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-rep=20"+"=20rx--greedy=20body))=0A+=20=20=20=20=20=20((or=20= 'zero-or-one=20'opt=20'optional)=20(rx--translate-rep=20"?"=20rx--greedy=20= body))=0A+=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(rx--translate-rep=20"*"=20t=20body))=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(rx--translate-rep=20"+"=20t=20body))=0A+=20=20=20=20=20=20= ((or=20'\?=20?\s)=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-rep=20"?"=20t=20body))=0A+=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= (rx--translate-rep=20"*"=20nil=20body))=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= (rx--translate-rep=20"+"=20nil=20body))=0A+=20=20=20=20=20=20((or=20'\??=20= ??)=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-rep=20"?"=20nil=20= body))=0A+=0A+=20=20=20=20=20=20('minimal-match=20=20=20=20=20=20=20=20=20= =20=20(rx--control-greedy=20nil=20body))=0A+=20=20=20=20=20=20= ('maximal-match=20=20=20=20=20=20=20=20=20=20=20(rx--control-greedy=20t=20= =20=20body))=0A+=0A+=20=20=20=20=20=20((or=20'group=20'submatch)=20=20=20= =20=20(rx--translate-group=20body))=0A+=20=20=20=20=20=20((or=20'group-n=20= 'submatch-n)=20(rx--translate-group-n=20body))=0A+=20=20=20=20=20=20= ('backref=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-backref=20body))=0A+=0A+=20=20=20=20=20=20('syntax=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-syntax=20nil=20= body))=0A+=20=20=20=20=20=20('not-syntax=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(rx--translate-syntax=20t=20body))=0A+=20=20=20=20=20=20= ('category=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-category=20nil=20body))=0A+=0A+=20=20=20=20=20=20= ('literal=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-literal=20body))=0A+=20=20=20=20=20=20('eval=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-eval=20= body))=0A+=20=20=20=20=20=20((or=20'regexp=20'regex)=20=20=20=20=20=20= (rx--translate-regexp=20body))=0A+=0A+=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+=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=20op=20rx-constituents)))=0A+=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(while=20(and=20= entry=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(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(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= ;;=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(assq=20(cdr=20entry)=20= rx-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;;=20Wrong=20type,=20try=20further=20down=20the=20= list.=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(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(cdr=20(memq=20= entry=20rx-constituents))))))=0A+=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= (rx--translate-compat-form=20(cdr=20entry)=20form)=0A+=20=20=20=20=20=20=20= =20=20=20=20(error=20"Unknown=20rx=20form=20`%s'"=20op)))))))=0A+=0A+;;=20= Defined=20here=20rather=20than=20in=20re-builder=20to=20lower=20the=20= odds=20that=20it=0A+;;=20will=20be=20kept=20in=20sync=20with=20changes.=0A= +(defconst=20rx--builtin-forms=0A+=20=20'(seq=20sequence=20:=20and=20or=20= |=20any=20in=20char=20not-char=20not=0A+=20=20=20=20repeat=20=3D=20>=3D=20= **=0A+=20=20=20=20zero-or-more=200+=20*=0A+=20=20=20=20one-or-more=201+=20= +=0A+=20=20=20=20zero-or-one=20opt=20optional=20\?=0A+=20=20=20=20*?=20= +?=20\??=0A+=20=20=20=20minimal-match=20maximal-match=0A+=20=20=20=20= group=20submatch=20group-n=20submatch-n=20backref=0A+=20=20=20=20syntax=20= not-syntax=20category=0A+=20=20=20=20literal=20eval=20regexp=20regex)=0A= +=20=20"List=20of=20built-in=20rx=20forms.=20=20For=20use=20in=20= re-builder=20only.")=0A+=0A+(defun=20rx--translate=20(item)=0A+=20=20= "Translate=20the=20rx-expression=20ITEM.=20=20Return=20(REGEXP=20.=20= PRECEDENCE)."=0A+=20=20(cond=0A+=20=20=20((stringp=20item)=0A+=20=20=20=20= (if=20(=3D=20(length=20item)=200)=0A+=20=20=20=20=20=20=20=20(cons=20nil=20= 'seq)=0A+=20=20=20=20=20=20(cons=20(list=20(regexp-quote=20item))=20(if=20= (=3D=20(length=20item)=201)=20t=20'seq))))=0A+=20=20=20((characterp=20= item)=0A+=20=20=20=20(cons=20(list=20(regexp-quote=20(char-to-string=20= item)))=20t))=0A+=20=20=20((symbolp=20item)=0A+=20=20=20=20= (rx--translate-symbol=20item))=0A+=20=20=20((consp=20item)=0A+=20=20=20=20= (rx--translate-form=20item))=0A+=20=20=20(t=20(error=20"Bad=20rx=20= expression:=20%S"=20item))))=0A=20=0A=20=0A=20;;;###autoload=0A=20(defun=20= rx-to-string=20(form=20&optional=20no-group)=0A-=20=20"Parse=20and=20= produce=20code=20for=20regular=20expression=20FORM.=0A-FORM=20is=20a=20= regular=20expression=20in=20sexp=20form.=0A-NO-GROUP=20non-nil=20means=20= don't=20put=20shy=20groups=20around=20the=20result.=0A-=0A-In=20contrast=20= to=20the=20`rx'=20macro,=20subforms=20`literal'=20and=20`regexp'=0A-will=20= not=20accept=20non-string=20arguments,=20i.e.,=20(literal=20STRING)=0A= -becomes=20just=20a=20more=20verbose=20version=20of=20STRING."=0A-=20=20= (rx-group-if=20(rx-form=20form)=20(null=20no-group)))=0A+=20=20= "Translate=20FORM=20from=20`rx'=20sexp=20syntax=20into=20a=20string=20= regexp.=0A+The=20arguments=20to=20`literal'=20and=20`regexp'=20forms=20= inside=20FORM=20must=20be=0A+constant=20strings.=0A+If=20NO-GROUP=20is=20= non-nil,=20don't=20bracket=20the=20result=20in=20a=20non-capturing=0A= +group."=0A+=20=20(let*=20((item=20(rx--translate=20form))=0A+=20=20=20=20= =20=20=20=20=20(exprs=20(if=20no-group=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(car=20item)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(rx--atomic-regexp=20item))))=0A+=20=20=20=20= (apply=20#'concat=20exprs)))=0A+=0A+(defun=20rx--to-expr=20(form)=0A+=20=20= "Translate=20the=20rx-expression=20FORM=20to=20a=20Lisp=20expression=20= yielding=20a=20regexp."=0A+=20=20(let*=20((rx--delayed-evaluation=20t)=0A= +=20=20=20=20=20=20=20=20=20(elems=20(car=20(rx--translate=20form)))=0A+=20= =20=20=20=20=20=20=20=20(args=20nil))=0A+=20=20=20=20;;=20Merge=20= adjacent=20strings.=0A+=20=20=20=20(while=20elems=0A+=20=20=20=20=20=20= (let=20((strings=20nil))=0A+=20=20=20=20=20=20=20=20(while=20(and=20= elems=20(stringp=20(car=20elems)))=0A+=20=20=20=20=20=20=20=20=20=20= (push=20(car=20elems)=20strings)=0A+=20=20=20=20=20=20=20=20=20=20(setq=20= elems=20(cdr=20elems)))=0A+=20=20=20=20=20=20=20=20(let=20((s=20(apply=20= #'concat=20(nreverse=20strings))))=0A+=20=20=20=20=20=20=20=20=20=20= (unless=20(zerop=20(length=20s))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= (push=20s=20args))))=0A+=20=20=20=20=20=20(when=20elems=0A+=20=20=20=20=20= =20=20=20(push=20(car=20elems)=20args)=0A+=20=20=20=20=20=20=20=20(setq=20= elems=20(cdr=20elems))))=0A+=20=20=20=20(cond=20((null=20args)=20"")=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20;=200=20args=0A+=20=20=20=20=20=20=20=20=20=20((cdr=20args)=20= (cons=20'concat=20(nreverse=20args)))=20=20;=20=E2=89=A52=20args=0A+=20=20= =20=20=20=20=20=20=20=20(t=20(car=20args)))))=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=201=20arg=0A=20=0A= =20=0A=20;;;###autoload=0A@@=20-1054,78=20+937,64=20@@=20rx=0A=20=0A=20= (literal=20EXPR)=20Match=20the=20literal=20string=20from=20evaluating=20= EXPR=20at=20run=20time.=0A=20(regexp=20EXPR)=20=20Match=20the=20string=20= regexp=20from=20evaluating=20EXPR=20at=20run=20time.=0A-(eval=20EXPR)=20=20= =20=20Match=20the=20rx=20sexp=20from=20evaluating=20EXPR=20at=20compile=20= time."=0A-=20=20(let*=20((rx--compile-to-lisp=20t)=0A-=20=20=20=20=20=20=20= =20=20(re=20(cond=20((null=20regexps)=0A-=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(error=20"No=20regexp"))=0A-=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20((cdr=20regexps)=0A-=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx-to-string=20`(and=20= ,@regexps)=20t))=0A-=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= (rx-to-string=20(car=20regexps)=20t)))))=0A-=20=20=20=20(if=20(stringp=20= re)=0A-=20=20=20=20=20=20=20=20re=0A-=20=20=20=20=20=20`(concat=20= ,@re))))=0A-=0A+(eval=20EXPR)=20=20=20=20Match=20the=20rx=20sexp=20from=20= evaluating=20EXPR=20at=20compile=20time.=0A+=0A+\(fn=20REGEXPS...)"=0A+=20= =20(rx--to-expr=20(cons=20'seq=20regexps)))=0A+=0A+=0A+;;=20During=20= `rx--pcase-transform',=20list=20of=20defined=20variables=20in=20= right-to-left=0A+;;=20order.=0A+(defvar=20rx--pcase-vars)=0A+=0A+(defun=20= rx--pcase-transform=20(rx)=0A+=20=20"Transform=20RX,=20an=20= rx-expression=20augmented=20with=20`let'=20and=20named=20`backref',=0A= +into=20a=20plain=20rx-expression,=20collecting=20names=20into=20= `rx--pcase-vars'."=0A+=20=20(pcase=20rx=0A+=20=20=20=20(`(let=20,name=20= .=20,body)=0A+=20=20=20=20=20(let*=20((index=20(length=20(memq=20name=20= rx--pcase-vars)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20(i=20(if=20= (zerop=20index)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(length=20(push=20name=20rx--pcase-vars))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20index)))=0A+=20=20=20=20=20=20=20`(group-n=20,i=20= ,(rx--pcase-transform=20(cons=20'seq=20body)))))=0A+=20=20=20=20((and=20= `(backref=20,ref)=0A+=20=20=20=20=20=20=20=20=20=20(guard=20(symbolp=20= ref)))=0A+=20=20=20=20=20(let=20((index=20(length=20(memq=20ref=20= rx--pcase-vars))))=0A+=20=20=20=20=20=20=20(when=20(zerop=20index)=0A+=20= =20=20=20=20=20=20=20=20(error=20"rx=20`backref'=20variable=20must=20be=20= one=20of:=20%s"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (mapconcat=20#'symbol-name=20rx--pcase-vars=20"=20")))=0A+=20=20=20=20=20= =20=20`(backref=20,index)))=0A+=20=20=20=20((and=20`(,head=20.=20,rest)=0A= +=20=20=20=20=20=20=20=20=20=20(guard=20(and=20(symbolp=20head)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(not=20(memq=20= head=20'(literal=20regexp=20regex=20eval))))))=0A+=20=20=20=20=20(cons=20= head=20(mapcar=20#'rx--pcase-transform=20rest)))=0A+=20=20=20=20(_=20= rx)))=0A=20=0A=20(pcase-defmacro=20rx=20(&rest=20regexps)=0A-=20=20= "Build=20a=20`pcase'=20pattern=20matching=20`rx'=20REGEXPS=20in=20sexp=20= form.=0A-The=20REGEXPS=20are=20interpreted=20as=20in=20`rx'.=20=20The=20= pattern=20matches=20any=0A-string=20that=20is=20a=20match=20for=20the=20= regular=20expression=20so=20constructed,=0A-as=20if=20by=20= `string-match'.=0A+=20=20"A=20pattern=20that=20matches=20strings=20= against=20`rx'=20REGEXPS=20in=20sexp=20form.=0A+REGEXPS=20are=20= interpreted=20as=20in=20`rx'.=20=20The=20pattern=20matches=20any=0A= +string=20that=20is=20a=20match=20for=20REGEXPS,=20as=20if=20by=20= `string-match'.=0A=20=0A-In=20addition=20to=20the=20usual=20`rx'=20= constructs,=20REGEXPS=20can=20contain=20the=0A+In=20addition=20to=20the=20= usual=20`rx'=20syntax,=20REGEXPS=20can=20contain=20the=0A=20following=20= constructs:=0A=20=0A-=20=20(let=20REF=20SEXP...)=20=20creates=20a=20new=20= explicitly=20named=20reference=20to=0A-=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20a=20submatch=20that=20matches=20regular=20= expressions=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20SEXP,=20and=20binds=20the=20match=20to=20REF.=0A-=20=20(backref=20= REF)=20=20=20=20=20=20creates=20a=20backreference=20to=20the=20submatch=0A= -=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= introduced=20by=20a=20previous=20(let=20REF=20...)=0A-=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20construct.=20=20REF=20can=20be=20= the=20same=20symbol=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20in=20the=20first=20argument=20of=20the=20corresponding=0A-=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20REF=20= ...)=20construct,=20or=20it=20can=20be=20a=0A-=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20submatch=20number.=20=20It=20matches=20= the=20referenced=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20submatch.=0A-=0A-The=20REFs=20are=20associated=20with=20= explicitly=20named=20submatches=20starting=0A-from=201.=20=20Multiple=20= occurrences=20of=20the=20same=20REF=20refer=20to=20the=20same=0A= -submatch.=0A-=0A-If=20a=20case=20matches,=20the=20match=20data=20is=20= modified=20as=20usual=20so=20you=20can=0A-use=20it=20in=20the=20case=20= body,=20but=20you=20still=20have=20to=20pass=20the=20correct=0A-string=20= as=20argument=20to=20`match-string'."=0A-=20=20(let*=20((vars=20())=0A-=20= =20=20=20=20=20=20=20=20(rx-constituents=0A-=20=20=20=20=20=20=20=20=20=20= `((let=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20,(lambda=20(form)=0A-=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx-check=20form)=0A-=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((var=20(cadr=20form)))=0A= -=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cl-check-type=20= var=20symbol)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (let=20((i=20(or=20(cl-position=20var=20vars=20:test=20#'eq)=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(prog1=20(length=20vars)=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(setq=20= vars=20`(,@vars=20,var))))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(rx-form=20`(submatch-n=20,(1+=20i)=20,@(cddr=20= form))))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=201=20nil)=0A-=20=20=20= =20=20=20=20=20=20=20=20=20(backref=0A-=20=20=20=20=20=20=20=20=20=20=20=20= =20,(lambda=20(form)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx-check=20form)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx-backref=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= `(backref=20,(let=20((var=20(cadr=20form)))=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(if=20= (integerp=20var)=20var=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(1+=20(cl-position=20var=20= vars=20:test=20#'eq)))))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=201=20= 1=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20,(lambda=20(var)=0A-=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(cond=20((integerp=20var)=20= (rx-check-backref=20var))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20((memq=20var=20vars)=20t)=0A-=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(t=20(error=20"rx=20`backref'=20= variable=20must=20be=20one=20of=20%s:=20%s"=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= vars=20var)))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20= ,@rx-constituents))=0A-=20=20=20=20=20=20=20=20=20(regexp=20= (rx-to-string=20`(seq=20,@regexps)=20:no-group)))=0A+=20=20(let=20REF=20= RX...)=20=20binds=20the=20symbol=20REF=20to=20a=20submatch=20that=20= matches=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20the=20= regular=20expressions=20RX.=20=20REF=20is=20bound=20in=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20CODE=20to=20the=20string=20of=20= the=20submatch=20or=20nil,=20but=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20can=20also=20be=20used=20in=20`backref'.=0A+=20=20= (backref=20REF)=20=20=20=20matches=20whatever=20the=20submatch=20REF=20= matched.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20REF=20= can=20be=20a=20number,=20as=20usual,=20or=20a=20name=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20introduced=20by=20a=20previous=20= (let=20REF=20...)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20construct."=0A+=20=20(let*=20((rx--pcase-vars=20nil)=0A+=20=20=20=20=20= =20=20=20=20(regexp=20(rx--to-expr=20(rx--pcase-transform=20(cons=20'seq=20= regexps)))))=0A=20=20=20=20=20`(and=20(pred=20(string-match=20,regexp))=0A= -=20=20=20=20=20=20=20=20=20=20,@(cl-loop=20for=20i=20from=201=0A-=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20for=20var=20in=20= vars=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= collect=20`(app=20(match-string=20,i)=20,var)))))=0A-=0C=0A+=20=20=20=20=20= =20=20=20=20=20,@(let=20((i=200))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(mapcar=20(lambda=20(name)=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(setq=20i=20(1+=20i))=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`(app=20= (match-string=20,i)=20,name))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(reverse=20rx--pcase-vars))))))=0A+=0A=20= (provide=20'rx)=0A=20=0A=20;;;=20rx.el=20ends=20here=0Adiff=20--git=20= a/test/lisp/emacs-lisp/rx-tests.el=20b/test/lisp/emacs-lisp/rx-tests.el=0A= index=208845ebf46d..fec046dd99=20100644=0A---=20= a/test/lisp/emacs-lisp/rx-tests.el=0A+++=20= b/test/lisp/emacs-lisp/rx-tests.el=0A@@=20-1,4=20+1,4=20@@=0A-;;;=20= rx-tests.el=20---=20test=20for=20rx.el=20functions=20-*-=20= lexical-binding:=20t=20-*-=0A+;;;=20rx-tests.el=20---=20tests=20for=20= rx.el=20=20=20=20=20=20=20=20=20=20=20=20=20=20-*-=20lexical-binding:=20= t=20-*-=0A=20=0A=20;;=20Copyright=20(C)=202016-2019=20Free=20Software=20= Foundation,=20Inc.=0A=20=0A@@=20-17,21=20+17,44=20@@=0A=20;;=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=0A=20;;=20along=20with=20GNU=20Emacs.=20=20If=20not,=20see=20= .=0A=20=0A-;;;=20Commentary:=0A-=0A=20= (require=20'ert)=0A=20(require=20'rx)=0A=20=0A-;;;=20Code:=0A= +(ert-deftest=20rx-seq=20()=0A+=20=20(should=20(equal=20(rx=20"a.b"=20= "*"=20"c")=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "a\\.b\\*c"))=0A+=20=20(should=20(equal=20(rx=20(seq=20"a"=20(:=20"b"=20= (and=20"c"=20(sequence=20"d"=20nonl)=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=20= =20=20=20=20=20=20"e")=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"f")=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"g"))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"abcd.efg"))=0A+=20=20= (should=20(equal=20(rx=20"a$"=20"b")=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20"a\\$b"))=0A+=20=20(should=20(equal=20(rx=20bol=20"a"=20= "b"=20?c=20eol)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "^abc$"))=0A+=20=20(should=20(equal=20(rx=20"a"=20""=20"b")=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(seq))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20""))=0A= +=20=20(should=20(equal=20(rx=20""=20(or=20"ab"=20nonl)=20"")=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20"ab\\|.")))=0A+=0A= +(ert-deftest=20rx-or=20()=0A+=20=20(should=20(equal=20(rx=20(or=20"ab"=20= (|=20"c"=20nonl)=20"de"))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"ab\\|c\\|.\\|de"))=0A+=20=20(should=20(equal=20(rx=20(or=20"ab"=20= "abc"=20"a"))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\(?:ab\\|abc\\|a\\)"))=0A+=20=20(should=20(equal=20(rx=20(|=20nonl=20= "a")=20(|=20"b"=20blank))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"\\(?:.\\|a\\)\\(?:b\\|[[:blank:]]\\)"))=0A+=20=20(should=20(equal=20= (rx=20(|))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\`a\\`")))=0A=20=0A=20(ert-deftest=20rx-char-any=20()=0A=20=20=20"Test=20= character=20alternatives=20with=20`]'=20and=20`-'=20(Bug#25123)."=0A-=20=20= (should=20(string-match=0A+=20=20(should=20(equal=0A=20=20=20=20=20=20=20= =20=20=20=20=20(rx=20string-start=20(1+=20(char=20(?\]=20.=20?\{)=20(?<=20= .=20?\])=20(?-=20.=20?:)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20string-end)=0A-=20=20=20=20=20=20=20=20=20=20=20(apply=20#'string=20= (nconc=20(number-sequence=20?\]=20?\{)=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= (number-sequence=20?<=20?\])=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= (number-sequence=20?-=20?:))))))=0A+=20=20=20=20=20=20=20=20=20=20=20= "\\`[.-:<-{-]+\\'")))=0A=20=0A=20(ert-deftest=20rx-char-any-range-nl=20= ()=0A=20=20=20"Test=20character=20alternatives=20with=20LF=20as=20a=20= range=20endpoint."=0A@@=20-40,28=20+63,72=20@@=20rx-char-any-range-nl=0A=20= =20=20(should=20(equal=20(rx=20(any=20"\a-\n"))=0A=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20"[\a-\n]")))=0A=20=0A-(ert-deftest=20= rx-char-any-range-bad=20()=0A-=20=20(should-error=20(rx=20(any=20= "0-9a-Z")))=0A-=20=20(should-error=20(rx=20(any=20(?0=20.=20?9)=20(?a=20= .=20?Z)))))=0A-=0A=20(ert-deftest=20rx-char-any-raw-byte=20()=0A=20=20=20= "Test=20raw=20bytes=20in=20character=20alternatives."=0A+=0A+=20=20;;=20= The=20multibyteness=20of=20the=20rx=20return=20value=20sometimes=20= depends=20on=20whether=0A+=20=20;;=20the=20test=20had=20been=20= byte-compiled=20or=20not,=20so=20we=20add=20explicit=20conversions.=0A+=0A= =20=20=20;;=20Separate=20raw=20characters.=0A-=20=20(should=20(equal=20= (string-match-p=20(rx=20(any=20"\326A\333B"))=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= "X\326\333")=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=201))=0A= +=20=20(should=20(equal=20(string-to-multibyte=20(rx=20(any=20= "\326A\333B")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (string-to-multibyte=20"[AB\326\333]")))=0A=20=20=20;;=20Range=20of=20= raw=20characters,=20unibyte.=0A-=20=20(should=20(equal=20(string-match-p=20= (rx=20(any=20"\200-\377"))=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"=C3=BFA\310B")=0A= -=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=202))=0A+=20=20(should=20= (equal=20(string-to-multibyte=20(rx=20(any=20"\200-\377")))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(string-to-multibyte=20= "[\200-\377]")))=0A+=0A=20=20=20;;=20Range=20of=20raw=20characters,=20= multibyte.=0A-=20=20(should=20(equal=20(string-match-p=20(rx=20(any=20= "=C3=85\211\326-\377\177"))=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= "XY\355\177\327")=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= 2))=0A+=20=20(should=20(equal=20(rx=20(any=20"=C3=85\211\326-\377\177"))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[\177=C3=85\211\326-\377]"))=0A=20=20=20;;=20Split=20range;=20= \177-\377=C3=BF=20should=20not=20be=20optimised=20to=20\177-\377.=0A-=20=20= (should=20(equal=20(string-match-p=20(rx=20(any=20"\177-\377"=20?=C3=BF))=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"=C3=BFA\310B")=0A-=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=200)))=0A+=20=20(should=20(equal=20(rx=20(any=20= "\177-\377"=20?=C3=BF))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20"[\177=C3=BF\200-\377]")))=0A+=0A+(ert-deftest=20rx-any=20()=0A+=20=20= (should=20(equal=20(rx=20(any=20?A=20(?C=20.=20?D)=20"F-H"=20"J-L"=20"M"=20= "N-P"=20"Q"=20"RS"))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[ACDF-HJ-S]"))=0A+=20=20(should=20(equal=20(rx=20(in=20"a!f"=20?c)=20= (char=20"q-z"=20"0-3")=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(not-char=20"a-e1-5")=20(not=20(in=20"A-M"=20?q)))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[!acf][0-3q-z][^1-5a-e][^A-Mq]"))=0A+=20=20(should=20(equal=20(rx=20= (any=20"^")=20(any=20"]")=20(any=20"-")=0A+=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"^"))=20(not=20(any=20= "]"))=20(not=20(any=20"-")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20"\\^]-[^^][^]][^-]"))=0A+=20=20(should=20(equal=20(rx=20(any=20= "]"=20"^")=20(any=20"]"=20"-")=20(any=20"-"=20"^")=0A+=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"]"=20"^"))=20= (not=20(any=20"]"=20"-"))=0A+=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"-"=20"^")))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20"[]^][]-][-^][^]^][^]-][^-^]"))=0A+=20=20(should=20= (equal=20(rx=20(any=20"]"=20"^"=20"-")=20(not=20(any=20"]"=20"^"=20= "-")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[]^-][^]^-]"))=0A+=20=20(should=20(equal=20(rx=20(any=20"-"=20ascii)=20= (any=20"^"=20ascii)=20(any=20"]"=20ascii))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20"[[:ascii:]-][[:ascii:]^][][:ascii:]]"))=0A+=20=20= (should=20(equal=20(rx=20(not=20(any=20"-"=20ascii))=20(not=20(any=20"^"=20= ascii))=0A+=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"]"=20ascii)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20"[^[:ascii:]-][^[:ascii:]^][^][:ascii:]]"))=0A+=20=20(should=20= (equal=20(rx=20(any=20"-]"=20ascii)=20(any=20"^]"=20ascii)=20(any=20"-^"=20= ascii))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[][:ascii:]-][]^[:ascii:]][[:ascii:]^-]"))=0A+=20=20(should=20(equal=20= (rx=20(not=20(any=20"-]"=20ascii))=20(not=20(any=20"^]"=20ascii))=0A+=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= "-^"=20ascii)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[^][:ascii:]-][^]^[:ascii:]][^[:ascii:]^-]"))=0A+=20=20(should=20(equal=20= (rx=20(any=20"-]^"=20ascii)=20(not=20(any=20"-]^"=20ascii)))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[]^[:ascii:]-][^]^[:ascii:]-]"))=0A+=20=20(should=20(equal=20(rx=20(any=20= "^"=20lower=20upper)=20(not=20(any=20"^"=20lower=20upper)))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20= "[[:lower:]^[:upper:]][^[:lower:]^[:upper:]]"))=0A+=20=20(should=20= (equal=20(rx=20(any=20"-"=20lower=20upper)=20(not=20(any=20"-"=20lower=20= upper)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[[:lower:][:upper:]-][^[:lower:][:upper:]-]"))=0A+=20=20(should=20= (equal=20(rx=20(any=20"]"=20lower=20upper)=20(not=20(any=20"]"=20lower=20= upper)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[][:lower:][:upper:]][^][:lower:][:upper:]]"))=0A+=20=20(should=20= (equal=20(rx=20(any=20"-a"=20"c-"=20"f-f"=20"--/*--"))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20"[*-/acf]"))=0A+=20=20(should=20= (equal=20(rx=20(any=20"]-a"=20?-)=20(not=20(any=20"]-a"=20?-)))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"[]-a-][^]-a-]"))=0A+=20=20= (should=20(equal=20(rx=20(any=20"--]")=20(not=20(any=20"--]"))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(any=20"-"=20= "^-a")=20(not=20(any=20"-"=20"^-a")))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20"[].-\\-][^].-\\-][-^-a][^-^-a]"))=0A+=20=20(should=20= (equal=20(rx=20(not=20(any=20"!a"=20"0-8"=20digit=20nonascii)))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[^!0-8a[:digit:][:nonascii:]]"))=0A+=20=20(should=20(equal=20(rx=20= (any)=20(not=20(any)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20"\\`a\\`\\(?:.\\|\n\\)"))=0A+=20=20(should=20(equal=20(rx=20(any=20= "")=20(not=20(any=20"")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"\\`a\\`\\(?:.\\|\n\\)")))=0A=20=0A=20(ert-deftest=20rx-pcase=20()=0A= =20=20=20(should=20(equal=20(pcase=20"a=201=202=203=201=201=20b"=0A@@=20= -71,7=20+138,11=20@@=20rx-pcase=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(backref=20u)=20space=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(backref=20= 1))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (list=20u=20v)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= '("1"=20"3"))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= '("1"=20"3")))=0A+=20=20(let=20((k=20"blue"))=0A+=20=20=20=20(should=20= (equal=20(pcase=20""=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20((rx=20"<"=20(literal=20k)=20">")=20'ok))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'ok))))=0A=20=0A=20= (ert-deftest=20rx-kleene=20()=0A=20=20=20"Test=20greedy=20and=20= non-greedy=20repetition=20operators."=0A@@=20-94,71=20+165,158=20@@=20= rx-kleene=0A=20=20=20(should=20(equal=20(rx=20(maximal-match=0A=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(seq=20(*=20= "a")=20(+=20"b")=20(\?=20"c")=20(?\s=20"d")=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"e")=20(+?=20= "f")=20(\??=20"g")=20(??=20"h"))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20"a*b+c?d?e*?f+?g??h??")))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"a*b+c?d?e*?f+?g??h??"))=0A+=20=20(should=20(equal=20= (rx=20"a"=20(*)=20(+=20(*))=20(?=20(*)=20(+))=20"b")=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20"ab")))=0A=20=0A-(ert-deftest=20rx-or=20= ()=0A-=20=20;;=20Test=20or-pattern=20reordering=20(Bug#34641).=0A-=20=20= (let=20((s=20"abc"))=0A-=20=20=20=20(should=20(equal=20(and=20= (string-match=20(rx=20(or=20"abc"=20"ab"=20"a"))=20s)=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(match-string=200=20= s))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"abc"))=0A= -=20=20=20=20(should=20(equal=20(and=20(string-match=20(rx=20(or=20"ab"=20= "abc"=20"a"))=20s)=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(match-string=200=20s))=0A-=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20"ab"))=0A-=20=20=20=20(should=20(equal=20= (and=20(string-match=20(rx=20(or=20"a"=20"ab"=20"abc"))=20s)=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= (match-string=200=20s))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20"a")))=0A-=20=20;;=20Test=20zero-argument=20`or'.=0A-=20=20= (should=20(equal=20(rx=20(or))=20regexp-unmatchable)))=0A+(ert-deftest=20= rx-repeat=20()=0A+=20=20(should=20(equal=20(rx=20(=3D=203=20"a")=20(>=3D=20= 51=20"b")=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(**=202=2011=20"c")=20(repeat=206=20"d")=20(repeat=204=208=20"e"))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "a\\{3\\}b\\{51,\\}c\\{2,11\\}d\\{6\\}e\\{4,8\\}"))=0A+=20=20(should=20= (equal=20(rx=20(=3D=200=20"k")=20(>=3D=200=20"l")=20(**=200=200=20"m")=20= (repeat=200=20"n")=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(repeat=200=200=20"o"))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20"k\\{0\\}l\\{0,\\}m\\{0\\}n\\{0\\}o\\{0\\}"))=0A+=20=20= (should=20(equal=20(rx=20(opt=20(0+=20"a")))=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= (opt=20(=3D=204=20"a")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"a\\{4\\}?"))=0A+=20=20(should=20(equal=20(rx=20"a"=20(**=203=207)=20= (=3D=204)=20(>=3D=203)=20(=3D=204=20(>=3D=207)=20(=3D=202))=20"b")=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"ab")))=0A+=0A= +(ert-deftest=20rx-atoms=20()=0A+=20=20(should=20(equal=20(rx=20= anything)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ".\\|\n"))=0A+=20=20(should=20(equal=20(rx=20line-start=20not-newline=20= nonl=20any=20line-end)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20"^...$"))=0A+=20=20(should=20(equal=20(rx=20bol=20string-start=20= string-end=20buffer-start=20buffer-end=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20bos=20eos=20bot=20eot=20eol)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20"^\\`\\'\\`\\'\\`\\'\\`\\'$"))=0A= +=20=20(should=20(equal=20(rx=20point=20word-start=20word-end=20bow=20= eow=20symbol-start=20symbol-end=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20word-boundary=20not-word-boundary=20= not-wordchar)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\=3D\\<\\>\\<\\>\\_<\\_>\\b\\B\\W"))=0A+=20=20(should=20(equal=20(rx=20= digit=20numeric=20num=20control=20cntrl)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20= "[[:digit:]][[:digit:]][[:digit:]][[:cntrl:]][[:cntrl:]]"))=0A+=20=20= (should=20(equal=20(rx=20hex-digit=20hex=20xdigit=20blank)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20= "[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:blank:]]"))=0A+=20=20(should=20= (equal=20(rx=20graph=20graphic=20print=20printing)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20= "[[:graph:]][[:graph:]][[:print:]][[:print:]]"))=0A+=20=20(should=20= (equal=20(rx=20alphanumeric=20alnum=20letter=20alphabetic=20alpha)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[[:alnum:]][[:alnum:]][[:alpha:]][[:alpha:]][[:alpha:]]"))=0A+=20=20= (should=20(equal=20(rx=20ascii=20nonascii=20lower=20lower-case)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[[:ascii:]][[:nonascii:]][[:lower:]][[:lower:]]"))=0A+=20=20(should=20= (equal=20(rx=20punctuation=20punct=20space=20whitespace=20white)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[[:punct:]][[:punct:]][[:space:]][[:space:]][[:space:]]"))=0A+=20=20= (should=20(equal=20(rx=20upper=20upper-case=20word=20wordchar)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[[:upper:]][[:upper:]][[:word:]][[:word:]]"))=0A+=20=20(should=20(equal=20= (rx=20unibyte=20multibyte)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"[[:unibyte:]][[:multibyte:]]")))=0A+=0A+(ert-deftest=20rx-syntax=20= ()=0A+=20=20(should=20(equal=20(rx=20(syntax=20whitespace)=20(syntax=20= punctuation)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(syntax=20word)=20(syntax=20symbol)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(syntax=20open-parenthesis)=20(syntax=20= close-parenthesis))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\s-\\s.\\sw\\s_\\s(\\s)"))=0A+=20=20(should=20(equal=20(rx=20(syntax=20= string-quote)=20(syntax=20paired-delimiter)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(syntax=20escape)=20(syntax=20= character-quote)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(syntax=20comment-start)=20(syntax=20comment-end)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(syntax=20= string-delimiter)=20(syntax=20comment-delimiter))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20"\\s\"\\s$\\s\\\\s/\\s<\\s>\\s|\\s!")))=0A= +=0A+(ert-deftest=20rx-category=20()=0A+=20=20(should=20(equal=20(rx=20= (category=20space-for-indent)=20(category=20base)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(category=20consonant)=20= (category=20base-vowel)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(category=20upper-diacritical-mark)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(category=20= lower-diacritical-mark)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(category=20tone-mark)=20(category=20symbol)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(category=20digit)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (category=20vowel-modifying-diacritical-mark)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(category=20vowel-sign)=20= (category=20semivowel-lower)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(category=20not-at-end-of-line)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(category=20= not-at-beginning-of-line))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"\\c=20\\c.\\c0\\c1\\c2\\c3\\c4\\c5\\c6\\c7\\c8\\c9\\c<\\c>"))=0A+=20= =20(should=20(equal=20(rx=20(category=20alpha-numeric-two-byte)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(category=20= chinese-two-byte)=20(category=20greek-two-byte)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(category=20= japanese-hiragana-two-byte)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(category=20indian-two-byte)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(category=20= japanese-katakana-two-byte)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(category=20strong-left-to-right)=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(category=20= korean-hangul-two-byte)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(category=20strong-right-to-left)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(category=20cyrillic-two-byte)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (category=20combining-diacritic))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20"\\cA\\cC\\cG\\cH\\cI\\cK\\cL\\cN\\cR\\cY\\c^"))=0A+=20=20= (should=20(equal=20(rx=20(category=20ascii)=20(category=20arabic)=20= (category=20chinese)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(category=20ethiopic)=20(category=20greek)=20(category=20= korean)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (category=20indian)=20(category=20japanese)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(category=20japanese-katakana)=20= (category=20latin)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(category=20lao)=20(category=20tibetan))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20= "\\ca\\cb\\cc\\ce\\cg\\ch\\ci\\cj\\ck\\cl\\co\\cq"))=0A+=20=20(should=20= (equal=20(rx=20(category=20japanese-roman)=20(category=20thai)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(category=20= vietnamese)=20(category=20hebrew)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(category=20cyrillic)=20(category=20= can-break))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\cr\\ct\\cv\\cw\\cy\\c|"))=0A+=20=20(should=20(equal=20(rx=20(category=20= ?g)=20(not=20(category=20?~)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"\\cg\\C~")))=0A+=0A+(ert-deftest=20rx-not=20()=0A+=20=20= (should=20(equal=20(rx=20(not=20word-boundary))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20"\\B"))=0A+=20=20(should=20(equal=20(rx=20= (not=20ascii)=20(not=20lower-case)=20(not=20wordchar))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20= "[^[:ascii:]][^[:lower:]][^[:word:]]"))=0A+=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"\\S.\\S\\"))=0A+=20=20(should=20= (equal=20(rx=20(not=20(category=20tone-mark))=20(not=20(category=20= lao)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\C4\\Co")))=0A+=0A+(ert-deftest=20rx-group=20()=0A+=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(group-n=203=20"y")=20= (submatch-n=2013=20"z")=20(backref=201))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"\\(.\\)\\(x\\)\\(?3:y\\)\\(?13:z\\)\\1"))=0A+=20=20= (should=20(equal=20(rx=20(group)=20(group-n=202))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20"\\(\\)\\(?2:\\)")))=0A+=0A+(ert-deftest=20= rx-regexp=20()=0A+=20=20(should=20(equal=20(rx=20(regexp=20"abc")=20= (regex=20"[de]"))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\(?:abc\\)[de]"))=0A+=20=20(let=20((x=20"a*"))=0A+=20=20=20=20(should=20= (equal=20(rx=20(regexp=20x)=20"b")=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"\\(?:a*\\)b"))=0A+=20=20=20=20(should=20(equal=20= (rx=20""=20(regexp=20x)=20(eval=20""))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20"a*"))))=0A+=0A+(ert-deftest=20rx-eval=20()=0A+=20= =20(should=20(equal=20(rx=20(eval=20(list=20'syntax=20'symbol)))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"\\s_"))=0A+=20=20(should=20= (equal=20(rx=20"a"=20(eval=20(concat))=20"b")=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20"ab")))=0A+=0A+(ert-deftest=20rx-literal=20()=0A= +=20=20(should=20(equal=20(rx=20(literal=20(char-to-string=2042))=20= nonl)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"\\*."))=0A+=20= =20(let=20((x=20"a+b"))=0A+=20=20=20=20(should=20(equal=20(rx=20(opt=20= (literal=20(upcase=20x))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"\\(?:A\\+B\\)?"))))=0A+=0A+(ert-deftest=20rx-to-string=20()=0A= +=20=20(should=20(equal=20(rx-to-string=20'(or=20nonl=20"\nx"))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"\\(?:.\\|\nx\\)"))=0A+=20=20= (should=20(equal=20(rx-to-string=20'(or=20nonl=20"\nx")=20t)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20".\\|\nx")))=0A+=0A+=0A= +(ert-deftest=20rx-constituents=20()=0A+=20=20(let=20((rx-constituents=0A= +=20=20=20=20=20=20=20=20=20(append=20'((beta=20.=20gamma)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(gamma=20.=20"a*b")=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(delta=20.=20((lambda=20= (form)=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(regexp-quote=20(format=20"<%S>"=20form)))=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=201=20nil=20symbolp))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(epsilon=20.=20delta))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20rx-constituents)))=0A+=20=20=20=20(should=20= (equal=20(rx-to-string=20'(seq=20(+=20beta)=20nonl=20gamma)=20t)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\(?:a*b\\)+.\\(?:a*b\\)"))=0A+=20=20=20=20(should=20(equal=20= (rx-to-string=20'(seq=20(delta=20a=20b=20c)=20(*=20(epsilon=20d=20e)))=20= t)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\(?:<(delta=20a=20b=20c)>\\)\\(?:<(epsilon=20d=20e)>\\)*"))))=0A=20=0A= -(ert-deftest=20rx-seq=20()=0A-=20=20;;=20Test=20zero-argument=20`seq'.=0A= -=20=20(should=20(equal=20(rx=20(seq))=20"")))=0A-=0A-(defmacro=20= rx-tests--match=20(regexp=20string=20&optional=20match)=0A-=20=20= (macroexp-let2=20nil=20strexp=20string=0A-=20=20=20=20`(ert-info=20= ((format=20"Matching=20%S=20to=20%S"=20',regexp=20,strexp))=0A-=20=20=20=20= =20=20=20(should=20(string-match=20,regexp=20,strexp))=0A-=20=20=20=20=20= =20=20,@(when=20match=0A-=20=20=20=20=20=20=20=20=20=20=20`((should=20= (equal=20(match-string=200=20,strexp)=20,match)))))))=0A-=0A= -(ert-deftest=20rx-nonstring-expr=20()=0A-=20=20(let=20((bee=20"b")=0A-=20= =20=20=20=20=20=20=20(vowel=20"[aeiou]"))=0A-=20=20=20=20= (rx-tests--match=20(rx=20"a"=20(literal=20bee)=20"c")=20"abc")=0A-=20=20=20= =20(rx-tests--match=20(rx=20"a"=20(regexp=20bee)=20"c")=20"abc")=0A-=20=20= =20=20(rx-tests--match=20(rx=20"a"=20(or=20(regexp=20bee)=20"xy")=20"c")=20= "abc")=0A-=20=20=20=20(rx-tests--match=20(rx=20"a"=20(or=20"xy"=20= (regexp=20bee))=20"c")=20"abc")=0A-=20=20=20=20(should-not=20= (string-match=20(rx=20(or=20(regexp=20bee)=20"xy"))=20""))=0A-=20=20=20=20= (rx-tests--match=20(rx=20"a"=20(=3D=203=20(regexp=20bee))=20"c")=20= "abbbc")=0A-=20=20=20=20(rx-tests--match=20(rx=20"x"=20(=3D=203=20= (regexp=20vowel))=20"z")=20"xeoez")=0A-=20=20=20=20(should-not=20= (string-match=20(rx=20"x"=20(=3D=203=20(regexp=20vowel))=20"z")=20= "xe[]z"))=0A-=20=20=20=20(rx-tests--match=20(rx=20"x"=20(=3D=203=20= (literal=20vowel))=20"z")=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20"x[aeiou][aeiou][aeiou]z")=0A-=20=20=20=20= (rx-tests--match=20(rx=20"x"=20(repeat=201=20(regexp=20vowel))=20"z")=20= "xaz")=0A-=20=20=20=20(rx-tests--match=20(rx=20"x"=20(repeat=201=202=20= (regexp=20vowel))=20"z")=20"xaz")=0A-=20=20=20=20(rx-tests--match=20(rx=20= "x"=20(repeat=201=202=20(regexp=20vowel))=20"z")=20"xauz")=0A-=20=20=20=20= (rx-tests--match=20(rx=20"x"=20(>=3D=201=20(regexp=20vowel))=20"z")=20= "xaiiz")=0A-=20=20=20=20(rx-tests--match=20(rx=20"x"=20(**=201=202=20= (regexp=20vowel))=20"z")=20"xaiz")=0A-=20=20=20=20(rx-tests--match=20(rx=20= "x"=20(group=20(regexp=20vowel))=20"z")=20"xaz")=0A-=20=20=20=20= (rx-tests--match=20(rx=20"x"=20(group-n=201=20(regexp=20vowel))=20"z")=20= "xaz")=0A-=20=20=20=20(rx-tests--match=20(rx=20"x"=20(?=20(regexp=20= vowel))=20"z")=20"xz")))=0A-=0A-(ert-deftest=20= rx-nonstring-expr-non-greedy=20()=0A-=20=20"`rx's=20greediness=20can't=20= affect=20runtime=20regexp=20parts."=0A-=20=20(let=20((ad-min=20"[ad]*?")=0A= -=20=20=20=20=20=20=20=20(ad-max=20"[ad]*")=0A-=20=20=20=20=20=20=20=20= (ad=20"[ad]"))=0A-=20=20=20=20(rx-tests--match=20(rx=20"c"=20(regexp=20= ad-min)=20"a")=20"cdaaada"=20"cda")=0A-=20=20=20=20(rx-tests--match=20= (rx=20"c"=20(regexp=20ad-max)=20"a")=20"cdaaada"=20"cdaaada")=0A-=20=20=20= =20(rx-tests--match=20(rx=20"c"=20(minimal-match=20(regexp=20ad-max))=20= "a")=20"cdaaada"=20"cdaaada")=0A-=20=20=20=20(rx-tests--match=20(rx=20= "c"=20(maximal-match=20(regexp=20ad-min))=20"a")=20"cdaaada"=20"cda")=0A= -=20=20=20=20(rx-tests--match=20(rx=20"c"=20(minimal-match=20(0+=20= (regexp=20ad)))=20"a")=20"cdaaada"=20"cda")=0A-=20=20=20=20= (rx-tests--match=20(rx=20"c"=20(maximal-match=20(0+=20(regexp=20ad)))=20= "a")=20"cdaaada"=20"cdaaada")))=0A-=0A-(ert-deftest=20= rx-to-string-lisp-forms=20()=0A-=20=20(rx-tests--match=20(rx-to-string=20= '(seq=20"a"=20(literal=20"b")=20"c"))=20"abc")=0A-=20=20(rx-tests--match=20= (rx-to-string=20'(seq=20"a"=20(regexp=20"b")=20"c"))=20"abc"))=0A=20=0A=20= (provide=20'rx-tests)=0A-;;=20rx-tests.el=20ends=20here.=0A--=20=0A= 2.21.0=20(Apple=20Git-122)=0A=0A= --Apple-Mail=_ED516277-A780-48D5-ABD4-A7754848202D Content-Disposition: attachment; filename=0002-Add-rx-extension-mechanism.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0002-Add-rx-extension-mechanism.patch" Content-Transfer-Encoding: quoted-printable =46rom=20f1b775f200b127c861ebdb0fa78110948d9e81f5=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Mon,=202=20Sep=202019=2016:07:23=20+0200=0A= Subject:=20[PATCH=202/2]=20Add=20rx=20extension=20mechanism=0A=0AAdd=20a=20= built-in=20set=20of=20extension=20macros:=20`rx-define',=20`rx-let'=20= and=0A`rx-let-eval'.=0A=0A*=20lisp/emacs-lisp/rx.el=20(rx-constituents,=20= rx-to-string):=20Doc=20updates.=0A(rx--builtin-symbols,=20= rx--builtin-names,=20rx--local-definitions)=0A(rx--lookup-def,=20= rx--substitute,=20rx--expand-template)=0A(rx--make-binding,=20= rx--make-named-binding,=20rx--extend-local-defs)=0A(rx-let-eval,=20= rx-let,=20rx-define):=20New.=0A(rx--translate-symbol,=20= rx--translate-form):=20Use=20extensions=20if=20any.=0A(rx):=20Use=20= local=20definitions.=0A*=20test/lisp/emacs-lisp/rx-tests.el=20(rx-let,=20= rx-define)=0A(rx-to-string-define,=20rx-let-define,=20rx-let-eval):=20= New.=0A*=20etc/NEWS=20(Changes=20in=20Specialized=20Modes=20and=20= Packages):=0A*=20doc/lispref/searching.texi=20(Rx=20Notation,=20Rx=20= Functions,=20Extending=20Rx):=0AAdd=20node=20about=20rx=20extensions.=0A= ---=0A=20doc/lispref/searching.texi=20=20=20=20=20=20=20|=20157=20= ++++++++++++++++=0A=20etc/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=204=20+=0A=20lisp/emacs-lisp/rx.el=20= =20=20=20=20=20=20=20=20=20=20=20|=20299=20= ++++++++++++++++++++++++++++---=0A=20test/lisp/emacs-lisp/rx-tests.el=20= |=20=2098=20++++++++++=0A=204=20files=20changed,=20538=20insertions(+),=20= 20=20deletions(-)=0A=0Adiff=20--git=20a/doc/lispref/searching.texi=20= b/doc/lispref/searching.texi=0Aindex=2021b1f7b68b..015871fab0=20100644=0A= ---=20a/doc/lispref/searching.texi=0A+++=20b/doc/lispref/searching.texi=0A= @@=20-1037,6=20+1037,7=20@@=20Rx=20Notation=0A=20@menu=0A=20*=20Rx=20= Constructs::=20=20=20=20=20=20=20Constructs=20valid=20in=20rx=20forms.=0A= =20*=20Rx=20Functions::=20=20=20=20=20=20=20=20Functions=20and=20macros=20= that=20use=20rx=20forms.=0A+*=20Extending=20Rx::=20=20=20=20=20=20=20=20= How=20to=20define=20your=20own=20rx=20forms.=0A=20@end=20menu=0A=20=0A=20= @node=20Rx=20Constructs=0A@@=20-1524,6=20+1525,162=20@@=20Rx=20Functions=0A= =20=0A=20The=20@code{pcase}=20macro=20can=20use=20@code{rx}=20= expressions=20as=20patterns=0A=20directly;=20@pxref{rx=20in=20pcase}.=0A= +=0A+For=20mechanisms=20to=20add=20user-defined=20extensions=20to=20the=20= @code{rx}=0A+notation,=20@pxref{Extending=20Rx}.=0A+=0A+@node=20= Extending=20Rx=0A+@subsubsection=20Defining=20new=20@code{rx}=20forms=0A= +=0A+The=20@code{rx}=20notation=20can=20be=20extended=20by=20defining=20= new=20symbols=20and=0A+parametrised=20forms=20in=20terms=20of=20other=20= @code{rx}=20expressions.=20=20This=20is=0A+handy=20for=20sharing=20parts=20= between=20several=20regexps,=20and=20for=20making=0A+complex=20ones=20= easier=20to=20build=20and=20understand=20by=20putting=20them=20together=0A= +from=20smaller=20pieces.=0A+=0A+For=20example,=20you=20could=20define=20= @code{name}=20to=20mean=0A+@code{(one-or-more=20letter)},=20and=20= @code{(quoted=20@var{x})}=20to=20mean=0A+@code{(seq=20?'=20@var{x}=20= ?')}=20for=20any=20@var{x}.=20=20These=20forms=20could=20then=20be=0A= +used=20in=20@code{rx}=20expressions=20like=20any=20other:=20@code{(rx=20= (quoted=20name))}=0A+would=20match=20a=20nonempty=20sequence=20of=20= letters=20inside=20single=20quotes.=0A+=0A+The=20Lisp=20macros=20below=20= provide=20different=20ways=20of=20binding=20names=20to=0A+definitions.=20= =20Common=20to=20all=20of=20them=20are=20the=20following=20rules:=0A+=0A= +@itemize=0A+@item=0A+Built-in=20@code{rx}=20forms,=20like=20= @code{digit}=20and=20@code{group},=20cannot=0A+be=20redefined.=0A+=0A= +@item=0A+The=20definitions=20live=20in=20a=20name=20space=20of=20their=20= own,=20separate=20from=20that=0A+of=20Lisp=20variables.=20=20There=20is=20= thus=20no=20need=20to=20attach=20a=20suffix=20like=0A+@code{-regexp}=20= to=20names;=20they=20cannot=20collide=20with=20anything=20else.=0A+=0A= +@item=0A+Definitions=20cannot=20refer=20to=20themselves=20recursively,=20= directly=20or=0A+indirectly.=20=20If=20you=20find=20yourself=20needing=20= this,=20you=20want=20a=20parser,=20not=0A+a=20regular=20expression.=0A+=0A= +@item=0A+Definitions=20are=20only=20ever=20expanded=20in=20calls=20to=20= @code{rx}=20or=0A+@code{rx-to-string},=20not=20merely=20by=20their=20= presence=20in=20definition=0A+macros.=20=20This=20means=20that=20the=20= order=20of=20definitions=20doesn't=20matter,=20even=0A+when=20they=20= refer=20to=20each=20other,=20and=20that=20syntax=20errors=20only=20show=20= up=0A+when=20they=20are=20used,=20not=20when=20they=20are=20defined.=0A+=0A= +@item=0A+User-defined=20forms=20are=20allowed=20wherever=20arbitrary=20= @code{rx}=0A+expressions=20are=20expected;=20for=20example,=20in=20the=20= body=20of=20a=0A+@code{zero-or-one}=20form,=20but=20not=20inside=20= @code{any}=20or=20@code{category}=0A+forms.=0A+@end=20itemize=0A+=0A= +@defmac=20rx-define=20name=20[arglist]=20rx-form=0A+Define=20@var{name}=20= globally=20in=20all=20subsequent=20calls=20to=20@code{rx}=20and=0A= +@code{rx-to-string}.=20=20If=20@var{arglist}=20is=20absent,=20then=20= @var{name}=20is=0A+defined=20as=20a=20plain=20symbol=20to=20be=20= replaced=20with=20@var{rx-form}.=20=20Example:=0A+=0A+@example=0A+@group=0A= +(rx-define=20haskell-comment=20(seq=20"--"=20(zero-or-more=20nonl)))=0A= +(rx=20haskell-comment)=0A+=20=20=20=20=20@result{}=20"--.*"=0A+@end=20= group=0A+@end=20example=0A+=0A+If=20@var{arglist}=20is=20present,=20it=20= must=20be=20a=20list=20of=20zero=20or=20more=0A+argument=20names,=20and=20= @var{name}=20is=20then=20defined=20as=20a=20parametrised=20form.=0A+When=20= used=20in=20an=20@code{rx}=20expression=20as=20@code{(@var{name}=20= @var{arg}@dots{})},=0A+each=20@var{arg}=20will=20replace=20the=20= corresponding=20argument=20name=20inside=0A+@var{rx-form}.=0A+=0A= +@var{arglist}=20may=20end=20in=20@code{&rest}=20and=20one=20final=20= argument=20name,=0A+denoting=20a=20rest=20parameter.=20=20The=20rest=20= parameter=20will=20expand=20to=20all=0A+extra=20actual=20argument=20= values=20not=20matched=20by=20any=20other=20parameter=20in=0A= +@var{arglist},=20spliced=20into=20@var{rx-form}=20where=20it=20occurs.=20= =20Example:=0A+=0A+@example=0A+@group=0A+(rx-define=20moan=20(x=20y=20= &rest=20r)=20(seq=20x=20(one-or-more=20y)=20r=20"!"))=0A+(rx=20(moan=20= "MOO"=20"A"=20"MEE"=20"OW"))=0A+=20=20=20=20=20@result{}=20"MOOA+MEEOW!"=0A= +@end=20group=0A+@end=20example=0A+=0A+Since=20the=20definition=20is=20= global,=20it=20is=20recommended=20to=20give=20@var{name}=20a=0A+package=20= prefix=20to=20avoid=20name=20clashes=20with=20definitions=20elsewhere,=20= as=20is=0A+usual=20when=20naming=20non-local=20variables=20and=20= functions.=0A+@end=20defmac=0A+=0A+@defmac=20rx-let=20(bindings@dots{})=20= body@dots{}=0A+Make=20the=20@code{rx}=20definitions=20in=20= @var{bindings}=20available=20locally=20for=0A+@code{rx}=20macro=20= invocations=20in=20@var{body},=20which=20is=20then=20evaluated.=0A+=0A= +Each=20element=20of=20@var{bindings}=20is=20on=20the=20form=0A= +@w{@code{(@var{name}=20[@var{arglist}]=20@var{rx-form})}},=20where=20= the=20parts=0A+have=20the=20same=20meaning=20as=20in=20@code{rx-define}=20= above.=20=20Example:=0A+=0A+@example=0A+@group=0A+(rx-let=20= ((comma-separated=20(item)=20(seq=20item=20(0+=20","=20item)))=0A+=20=20=20= =20=20=20=20=20=20(number=20(1+=20digit))=0A+=20=20=20=20=20=20=20=20=20= (numbers=20(comma-separated=20number)))=0A+=20=20(re-search-forward=20= (rx=20"("=20numbers=20")")))=0A+@end=20group=0A+@end=20example=0A+=0A= +The=20definitions=20are=20only=20available=20during=20the=20= macro-expansion=20of=0A+@var{body},=20and=20are=20thus=20not=20present=20= during=20execution=20of=20compiled=0A+code.=0A+=0A+@code{rx-let}=20can=20= be=20used=20not=20only=20inside=20a=20function,=20but=20also=20at=20top=0A= +level=20to=20include=20global=20variable=20and=20function=20definitions=20= that=20need=0A+to=20share=20a=20common=20set=20of=20@code{rx}=20forms.=20= =20Since=20the=20names=20are=20local=0A+inside=20@var{body},=20there=20= is=20no=20need=20for=20any=20package=20prefixes.=0A+Example:=0A+=0A= +@example=0A+@group=0A+(rx-let=20((phone-number=20(seq=20(opt=20?+)=20= (1+=20(any=20digit=20?-)))))=0A+=20=20(defun=20find-next-phone-number=20= ()=0A+=20=20=20=20(re-search-forward=20(rx=20phone-number)))=0A+=20=20= (defun=20phone-number-p=20(string)=0A+=20=20=20=20(string-match-p=20(rx=20= bos=20phone-number=20eos)=20string)))=0A+@end=20group=0A+@end=20example=0A= +=0A+The=20scope=20of=20the=20@code{rx-let}=20bindings=20is=20lexical,=20= which=20means=20that=0A+they=20are=20not=20visible=20outside=20= @var{body}=20itself,=20even=20in=20functions=0A+called=20from=20= @var{body}.=0A+@end=20defmac=0A+=0A+@defmac=20rx-let-eval=20bindings=20= body@dots{}=0A+Evaluate=20@var{bindings}=20to=20a=20list=20of=20bindings=20= as=20in=20@code{rx-let},=0A+and=20evaluate=20@var{body}=20with=20those=20= bindings=20in=20effect=20for=20calls=0A+to=20@code{rx-to-string}.=0A+=0A= +This=20macro=20is=20similar=20to=20@code{rx-let},=20except=20that=20the=20= @var{bindings}=0A+argument=20is=20evaluated=20(and=20thus=20needs=20to=20= be=20quoted=20if=20it=20is=20a=20list=0A+literal),=20and=20the=20= definitions=20are=20substituted=20at=20run=20time,=20which=20is=0A= +required=20for=20@code{rx-to-string}=20to=20work.=20=20Example:=0A+=0A= +@example=0A+@group=0A+(rx-let-eval=0A+=20=20=20=20'((ponder=20(x)=20= (seq=20"Where=20have=20all=20the=20"=20x=20"=20gone?")))=0A+=20=20= (looking-at=20(rx-to-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20'(ponder=20(or=20"flowers"=20"young=20girls"=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"left=20= socks")))))=0A+@end=20group=0A+@end=20example=0A+=0A+Another=20= difference=20from=20@code{rx-let}=20is=20that=20the=20@var{bindings}=20= are=0A+dynamically=20scoped,=20and=20thus=20also=20available=20in=20= functions=20called=20from=0A+@var{body}.=20However,=20they=20are=20not=20= visible=20inside=20functions=20defined=20in=0A+@var{body}.=0A+@end=20= defmac=0A+=0A=20@end=20ifnottex=0A=20=0A=20@node=20Regexp=20Functions=0A= diff=20--git=20a/etc/NEWS=20b/etc/NEWS=0Aindex=2050956f4082..3f7d4894df=20= 100644=0A---=20a/etc/NEWS=0A+++=20b/etc/NEWS=0A@@=20-1725,6=20+1725,10=20= @@=20This=20also=20works=20for=20their=20aliases:=20'|'=20for=20'or';=20= ':',=20'and'=20and=0A=20In=20this=20case,=20'rx'=20will=20generate=20= code=20which=20produces=20a=20regexp=20string=0A=20at=20run=20time,=20= instead=20of=20a=20constant=20string.=0A=20=0A+---=0A+***=20New=20rx=20= extension=20mechanism:=20'rx-define',=20'rx-let',=20'rx-let-eval'.=0A= +These=20macros=20add=20new=20forms=20to=20the=20rx=20notation.=0A+=0A=20= **=20Frames=0A=20=0A=20+++=0Adiff=20--git=20a/lisp/emacs-lisp/rx.el=20= b/lisp/emacs-lisp/rx.el=0Aindex=209b3419e1c8..a192ed1ad2=20100644=0A---=20= a/lisp/emacs-lisp/rx.el=0A+++=20b/lisp/emacs-lisp/rx.el=0A@@=20-97,6=20= +97,7=20@@=20rx--char-classes=0A=20=0A=20(defvar=20rx-constituents=20nil=0A= =20=20=20"Alist=20of=20old-style=20rx=20extensions,=20for=20= compatibility.=0A+For=20new=20code,=20use=20`rx-define',=20`rx-let'=20or=20= `rx-let-eval'.=0A=20=0A=20Each=20element=20is=20(SYMBOL=20.=20DEF).=0A=20= =0A@@=20-113,6=20+114,17=20@@=20rx-constituents=0A=20=20=20=20If=20PRED=20= is=20non-nil,=20it=20is=20a=20predicate=20that=20all=20actual=20= arguments=20must=0A=20=20=20=20satisfy.")=0A=20=0A+(defvar=20= rx--local-definitions=20nil=0A+=20=20"Alist=20of=20dynamic=20local=20rx=20= definitions.=0A+Each=20entry=20is:=0A+=20(NAME=20DEF)=20=20=20=20=20=20= --=20NAME=20is=20an=20rx=20symbol=20defined=20as=20the=20rx=20form=20= DEF.=0A+=20(NAME=20ARGS=20DEF)=20--=20NAME=20is=20an=20rx=20form=20with=20= arglist=20ARGS,=20defined=0A+=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=20contain=20= members=20of=20ARGS).")=0A+=0A+(defsubst=20rx--lookup-def=20(name)=0A+=20= =20(or=20(cdr=20(assq=20name=20rx--local-definitions))=0A+=20=20=20=20=20= =20(get=20name=20'rx-definition)))=0A+=0A=20;;=20TODO:=20Additions=20to=20= consider:=0A=20;;=20-=20A=20better=20name=20for=20`anything',=20like=20= `any-char'=20or=20`anychar'.=0A=20;;=20-=20A=20name=20for=20(or),=20= maybe=20`unmatchable'.=0A@@=20-144,6=20+156,12=20@@=20= rx--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=20= class=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=20definition))))))=0A+=0A=20=20= =20=20=20=20=20;;=20For=20compatibility=20with=20old=20rx.=0A=20=20=20=20= =20=20=20((let=20((entry=20(assq=20sym=20rx-constituents)))=0A=20=20=20=20= =20=20=20=20=20=20(and=20(progn=0A@@=20-310,6=20+328,19=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=20(defun=20rx--translate-any=20= (negated=20body)=0A=20=20=20"Translate=20an=20(any=20...)=20construct.=20= =20Return=20(REGEXP=20.=20PRECEDENCE).=0A=20If=20NEGATED,=20negate=20the=20= sense."=0A@@=20-712,6=20+743,94=20@@=20rx--translate-compat-form=0A=20=20= =20=20=20=20=20=20=20(error=20"The=20`%s'=20form=20did=20not=20expand=20= to=20a=20string"=20(car=20form)))=0A=20=20=20=20=20=20=20(cons=20(list=20= regexp)=20nil))))=0A=20=0A+(defun=20rx--substitute=20(bindings=20form)=0A= +=20=20"Substitute=20BINDINGS=20in=20FORM.=20=20BINDINGS=20is=20an=20= alist=20of=20(NAME=20.=20VALUES)=0A+where=20VALUES=20is=20a=20list=20to=20= splice=20into=20FORM=20wherever=20NAME=20occurs.=0A+Return=20the=20= substitution=20result=20wrapped=20in=20a=20list,=20since=20a=20single=20= value=0A+can=20expand=20to=20any=20number=20of=20values."=0A+=20=20(cond=20= ((symbolp=20form)=0A+=20=20=20=20=20=20=20=20=20(let=20((binding=20(assq=20= form=20bindings)))=0A+=20=20=20=20=20=20=20=20=20=20=20(if=20binding=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(cdr=20binding)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20(list=20form))))=0A+=20=20=20=20=20=20=20=20= ((consp=20form)=0A+=20=20=20=20=20=20=20=20=20(if=20(listp=20(cdr=20= form))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Proper=20list.=20=20= We=20substitute=20variables=20even=20in=20the=20head=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20;;=20position=20--=20who=20knows,=20might=20be=20= handy=20one=20day.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(list=20= (mapcan=20(lambda=20(x)=20(copy-sequence=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= =20=20=20=20=20(rx--substitute=20bindings=20x)))=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=20form))=0A+=20= =20=20=20=20=20=20=20=20=20=20;;=20Cons=20pair=20(presumably=20an=20= interval).=0A+=20=20=20=20=20=20=20=20=20=20=20(let=20((first=20= (rx--substitute=20bindings=20(car=20form)))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(second=20(rx--substitute=20bindings=20(cdr=20= form))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20(and=20first=20= (not=20(cdr=20first))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20second=20(not=20(cdr=20second)))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(list=20(cons=20(car=20first)=20(car=20= second)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(error=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20"Cannot=20substitute=20a=20= &rest=20parameter=20into=20a=20dotted=20pair")))))=0A+=20=20=20=20=20=20=20= =20(t=20(list=20form))))=0A+=0A+;;=20FIXME:=20Consider=20adding=20= extensions=20in=20Lisp=20macro=20style,=20where=0A+;;=20arguments=20are=20= passed=20unevaluated=20to=20code=20that=20returns=20the=20rx=20form=0A= +;;=20to=20use.=20=20Example:=0A+;;=0A+;;=20=20=20(rx-let=20= ((radix-digit=20(radix)=0A+;;=20=20=20=20=20=20=20=20=20=20=20=20=20= :lisp=20(list=20'any=20(cons=20?0=20(+=20?0=20(eval=20radix)=20-1)))))=0A= +;;=20=20=20=20=20(rx=20(radix-digit=20(+=205=203))))=0A+;;=20=3D>=0A+;;=20= =20=20"[0-7]"=0A+;;=0A+;;=20While=20this=20would=20permit=20more=20= powerful=20extensions,=20it's=20unclear=20just=0A+;;=20how=20often=20= they=20would=20be=20used=20in=20practice.=20=20Let's=20wait=20until=20= there=20is=0A+;;=20demand=20for=20it.=0A+=0A+;;=20FIXME:=20An=20= alternative=20binding=20syntax=20would=20be=0A+;;=0A+;;=20=20=20(NAME=20= RXs...)=0A+;;=20and=0A+;;=20=20=20((NAME=20ARGS...)=20RXs...)=0A+;;=0A= +;;=20which=20would=20have=20two=20minor=20advantages:=20multiple=20RXs=20= with=20implicit=0A+;;=20`seq'=20in=20the=20definition,=20and=20the=20= arglist=20is=20no=20longer=20an=20optional=0A+;;=20element=20in=20the=20= middle=20of=20the=20list.=20=20On=20the=20other=20hand,=20it's=20less=0A= +;;=20like=20traditional=20lisp=20arglist=20constructs=20(defun,=20= defmacro).=0A+;;=20Since=20it's=20a=20Scheme-like=20syntax,=20&rest=20= parameters=20could=20be=20done=20using=0A+;;=20dotted=20lists:=0A+;;=20=20= (rx-let=20(((name=20arg1=20arg2=20.=20rest)=20...definition...))=20...)=0A= +=0A+(defun=20rx--expand-template=20(op=20values=20arglist=20template)=0A= +=20=20"Return=20TEMPLATE=20with=20variables=20in=20ARGLIST=20replaced=20= with=20VALUES."=0A+=20=20(let=20((bindings=20nil)=0A+=20=20=20=20=20=20=20= =20(value-tail=20values)=0A+=20=20=20=20=20=20=20=20(formals=20arglist))=0A= +=20=20=20=20(while=20formals=0A+=20=20=20=20=20=20(pcase=20(car=20= formals)=0A+=20=20=20=20=20=20=20=20('&rest=0A+=20=20=20=20=20=20=20=20=20= (unless=20(cdr=20formals)=0A+=20=20=20=20=20=20=20=20=20=20=20(error=0A+=20= =20=20=20=20=20=20=20=20=20=20=20"Expanding=20rx=20def=20`%s':=20missing=20= &rest=20parameter=20name"=20op))=0A+=20=20=20=20=20=20=20=20=20(push=20= (cons=20(cadr=20formals)=20value-tail)=20bindings)=0A+=20=20=20=20=20=20=20= =20=20(setq=20formals=20nil)=0A+=20=20=20=20=20=20=20=20=20(setq=20= value-tail=20nil))=0A+=20=20=20=20=20=20=20=20(name=0A+=20=20=20=20=20=20= =20=20=20(unless=20value-tail=0A+=20=20=20=20=20=20=20=20=20=20=20(error=0A= +=20=20=20=20=20=20=20=20=20=20=20=20"Expanding=20rx=20def=20`%s':=20too=20= few=20arguments=20(got=20%d,=20need=20%s%d)"=0A+=20=20=20=20=20=20=20=20=20= =20=20=20op=20(length=20values)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= (if=20(memq=20'&rest=20arglist)=20"at=20least=20"=20"")=0A+=20=20=20=20=20= =20=20=20=20=20=20=20(-=20(length=20arglist)=20(length=20(memq=20'&rest=20= arglist)))))=0A+=20=20=20=20=20=20=20=20=20(push=20(cons=20name=20(list=20= (car=20value-tail)))=20bindings)=0A+=20=20=20=20=20=20=20=20=20(setq=20= value-tail=20(cdr=20value-tail))))=0A+=20=20=20=20=20=20(setq=20formals=20= (cdr=20formals)))=0A+=20=20=20=20(when=20value-tail=0A+=20=20=20=20=20=20= (error=0A+=20=20=20=20=20=20=20"Expanding=20rx=20def=20`%s':=20too=20= many=20arguments=20(got=20%d,=20need=20%d)"=0A+=20=20=20=20=20=20=20op=20= (length=20values)=20(length=20arglist)))=0A+=20=20=20=20(let=20((subst=20= (rx--substitute=20bindings=20template)))=0A+=20=20=20=20=20=20(if=20(and=20= subst=20(not=20(cdr=20subst)))=0A+=20=20=20=20=20=20=20=20=20=20(car=20= subst)=0A+=20=20=20=20=20=20=20=20(error=20"Expanding=20rx=20def=20`%s':=20= must=20result=20in=20a=20single=20value"=20op)))))=0A+=0A=20(defun=20= rx--translate-form=20(form)=0A=20=20=20"Translate=20an=20rx=20form=20= (list=20structure).=20=20Return=20(REGEXP=20.=20PRECEDENCE)."=0A=20=20=20= (let=20((body=20(cdr=20form)))=0A@@=20-757,24=20+876,29=20@@=20= rx--translate-form=0A=20=20=20=20=20=20=20(op=0A=20=20=20=20=20=20=20=20= (unless=20(symbolp=20op)=0A=20=20=20=20=20=20=20=20=20=20(error=20"Bad=20= rx=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=20definition)=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=20= definition)=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'=20form=20definition:=20%s"=20op))=0A= +=0A+=20=20=20=20=20=20=20=20=20=20=20;;=20For=20compatibility=20with=20= old=20rx.=0A+=20=20=20=20=20=20=20=20=20=20=20(let=20((entry=20(assq=20= op=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=20entry))))=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=20= another=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)=20= rx-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=20further=20= down=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=20= entry)=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=0A-=20=20=20=20=20=20=20= ;;=20For=20compatibility=20with=20old=20rx.=0A-=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= (if=20(progn=0A-=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(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(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;;=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(assq=20(cdr=20= entry)=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;;=20Wrong=20type,=20try=20further=20down=20= the=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(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(cdr=20(memq=20= entry=20rx-constituents))))))=0A-=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= (rx--translate-compat-form=20(cdr=20entry)=20form)=0A-=20=20=20=20=20=20=20= =20=20=20=20(error=20"Unknown=20rx=20form=20`%s'"=20op)))))))=0A-=0A-;;=20= Defined=20here=20rather=20than=20in=20re-builder=20to=20lower=20the=20= odds=20that=20it=0A-;;=20will=20be=20kept=20in=20sync=20with=20changes.=0A= =20(defconst=20rx--builtin-forms=0A=20=20=20'(seq=20sequence=20:=20and=20= or=20|=20any=20in=20char=20not-char=20not=0A=20=20=20=20=20repeat=20=3D=20= >=3D=20**=0A@@=20-786,7=20+910,21=20@@=20rx--builtin-forms=0A=20=20=20=20= =20group=20submatch=20group-n=20submatch-n=20backref=0A=20=20=20=20=20= syntax=20not-syntax=20category=0A=20=20=20=20=20literal=20eval=20regexp=20= regex)=0A-=20=20"List=20of=20built-in=20rx=20forms.=20=20For=20use=20in=20= re-builder=20only.")=0A+=20=20"List=20of=20built-in=20rx=20function-like=20= symbols.")=0A+=0A+(defconst=20rx--builtin-symbols=0A+=20=20(append=20= '(nonl=20not-newline=20any=20anything=0A+=20=20=20=20=20=20=20=20=20=20=20= =20bol=20eol=20line-start=20line-end=0A+=20=20=20=20=20=20=20=20=20=20=20= =20bos=20eos=20string-start=20string-end=0A+=20=20=20=20=20=20=20=20=20=20= =20=20bow=20eow=20word-start=20word-end=0A+=20=20=20=20=20=20=20=20=20=20= =20=20symbol-start=20symbol-end=0A+=20=20=20=20=20=20=20=20=20=20=20=20= point=20word-boundary=20not-word-boundary=20not-wordchar)=0A+=20=20=20=20= =20=20=20=20=20=20(mapcar=20#'car=20rx--char-classes))=0A+=20=20"List=20= of=20built-in=20rx=20variable-like=20symbols.")=0A+=0A+(defconst=20= rx--builtin-names=0A+=20=20(append=20rx--builtin-forms=20= rx--builtin-symbols)=0A+=20=20"List=20of=20built-in=20rx=20names.=20=20= These=20cannot=20be=20redefined=20by=20the=20user.")=0A=20=0A=20(defun=20= rx--translate=20(item)=0A=20=20=20"Translate=20the=20rx-expression=20= ITEM.=20=20Return=20(REGEXP=20.=20PRECEDENCE)."=0A@@=20-810,7=20+948,9=20= @@=20rx-to-string=0A=20The=20arguments=20to=20`literal'=20and=20`regexp'=20= forms=20inside=20FORM=20must=20be=0A=20constant=20strings.=0A=20If=20= NO-GROUP=20is=20non-nil,=20don't=20bracket=20the=20result=20in=20a=20= non-capturing=0A-group."=0A+group.=0A+=0A+For=20extending=20the=20`rx'=20= notation=20in=20FORM,=20use=20`rx-define'=20or=20`rx-let-eval'."=0A=20=20= =20(let*=20((item=20(rx--translate=20form))=0A=20=20=20=20=20=20=20=20=20= =20(exprs=20(if=20no-group=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(car=20item)=0A@@=20-939,14=20+1079,133=20@@=20rx=0A=20= (regexp=20EXPR)=20=20Match=20the=20string=20regexp=20from=20evaluating=20= EXPR=20at=20run=20time.=0A=20(eval=20EXPR)=20=20=20=20Match=20the=20rx=20= sexp=20from=20evaluating=20EXPR=20at=20compile=20time.=0A=20=0A= +Additional=20constructs=20can=20be=20defined=20using=20`rx-define'=20= and=20`rx-let',=0A+which=20see.=0A+=0A=20\(fn=20REGEXPS...)"=0A-=20=20= (rx--to-expr=20(cons=20'seq=20regexps)))=0A+=20=20;;=20Retrieve=20local=20= definitions=20from=20the=20macroexpansion=20environment.=0A+=20=20;;=20= (It's=20unclear=20whether=20the=20previous=20value=20of=20= `rx--local-definitions'=0A+=20=20;;=20should=20be=20included,=20and=20if=20= so,=20in=20which=20order.)=0A+=20=20(let=20((rx--local-definitions=0A+=20= =20=20=20=20=20=20=20=20(cdr=20(assq=20:rx-locals=20= macroexpand-all-environment))))=0A+=20=20=20=20(rx--to-expr=20(cons=20= 'seq=20regexps))))=0A+=0A+(defun=20rx--make-binding=20(name=20tail)=0A+=20= =20"Make=20a=20definitions=20entry=20out=20of=20TAIL.=0A+TAIL=20is=20on=20= the=20form=20([ARGLIST]=20DEFINITION)."=0A+=20=20(unless=20(symbolp=20= name)=0A+=20=20=20=20(error=20"Bad=20`rx'=20definition=20name:=20%S"=20= name))=0A+=20=20;;=20FIXME:=20Consider=20using=20a=20hash=20table=20or=20= symbol=20property,=20for=20speed.=0A+=20=20(when=20(memq=20name=20= rx--builtin-names)=0A+=20=20=20=20(error=20"Cannot=20redefine=20built-in=20= rx=20name=20`%s'"=20name))=0A+=20=20(pcase=20tail=0A+=20=20=20=20= (`(,def)=0A+=20=20=20=20=20(list=20def))=0A+=20=20=20=20(`(,args=20,def)=0A= +=20=20=20=20=20(unless=20(and=20(listp=20args)=20(rx--every=20#'symbolp=20= args))=0A+=20=20=20=20=20=20=20(error=20"Bad=20argument=20list=20for=20= `rx'=20definition=20%s:=20%S"=20name=20args))=0A+=20=20=20=20=20(list=20= args=20def))=0A+=20=20=20=20(_=20(error=20"Bad=20`rx'=20definition=20of=20= %s:=20%S"=20name=20tail))))=0A+=0A+(defun=20rx--make-named-binding=20= (bindspec)=0A+=20=20"Make=20a=20definitions=20entry=20out=20of=20= BINDSPEC.=0A+BINDSPEC=20is=20on=20the=20form=20(NAME=20[ARGLIST]=20= DEFINITION)."=0A+=20=20(unless=20(consp=20bindspec)=0A+=20=20=20=20= (error=20"Bad=20`rx-let'=20binding:=20%S"=20bindspec))=0A+=20=20(cons=20= (car=20bindspec)=0A+=20=20=20=20=20=20=20=20(rx--make-binding=20(car=20= bindspec)=20(cdr=20bindspec))))=0A+=0A+(defun=20rx--extend-local-defs=20= (bindspecs)=0A+=20=20(append=20(mapcar=20#'rx--make-named-binding=20= bindspecs)=0A+=20=20=20=20=20=20=20=20=20=20rx--local-definitions))=0A=20= =0A+;;;###autoload=0A+(defmacro=20rx-let-eval=20(bindings=20&rest=20= body)=0A+=20=20"Evaluate=20BODY=20with=20local=20BINDINGS=20for=20= `rx-to-string'.=0A+BINDINGS,=20after=20evaluation,=20is=20a=20list=20of=20= definitions=20each=20on=20the=20form=0A+(NAME=20[(ARGS...)]=20RX),=20in=20= effect=20for=20calls=20to=20`rx-to-string'=0A+in=20BODY.=0A+=0A+For=20= bindings=20without=20an=20ARGS=20list,=20NAME=20is=20defined=20as=20an=20= alias=0A+for=20the=20`rx'=20expression=20RX.=20=20Where=20ARGS=20is=20= supplied,=20NAME=20is=0A+defined=20as=20an=20`rx'=20form=20with=20ARGS=20= as=20argument=20list.=20=20The=0A+parameters=20are=20bound=20from=20the=20= values=20in=20the=20(NAME=20...)=20form=20and=0A+are=20substituted=20in=20= RX.=20=20ARGS=20can=20contain=20`&rest'=20parameters,=0A+whose=20values=20= are=20spliced=20into=20RX=20where=20the=20parameter=20name=20occurs.=0A+=0A= +Any=20previous=20definitions=20with=20the=20same=20names=20are=20= shadowed=20during=0A+the=20expansion=20of=20BODY=20only.=0A+For=20= extensions=20when=20using=20the=20`rx'=20macro,=20use=20`rx-let'.=0A+To=20= make=20global=20rx=20extensions,=20use=20`rx-define'.=0A+For=20more=20= details,=20see=20Info=20node=20`(elisp)=20Extending=20Rx'.=0A+=0A+\(fn=20= BINDINGS=20BODY...)"=0A+=20=20(declare=20(indent=201)=20(debug=20(form=20= body)))=0A+=20=20;;=20FIXME:=20this=20way,=20`rx--extend-local-defs'=20= may=20need=20to=20be=20autoloaded.=0A+=20=20`(let=20= ((rx--local-definitions=20(rx--extend-local-defs=20,bindings)))=0A+=20=20= =20=20=20,@body))=0A+=0A+;;;###autoload=0A+(defmacro=20rx-let=20= (bindings=20&rest=20body)=0A+=20=20"Evaluate=20BODY=20with=20local=20= BINDINGS=20for=20`rx'.=0A+BINDINGS=20is=20an=20unevaluated=20list=20of=20= bindings=20each=20on=20the=20form=0A+(NAME=20[(ARGS...)]=20RX).=0A+They=20= are=20bound=20lexically=20and=20are=20available=20in=20`rx'=20= expressions=20in=0A+BODY=20only.=0A+=0A+For=20bindings=20without=20an=20= ARGS=20list,=20NAME=20is=20defined=20as=20an=20alias=0A+for=20the=20`rx'=20= expression=20RX.=20=20Where=20ARGS=20is=20supplied,=20NAME=20is=0A= +defined=20as=20an=20`rx'=20form=20with=20ARGS=20as=20argument=20list.=20= =20The=0A+parameters=20are=20bound=20from=20the=20values=20in=20the=20= (NAME=20...)=20form=20and=0A+are=20substituted=20in=20RX.=20=20ARGS=20= can=20contain=20`&rest'=20parameters,=0A+whose=20values=20are=20spliced=20= into=20RX=20where=20the=20parameter=20name=20occurs.=0A+=0A+Any=20= previous=20definitions=20with=20the=20same=20names=20are=20shadowed=20= during=0A+the=20expansion=20of=20BODY=20only.=0A+For=20local=20= extensions=20to=20`rx-to-string',=20use=20`rx-let-eval'.=0A+To=20make=20= global=20rx=20extensions,=20use=20`rx-define'.=0A+For=20more=20details,=20= see=20Info=20node=20`(elisp)=20Extending=20Rx'.=0A+=0A+\(fn=20BINDINGS=20= BODY...)"=0A+=20=20(declare=20(indent=201)=20(debug=20(sexp=20body)))=0A= +=20=20(let=20((prev-locals=20(cdr=20(assq=20:rx-locals=20= macroexpand-all-environment)))=0A+=20=20=20=20=20=20=20=20(new-locals=20= (mapcar=20#'rx--make-named-binding=20bindings)))=0A+=20=20=20=20= (macroexpand-all=20(cons=20'progn=20body)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(cons=20(cons=20:rx-locals=20(append=20= new-locals=20prev-locals))=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=20macroexpand-all-environment))))=0A+=0A= +;;;###autoload=0A+(defmacro=20rx-define=20(name=20&rest=20definition)=0A= +=20=20"Define=20NAME=20as=20a=20global=20`rx'=20definition.=0A+If=20the=20= ARGS=20list=20is=20omitted,=20define=20NAME=20as=20an=20alias=20for=20= the=20`rx'=0A+expression=20RX.=0A+=0A+If=20the=20ARGS=20list=20is=20= supplied,=20define=20NAME=20as=20an=20`rx'=20form=20with=0A+ARGS=20as=20= argument=20list.=20=20The=20parameters=20are=20bound=20from=20the=20= values=0A+in=20the=20(NAME=20...)=20form=20and=20are=20substituted=20in=20= RX.=0A+ARGS=20can=20contain=20`&rest'=20parameters,=20whose=20values=20= are=20spliced=0A+into=20RX=20where=20the=20parameter=20name=20occurs.=0A= +=0A+Any=20previous=20global=20definition=20of=20NAME=20is=20overwritten=20= with=20the=20new=20one.=0A+To=20make=20local=20rx=20extensions,=20use=20= `rx-let'=20for=20`rx',=0A+`rx-let-eval'=20for=20`rx-to-string'.=0A+For=20= more=20details,=20see=20Info=20node=20`(elisp)=20Extending=20Rx'.=0A+=0A= +\(fn=20NAME=20[(ARGS...)]=20RX)"=0A+=20=20(declare=20(indent=201))=0A+=20= =20`(eval-and-compile=0A+=20=20=20=20=20(put=20',name=20'rx-definition=20= ',(rx--make-binding=20name=20definition))=0A+=20=20=20=20=20',name))=0A=20= =0A=20;;=20During=20`rx--pcase-transform',=20list=20of=20defined=20= variables=20in=20right-to-left=0A=20;;=20order.=0A=20(defvar=20= rx--pcase-vars)=0A=20=0A+;;=20FIXME:=20The=20rewriting=20strategy=20for=20= pcase=20works=20so-so=20with=20extensions;=0A+;;=20definitions=20cannot=20= expand=20to=20`let'=20or=20named=20`backref'.=20=20If=20this=20ever=0A= +;;=20becomes=20a=20problem,=20we=20can=20handle=20those=20forms=20in=20= the=20ordinary=20parser,=0A+;;=20using=20a=20dynamic=20variable=20for=20= activating=20the=20augmented=20forms.=0A+=0A=20(defun=20= rx--pcase-transform=20(rx)=0A=20=20=20"Transform=20RX,=20an=20= rx-expression=20augmented=20with=20`let'=20and=20named=20`backref',=0A=20= into=20a=20plain=20rx-expression,=20collecting=20names=20into=20= `rx--pcase-vars'."=0Adiff=20--git=20a/test/lisp/emacs-lisp/rx-tests.el=20= b/test/lisp/emacs-lisp/rx-tests.el=0Aindex=20fec046dd99..11de4771de=20= 100644=0A---=20a/test/lisp/emacs-lisp/rx-tests.el=0A+++=20= b/test/lisp/emacs-lisp/rx-tests.el=0A@@=20-303,6=20+303,104=20@@=20= rx-to-string=0A=20=20=20(should=20(equal=20(rx-to-string=20'(or=20nonl=20= "\nx")=20t)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ".\\|\nx")))=0A=20=0A+(ert-deftest=20rx-let=20()=0A+=20=20(rx-let=20= ((beta=20gamma)=0A+=20=20=20=20=20=20=20=20=20=20=20(gamma=20delta)=0A+=20= =20=20=20=20=20=20=20=20=20=20(delta=20(+=20digit))=0A+=20=20=20=20=20=20= =20=20=20=20=20(epsilon=20(or=20gamma=20nonl)))=0A+=20=20=20=20(should=20= (equal=20(rx=20bol=20delta=20epsilon)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20"^[[:digit:]]+\\(?:[[:digit:]]+\\|.\\)")))=0A+=20= =20(rx-let=20((p=20()=20point)=0A+=20=20=20=20=20=20=20=20=20=20=20= (separated=20(x=20sep)=20(seq=20x=20(*=20sep=20x)))=0A+=20=20=20=20=20=20= =20=20=20=20=20(comma-separated=20(x)=20(separated=20x=20","))=0A+=20=20=20= =20=20=20=20=20=20=20=20(semi-separated=20(x)=20(separated=20x=20";"))=0A= +=20=20=20=20=20=20=20=20=20=20=20(matrix=20(v)=20(semi-separated=20= (comma-separated=20v))))=0A+=20=20=20=20(should=20(equal=20(rx=20(p)=20= (matrix=20(+=20"a"))=20eos)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20"\\=3Da+\\(?:,a+\\)*\\(?:;a+\\(?:,a+\\)*\\)*\\'")))=0A+=20= =20(rx-let=20((b=20bol)=0A+=20=20=20=20=20=20=20=20=20=20=20(z=20"B")=0A= +=20=20=20=20=20=20=20=20=20=20=20(three=20(x)=20(=3D=203=20x)))=0A+=20=20= =20=20(rx-let=20((two=20(x)=20(seq=20x=20x))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20(z=20"A")=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(e=20= eol))=0A+=20=20=20=20=20=20(should=20(equal=20(rx=20b=20(two=20(three=20= z))=20e)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "^A\\{3\\}A\\{3\\}$"))))=0A+=20=20(rx-let=20((f=20(a=20b=20&rest=20r)=20= (seq=20"<"=20a=20";"=20b=20":"=20r=20">")))=0A+=20=20=20=20(should=20= (equal=20(rx=20bol=20(f=20?x=20?y)=20?!=20(f=20?u=20?v=20?w)=20?!=20(f=20= ?k=20?l=20?m=20?n)=20eol)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"^!!$")))=0A+=0A+=20=20;;=20Rest=20= parameters=20are=20expanded=20by=20splicing.=0A+=20=20(rx-let=20((f=20= (&rest=20r)=20(or=20bol=20r=20eol)))=0A+=20=20=20=20(should=20(equal=20= (rx=20(f=20"ab"=20nonl))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"^\\|ab\\|.\\|$")))=0A+=0A+=20=20;;=20Substitution=20is=20= done=20in=20number=20positions.=0A+=20=20(rx-let=20((stars=20(n)=20(=3D=20= n=20?*)))=0A+=20=20=20=20(should=20(equal=20(rx=20(stars=204))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"\\*\\{4\\}")))=0A+=0A+=20= =20;;=20Substitution=20is=20done=20inside=20dotted=20pairs.=0A+=20=20= (rx-let=20((f=20(x=20y=20z)=20(any=20x=20(y=20.=20z))))=0A+=20=20=20=20= (should=20(equal=20(rx=20(f=20?*=20?a=20?t))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20"[*a-t]")))=0A+=0A+=20=20;;=20Substitution=20= is=20done=20in=20the=20head=20position=20of=20forms.=0A+=20=20(rx-let=20= ((f=20(x)=20(x=20"a")))=0A+=20=20=20=20(should=20(equal=20(rx=20(f=20+))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"a+"))))=0A+=0A= +(ert-deftest=20rx-define=20()=0A+=20=20(rx-define=20rx--a=20(seq=20"x"=20= (opt=20"y")))=0A+=20=20(should=20(equal=20(rx=20bol=20rx--a=20eol)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"^xy?$"))=0A+=20=20= (rx-define=20rx--c=20(lb=20rb=20&rest=20stuff)=20(seq=20lb=20stuff=20= rb))=0A+=20=20(should=20(equal=20(rx=20bol=20(rx--c=20"<"=20">"=20rx--a=20= nonl)=20eol)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "^$"))=0A+=20=20(rx-define=20rx--b=20(*=20rx--a))=0A+=20=20(should=20= (equal=20(rx=20rx--b)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20"\\(?:xy?\\)*"))=0A+=20=20(rx-define=20rx--a=20"z")=0A+=20=20(should=20= (equal=20(rx=20rx--b)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20"z*")))=0A+=0A+(defun=20rx--test-rx-to-string-define=20()=0A+=20=20;;=20= `rx-define'=20won't=20expand=20to=20code=20inside=20`ert-deftest'=20= since=20we=20use=0A+=20=20;;=20`eval-and-compile'.=20=20Put=20it=20into=20= a=20defun=20as=20a=20workaround.=0A+=20=20(rx-define=20rx--d=20"Q")=0A+=20= =20(rx-to-string=20'(seq=20bol=20rx--d)=20t))=0A+=0A+(ert-deftest=20= rx-to-string-define=20()=0A+=20=20"Check=20that=20`rx-to-string'=20uses=20= definitions=20made=20by=20`rx-define'."=0A+=20=20(should=20(equal=20= (rx--test-rx-to-string-define)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"^Q")))=0A+=0A+(ert-deftest=20rx-let-define=20()=0A+=20=20= "Test=20interaction=20between=20`rx-let'=20and=20`rx-define'."=0A+=20=20= (rx-define=20rx--e=20"one")=0A+=20=20(rx-define=20rx--f=20"eins")=0A+=20=20= (rx-let=20((rx--e=20"two"))=0A+=20=20=20=20(should=20(equal=20(rx=20= rx--e=20nonl=20rx--f)=20"two.eins"))=0A+=20=20=20=20(rx-define=20rx--e=20= "three")=0A+=20=20=20=20(should=20(equal=20(rx=20rx--e)=20"two"))=0A+=20=20= =20=20(rx-define=20rx--f=20"zwei")=0A+=20=20=20=20(should=20(equal=20(rx=20= rx--f)=20"zwei")))=0A+=20=20(should=20(equal=20(rx=20rx--e=20nonl=20= rx--f)=20"three.zwei")))=0A+=0A+(ert-deftest=20rx-let-eval=20()=0A+=20=20= (rx-let-eval=20'((a=20(*=20digit))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(f=20(x=20&rest=20r)=20(seq=20x=20nonl=20r)))=0A+=20=20=20= =20(should=20(equal=20(rx-to-string=20'(seq=20a=20(f=20bow=20a=20?b))=20= t)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[[:digit:]]*\\<.[[:digit:]]*b"))))=0A+=0A+(ert-deftest=20= rx-redefine-builtin=20()=0A+=20=20(should-error=20(rx-define=20sequence=20= ()=20"x"))=0A+=20=20(should-error=20(rx-define=20sequence=20"x"))=0A+=20=20= (should-error=20(rx-define=20nonl=20()=20"x"))=0A+=20=20(should-error=20= (rx-define=20nonl=20"x"))=0A+=20=20(should-error=20(rx-let=20= ((punctuation=20()=20"x"))=20nil))=0A+=20=20(should-error=20(rx-let=20= ((punctuation=20"x"))=20nil))=0A+=20=20(should-error=20(rx-let-eval=20= '((not-char=20()=20"x"))=20nil))=0A+=20=20(should-error=20(rx-let-eval=20= '((not-char=20"x"))=20nil)))=0A=20=0A=20(ert-deftest=20rx-constituents=20= ()=0A=20=20=20(let=20((rx-constituents=0A--=20=0A2.21.0=20(Apple=20= Git-122)=0A=0A= --Apple-Mail=_ED516277-A780-48D5-ABD4-A7754848202D--