emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Removing no-back-reference restriction from syntax-propertize-rules


From: Tassilo Horn
Subject: Re: Removing no-back-reference restriction from syntax-propertize-rules
Date: Mon, 18 May 2020 20:20:50 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Stefan Monnier <address@hidden> writes:

>> -(defun syntax-propertize--shift-groups (re n)
>> -  (replace-regexp-in-string
>> -   "\\\\(\\?\\([0-9]+\\):"
>> -   (lambda (s)
>> -     (replace-match
>> -      (number-to-string (+ n (string-to-number (match-string 1 s))))
>> -      t t s 1))
>> -   re t t))
>> +(defun syntax-propertize--shift-groups-and-backrefs (re n)
>> +  (let ((incr (lambda (s)
>> +                (replace-match
>> +                 (number-to-string
>> +                  (+ n (string-to-number (match-string 1 s))))
>> +                 t t s 1))))
>> +    (replace-regexp-in-string
>> +     "[^\\]\\\\\\([0-9]+\\)" incr
>> +     (replace-regexp-in-string "\\\\(\\?\\([0-9]+\\):" incr re t t)
>> +     t t)))
>
> I think it's OK, but I think the risk of false positives for `\N` is
> sufficiently high (compared to that for `\(?N:`)

Can you give an example regexp where \N preceeded by a non-\ is no
back-reference (and still valid)?

BTW, do I read the docs right in that there are at most nine
back-references, i.e., \10 cannot exist?  In that case, we'd have the
restriction that at most 9 back-references may appear in all syntax
rules.  I guess in that case we should signal an error, no?

> that I think we need to be more careful and use `subregexp-context-p`.

I'm not sure how to use that.  Do you mean something like this?

--8<---------------cut here---------------start------------->8---
(defun syntax-propertize--shift-groups-and-backrefs (re n)
  (let ((new-re (replace-regexp-in-string
                 "\\\\(\\?\\([0-9]+\\):"
                 (lambda (s)
                   (replace-match
                    (number-to-string
                     (+ n (string-to-number (match-string 1 s))))
                    t t s 1))
                 re t t))
        (pos 0))
    (while (string-match "\\\\\\([0-9]+\\)" new-re pos)
      (setq pos (+ 1 (match-beginning 1)))
      (when (save-match-data
              ;; With \N, the \ must be in a subregexp context and the
              ;; N must not be in a subregexp context.
              (and (subregexp-context-p new-re (match-beginning 0))
                   (not (subregexp-context-p new-re (match-beginning 1)))))
        (setq new-re (replace-match
                      (number-to-string
                       (+ n (string-to-number (match-string 1 new-re))))
                      t t new-re 1))))
    new-re))
--8<---------------cut here---------------end--------------->8---

That doesn't shift/renumber things like [\N] or fo\{\N\} but are those
valid regexps anyway?

Bye,
Tassilo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]