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
(defun rx--translate-or (body)
  "Translate an or-pattern of zero or more rx items.
Return (REGEXP . PRECEDENCE)."
  ;; FIXME: Possible improvements:
  ;;
  ;; - Flatten sub-patterns first: (or (or A B) (or C D)) -> (or A B C D)
  ;;   Then call regexp-opt on runs of string arguments. Example:
  ;;   (or (+ digit) "CHARLIE" "CHAN" (+ blank))
  ;;   -> (or (+ digit) (or "CHARLIE" "CHAN") (+ blank))
  ;;
  ;; - Optimize single-character alternatives better:
  ;;     * classes: space, alpha, ...
  ;;     * (syntax S), for some S (whitespace, word)
  ;;   so that (or "@" "%" digit (any "A-Z" space) (syntax word))
  ;;        -> (any "@" "%" digit "A-Z" space word)
  ;;        -> "[A-Z@%[:digit:][:space:][:word:]]"
  (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-or-arg body))
           (all-strings (catch 'rx--nonstring (rx--all-string-or-args args))))
      (cond
       (all-strings                       ; Only strings.
        (cons (list (regexp-opt all-strings nil))
              t))
       ((rx--every #'rx--charset-p args)  ; All charsets.
        (rx--translate-union nil args))
       (t
        (cons (append (car (rx--translate (car args)))
                      (mapcan (lambda (item)
                                (cons "\\|" (car (rx--translate item))))
                              (cdr args)))
              nil)))))))