-
Notifications
You must be signed in to change notification settings - Fork 1
/
fsm-tools.el
102 lines (96 loc) · 3.17 KB
/
fsm-tools.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
;;; FSM XML MANIPULATING UTILS
(cl-defun sktl-extract-entries (fsm-xml &key raw-p)
"Return edges as (<state> . ( <in> <out> [ <next> [ <attribs> ] ] )+ )+"
(let (ret)
(cl-destructuring-bind (fsm1 fsm1-attribs . fsm1-rest)
fsm-xml
(cl-assert (eql fsm1 'fsm))
(dolist (ent fsm1-rest)
;; (e nil (s nil "INIT") (in nil "f") (out nil "R"))
(cl-destructuring-bind (e1 e1-attribs . e1-rest) ent
(if (eql e1 'e)
(dolist (state (sktl--parse-states (caddr (assoc 's e1-rest))))
(let* ((state (sktl--keywordify state))
(ent (or (assoc state ret)
(car (push (list state) ret))))
(in-raw (sktl--parse-string
(caddr (assoc 'in e1-rest))))
(in (if raw-p
in-raw
(apply #'string in-raw)))
(out-raw (sktl--parse-string
(caddr (assoc 'out e1-rest))))
(out (if raw-p
out-raw
(apply #'string out-raw)))
(next (sktl--parse-string
(cdddr (assoc 'next e1-rest)))))
(push (append (list in out)
(if e1-attribs (list next))
e1-attribs)
(cdr ent))))))))
ret))
(defun sktl-unkeywordify (symbol)
"Returns an UPCASE string without a leading colon"
(when symbol
(let ((name (upcase (if (symbolp symbol) (symbol-name symbol) symbol))))
(if (eq ?\: (aref name 0))
(cl-subseq name 1)
name))))
(defun sktl-dump-attribs (attribs)
(apply #'concat (cl-loop for (key . val) in attribs
collect (format "%s='%s'" key val))))
(defun sktl-maybe-dump-unicode (seq)
(cl-etypecase seq
(character (sktl-maybe-dump-unicode (list seq)))
(string (sktl-maybe-dump-unicode (cl-coerce seq 'list)))
(sequence
(with-output-to-string
(seq-doseq (c seq)
(if (characterp c)
(if (and (< c 128) (aref printable-chars c))
(write-char c)
(princ (format "\\u%04x" c)))
(progn
(cl-assert (eql (car c) :not))
(princ (format "/^([^"))
(seq-doseq (c (cdr c))
(if (char-equal c ?\\) (write-char c))
(write-char c))
(princ (format "])")))))))))
(defun sktl-dump-entries (entries start-state path)
(with-temp-buffer
(insert (format "<fsm start='%s'>\n" (sktl-unkeywordify start-state)))
(cl-loop for (state . rest) in entries
do
(cl-loop for (in out next . attribs) in rest
do
(insert "<e")
(when attribs
(insert " " (sktl-dump-attribs attribs)))
(insert ">")
(insert
(format " <s>%s</s> <in>%s</in> <out>%s</out>"
(sktl-unkeywordify start-state)
(sktl-maybe-dump-unicode in)
(sktl-maybe-dump-unicode out)))
(if next
(insert (format " <next>%s</next>"
(sktl-unkeywordify next)))
(insert " </e>\n"))))
(insert "</fsm>\n")
(write-region (point-min) (point-max) path)))
(when nil
(setq $from :slp1)
(setq $to :deva)
(setq $xml
(sktl--snarf-xml-file (sktl-get-transcoder-path $from $to $sktl-cat)))
(setq $a (sktl-extract-entries $xml :raw-p t))
(sktl-dump-entries $a :init (format "/dev/shm/%s_%s.xml"
(downcase (sktl-unkeywordify $from))
(downcase (sktl-unkeywordify $to))
))
(setq $s "S/^([^aAiIuUfFxXeEoO^/\\\\])")
(princ $s)
(pp (sktl-maybe-dump-unicode (sktl--parse-string $s)))
)