正規表現から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 件のコメント:
コメントを投稿