Function: rx--translate-or
rx--translate-or is a byte-compiled function defined in rx.el.gz.
Signature
(rx--translate-or BODY)
Documentation
Translate an or-pattern of zero or more rx items.
Return (REGEXP . PRECEDENCE).
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/rx.el.gz
;; TODO: Write a more general rx-level factoriser to replace
;; `regexp-opt' for our purposes. It would handle non-literals:
;;
;; (or "ab" (: "a" space) "bc" (: "b" (+ digit)))
;; -> (or (: "a" (in "b" space)) (: "b" (or "c" (+ digit))))
;;
;; As a minor side benefit we would get less useless bracketing.
;; The main problem is how to deal with matching order, which `regexp-opt'
;; alters in its own way.
(defun rx--translate-or (body)
"Translate an or-pattern of zero or more rx items.
Return (REGEXP . PRECEDENCE)."
(cond
((null body) ; No items: a never-matching regexp.
(rx--empty))
((null (cdr body)) ; Single item.
(rx--translate (car body)))
(t
(let ((args (mapcar #'rx--normalise-char-pattern body)))
(if (rx--all-string-branches-p args)
;; All branches are strings: use `regexp-opt'.
(cons (list (regexp-opt (rx--collect-or-strings args) nil))
t)
(let ((form (rx--optimise-or-args args)))
(if (eq (car-safe form) 'or)
(let ((branches (cdr form)))
(cons (append (car (rx--translate (car branches)))
(mapcan (lambda (item)
(cons "\\|" (car (rx--translate item))))
(cdr branches)))
nil))
(rx--translate form))))))))