Function: mh-index-parse-search-regexp

mh-index-parse-search-regexp is a byte-compiled function defined in mh-search.el.gz.

Signature

(mh-index-parse-search-regexp INPUT-STRING)

Documentation

Construct parse tree for INPUT-STRING.

All occurrences of &, |, ! and ~ in INPUT-STRING are replaced by AND, OR and NOT as appropriate. Then the resulting string is parsed.

Source Code

;; Defined in /usr/src/emacs/lisp/mh-e/mh-search.el.gz
(defun mh-index-parse-search-regexp (input-string)
  "Construct parse tree for INPUT-STRING.
All occurrences of &, |, ! and ~ in INPUT-STRING are replaced by
AND, OR and NOT as appropriate. Then the resulting string is
parsed."
  (let (input)
    (with-temp-buffer
      (insert input-string)
      ;; replace tabs
      (mh-replace-string "\t" " ")
      ;; synonyms of AND
      (mh-replace-string " AND " " and ")
      (mh-replace-string "&" " and ")
      (mh-replace-string " -and " " and ")
      ;; synonyms of OR
      (mh-replace-string " OR " " or ")
      (mh-replace-string "|" " or ")
      (mh-replace-string " -or " " or ")
      ;; synonyms of NOT
      (mh-replace-string " NOT " " not ")
      (mh-replace-string "!" " not ")
      (mh-replace-string "~" " not ")
      (mh-replace-string " -not " " not ")
      ;; synonyms of left brace
      (mh-replace-string "(" " ( ")
      (mh-replace-string " -lbrace " " ( ")
      ;; synonyms of right brace
      (mh-replace-string ")" " ) ")
      (mh-replace-string " -rbrace " " ) ")
      ;; get the normalized input
      (setq input (format "( %s )" (buffer-substring (point-min) (point-max)))))

    (let ((tokens (mh-index-add-implicit-ops (split-string input)))
          (op-stack ())
          (operand-stack ())
          oper1)
      (dolist (token tokens)
        (cond ((equal token "(") (push 'paren op-stack))
              ((equal token "not") (push 'not op-stack))
              ((equal token "or") (push 'or op-stack))
              ((equal token "and") (push 'and op-stack))
              ((equal token ")")
               (cl-multiple-value-setq (op-stack operand-stack)
                 (cl-values-list (mh-index-evaluate op-stack operand-stack)))
               (when (eq (car op-stack) 'not)
                 (setq op-stack (cdr op-stack))
                 (push `(not ,(pop operand-stack)) operand-stack))
               (when (eq (car op-stack) 'and)
                 (setq op-stack (cdr op-stack))
                 (setq oper1 (pop operand-stack))
                 (push `(and ,(pop operand-stack) ,oper1) operand-stack)))
              ((eq (car op-stack) 'not)
               (setq op-stack (cdr op-stack))
               (push `(not ,token) operand-stack)
               (when (eq (car op-stack) 'and)
                 (setq op-stack (cdr op-stack))
                 (setq oper1 (pop operand-stack))
                 (push `(and ,(pop operand-stack) ,oper1) operand-stack)))
              ((eq (car op-stack) 'and)
               (setq op-stack (cdr op-stack))
               (push `(and ,(pop operand-stack) ,token) operand-stack))
              (t (push token operand-stack))))
      (prog1 (pop operand-stack)
        (when (or op-stack operand-stack)
          (error "Invalid regexp: %s" input))))))