[Mew-dist 14542] Re: incdir Re: b68
Yoshinari Nomura
nom at example.com
2000年 10月 14日 (土) 10:56:28 JST
ごぶさたしています。乃村です。
On Fri, 13 Oct 2000 11:23:38 +0900,
Kazu Yamamoto (山本和彦) <kazu at example.com> said:
> 来週中に beta に復帰したいなぁ。(Pick の pattern が難関だぁ。コンパイ
> ラ勉強中。)
mhc で、カテゴリの検索式を parse するために、parser もどきを
作ったので、もし役に立つなら使ってあげてください。
よくある再帰下降型 (っていうだっけ?) の paerser です。
(mew-expr-parse "(subject != mew-dist || from = nom) && to = kazu")
とやると、
(and
(or (not (xxx-my-search-in-buffer "subject" "mew-dist"))
(xxx-my-search-in-buffer "from" "nom"))
(xxx-my-search-in-buffer "to" "kazu"))
のような S式を吐きます。mew-expr-compile で bytecompile してくれます。
xxx-my-search-in-buffer を適当な値に変更すると使えるのではないかと。
# もしかして、そういう意味ではないのかしら?
--
nom
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; lexical analyzer part for category.
;;
(defsubst mew-expr/new ()
(vector nil nil nil nil))
(defsubst mew-expr/token (expr-obj) ;; literal
(aref expr-obj 0))
(defsubst mew-expr/token-type (expr-obj) ;; symbolized
(aref expr-obj 1))
(defsubst mew-expr/string (expr-obj) ;; currently parsing string.
(aref expr-obj 2))
(defsubst mew-expr/set-token (expr-obj val)
(aset expr-obj 0 val))
(defsubst mew-expr/set-token-type (expr-obj val)
(aset expr-obj 1 val))
(defsubst mew-expr/set-string (expr-obj val)
(aset expr-obj 2 val))
;; keep the order of elements for first matching !!
(defconst mew-expr-token-type-alist
'(
("[^=!&|()\t \n]+" . symbol)
("!=" . neqop)
("=" . eqop)
("!" . negop)
("&&" . andop)
("||" . orop)
("(" . lparen)
(")" . rparen)))
;; Eat one token from parsing string in obj.
(defun mew-expr/gettoken (obj)
(let ((string (mew-expr/string obj))
(token-alist mew-expr-token-type-alist)
(token-type nil)
(token nil))
;; delete leading white spaces.
(if (string-match "^[\t ]+" string)
(setq string (substring string (match-end 0))))
(while (and token-alist (not token-type))
(if (string-match (concat "^" (car (car token-alist))) string)
(setq token (substring string 0 (match-end 0))
string (substring string (match-end 0))
token-type (cdr (car token-alist))))
(setq token-alist (cdr token-alist)))
(mew-expr/set-token obj token)
(mew-expr/set-string obj string)
(mew-expr/set-token-type obj token-type)
obj))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; recursive descent parser
;;
;;
;; expression -> term ("||" term)*
;;
(defun mew-expr/expression (obj)
(let ((ret (list (mew-expr/term obj))))
(while (eq (mew-expr/token-type obj) 'orop)
(mew-expr/gettoken obj)
(setq ret (cons (mew-expr/term obj) ret)))
(if (= 1 (length ret))
(car ret)
(cons 'or (nreverse ret)))))
;;
;; term -> factor ("&&" factor)*
;;
(defun mew-expr/term (obj)
(let ((ret (list (mew-expr/factor obj))))
(while (eq (mew-expr/token-type obj) 'andop)
(mew-expr/gettoken obj)
(setq ret (cons (mew-expr/factor obj) ret)))
(if (= 1 (length ret))
(car ret)
(cons 'and (nreverse ret)))))
;;
;; factor -> "!"* xxx "!"?"=" yyy || "(" expression ")"
;;
(defun mew-expr/factor (obj)
(let ((ret)
(neg-flag nil)
(not-flag nil))
(while (eq (mew-expr/token-type obj) 'negop)
(setq neg-flag (not neg-flag))
(mew-expr/gettoken obj))
(cond
;; symbol != symbol, symbol = symbol
((eq (mew-expr/token-type obj) 'symbol)
(setq ret (list 'xxx-my-search-in-buffer (mew-expr/token obj)))
(mew-expr/gettoken obj)
(cond
((eq (mew-expr/token-type obj) 'eqop)
(setq not-flag nil))
((eq (mew-expr/token-type obj) 'neqop)
(setq not-flag t))
(t
(error "Syntax Error")))
(mew-expr/gettoken obj)
(if (eq (mew-expr/token-type obj) 'symbol)
(setq ret (append ret (list (mew-expr/token obj))))
(error "Syntax Error"))
(if not-flag
(setq ret (list 'not ret)))
(mew-expr/gettoken obj))
;; ( expression )
((eq (mew-expr/token-type obj) 'lparen)
(mew-expr/gettoken obj)
(setq ret (mew-expr/expression obj))
(if (not (eq (mew-expr/token-type obj) 'rparen))
(error "Syntax error."))
(mew-expr/gettoken obj))
;; error
(t
(error "Syntax error.")
;; (error "Missing category name or `(' %s %s"
;; mew-expr-token mew-expr-parsing-string)
))
(if neg-flag (list 'not ret) ret)))
(defun mew-expr-parse (string)
(let ((obj (mew-expr/new)) (ret nil))
(if (or (not string) (string= string ""))
t
(mew-expr/set-string obj string)
(mew-expr/gettoken obj)
(setq ret (mew-expr/expression obj))
(if (mew-expr/token obj)
(error "Syntax Error.")
ret))))
(defun mew-expr-compile (string)
(byte-compile
`(lambda ()
,(mew-expr-parse string)
)))
Mew-dist メーリングリストの案内