2010年3月17日水曜日

NFAの状態遷移図をcl-dotで描画する

正規表現からNFAへ変換処理をデバッグするときに、NFAの状態遷移図どのようになったかを知りたい。手書きするのも面倒くさくなってきたので、cl-dotで描画することにした。

NFAは前回の記事の形式であるとする。

cl-dotのノードや矢印に属性値を指定したい場合、元々のオブジェクトをattributedというクラスのオブジェクトでラップすれば良いようだ。

;;;nfaの遷移図を描画
(defparameter *table* nil)
(defparameter *f* nil)

(defun mklist (lst)
(if (listp lst) lst (list lst)))

(defmethod cl-dot:graph-object-node ((graph (eql 'nfa)) (key symbol))
(make-instance 'cl-dot:node
:attributes
(list :label (format nil "~A" key)
:shape :box
:fontname "Arial"
:style :filled
:fillcolor
(if (member key *f*)"#aaaaaa" "#ffffff")
:color :black)))

(defmethod cl-dot:graph-object-points-to ((graph (eql 'nfa)) (key symbol))
(let ((alist (gethash key *table*)))
(mapcan
#'(lambda (lst)
(mapcar
#'(lambda (next)
(make-instance 'cl-dot:attributed :object next
:attributes (list
:label (format nil "~A" (car lst))
:dir :forward)))
(cdr lst)))
alist)))

(defun run (nfa path &key (format :png))
(let ((*table* (nfa-table nfa))
(*f* (mklist (nfa-f nfa))))
(let ((graph (cl-dot:generate-graph-from-roots
'nfa
(list (nfa-start nfa)))))
(cl-dot:dot-graph graph path :format format))))

;;(run nfa
;; "/home/kurohuku/edit/lisp/graphic/nfa.png")

0 件のコメント:

コメントを投稿