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))))))