5 (defvar automata-never-fail (make-symbol "automata-never-fail"))
6 (defvar automata-state-var (make-symbol "automata-state"))
8 (defmacro automata (in-var start-tag &rest clauses)
9 (let* ((org-len (length clauses))
10 (org-graph (digraph-make org-len))
11 (tag-to-org-alist nil)
12 forest org-to-forest forest-to-org
17 (setq tag-to-org-alist (cons (cons (caar tmp) i) tag-to-org-alist)
23 (setq trans (cddr (cdar tmp)))
25 (setq j (cdr (assoc (cadr (car trans)) tag-to-org-alist)))
26 (digraph-add-edge org-graph i j)
27 (setq trans (cdr trans)))
30 ;;(error "%s" org-graph)
31 (setq tmp (digraph-split-as-forest org-graph)
33 org-to-forest (aref tmp 1)
34 forest-to-org (aref tmp 2))
49 (lambda (tr) (if (equal (cadr tr) next) (car tr) (natset-empty)))
52 (natset-enum (apply 'natset-single (mapcar 'cadr trs)))))
53 (cons tag (cons action (cons fail trs)))))
55 `(let ((,automata-state-var ,(cdr (assoc start-tag tag-to-org-alist))))
60 (list (cdr (assoc start-tag tag-to-org-alist)))
62 (aref org-to-forest (cdr (assoc start-tag tag-to-org-alist)))
63 forest org-to-forest forest-to-org)))))
65 (defun automata-gen-state (in-var clauses
69 forest-state forest org-to-forest forest-to-org)
70 (let* ((org-states (aref forest-to-org forest-state))
71 (forest-states (digraph-descents forest forest-state))
72 (branch-length (+ (length org-states) (length forest-states)))
75 (mapcar 'list org-states)
76 (mapcar (lambda (forest-state)
77 (aref forest-to-org forest-state))
80 (let ((org-to-branch (make-vector org-len nil))
82 (while (< i branch-length)
83 (setq tmp (aref branch-to-org i))
85 (aset org-to-branch (car tmp) i)
91 (make-list (length org-states) nil)
95 (mapcar 'natset-single org-states)
96 (mapcar (lambda (forest-state)
98 (aref forest-to-org forest-state)))
102 (mapcar (lambda (org-state)
103 (let* ((c (nth org-state clauses))
108 (cdr (assoc (cadr tr) tag-to-org-alist))))
111 (mapcar (lambda (forest-state) ())
113 (all-descents (apply 'natset-union (append branch-descents ())))
115 (let* ((branch-ascents (make-vector branch-length 0))
117 (while (< i branch-length)
119 (while (< j branch-length)
120 (if (natset-has-intersection-p (aref branch-state-range i)
121 (aref branch-descents j))
122 (aset branch-ascents i
123 (1+ (aref branch-ascents i))))
129 (let* ((branch-inline (make-vector branch-length nil))
130 (start-ns (apply 'natset-single start-states))
132 (while (< i branch-length)
133 (if (natset-has-intersection-p (aref branch-state-range i) start-ns)
134 (if (and (= (length start-states) 1)
135 (= (aref branch-ascents i) 0))
137 (setq start-inline i)
138 (aset branch-inline i t))
140 (if (= (aref branch-ascents i) 1)
141 (aset branch-inline i t)))
152 `(,(natset-single org-state)
153 nil ; don't duplicate.
154 ,@(let* ((c (nth org-state clauses)))
157 (if (null (nthcdr 3 c))
160 ,in-var ; input variable
161 ,(natset-full) ; input is unpredictable.
162 ,(nth 2 c) ; fail action
163 ,@(let ((trs (nthcdr 3 c)))
165 (lambda (next-branch)
170 (if (member (cdr (assoc (cadr tr) tag-to-org-alist))
171 (aref branch-to-org next-branch))
175 `(,input-range ; input range
176 ,(not (aref branch-inline next-branch)) ; duplicatable unless inlining.
177 ,(let ((goto-list (apply
181 (let ((range (natset-intersection (car tr) input-range)))
188 ,(cdr (assoc (cadr tr) tag-to-org-alist)))))
191 (if (= (length goto-list) 1)
192 (car (cddr (car goto-list)))
198 ,@(if (aref branch-inline next-branch)
200 `(progn ,@(cddr (funcall (car (aref branch-gen next-branch))
201 (cdr (aref branch-gen next-branch))))))
209 (cdr (assoc (cadr tr) tag-to-org-alist)))))
215 (lambda (forest-state)
217 (lambda (forest-state)
218 `(,(natset-intersection
219 (apply 'natset-single (aref forest-to-org forest-state))
220 all-descents) ; state range
221 nil ; don't duplicate.
226 (aref forest-to-org forest-state)
228 forest-state forest org-to-forest forest-to-org))))
236 (if (not (aref branch-inline i))
239 (funcall (car (aref branch-gen i))
240 (cdr (aref branch-gen i)))
248 `(progn ,@(cddr (funcall (car (aref branch-gen start-inline))
249 (cdr (aref branch-gen start-inline)))))
252 ((null (cdr branches))
253 (cddr (car branches)))
257 ,automata-state-var ,(natset-full) ,automata-never-fail
259 (if (= (length branches) 1)
260 `(while t ,@(cddr (car branches)))
261 `(while t ; ,branch-inline ,branch-state-range ,branch-descents ,branch-ascents
263 ,automata-state-var ,(natset-full) ,automata-never-fail
266 (defun automata-seq-exp (&rest seq)
276 (lambda (exp) (if (and (consp exp) (eq (car exp) 'progn))
280 (let ((rseq (reverse seq)))
287 (lambda (exp) (if (null exp) () (list exp)))
288 (nreverse (cdr rseq))))
289 (list (list (car rseq)))))))))
291 (defun automata-exp-seq (&rest seq)
292 (let ((exp (apply 'automata-seq-exp seq)))
293 (if (and (consp exp) (eq (car exp) 'progn))
297 (defmacro automata-goto (var curr next)
302 (defmacro automata-branch (var range fail &rest clauses)
303 (when (eq fail automata-never-fail)
304 (setq range (natset-intersection
305 (apply 'natset-union (mapcar 'car clauses))
307 (let ((len (length clauses))
308 ns-list dup-list body-list tmp ns)
310 ns (natset-negate range))
312 (setq ns-list (cons (natset-sub (caar tmp) ns) ns-list)
313 dup-list (cons (cadr (car tmp)) dup-list)
314 body-list (cons (cddr (car tmp)) body-list)
315 ns (natset-union ns (caar tmp))
317 (if (natset-empty-p (car ns-list))
318 (setq ns-list (cdr ns-list)
319 dup-list (cdr dup-list)
320 body-list (cdr body-list))))
321 (setq ns-list (nreverse ns-list)
322 dup-list (nreverse dup-list)
323 body-list (nreverse body-list))
324 (automata-branch-i var range fail ns-list dup-list body-list)))
326 (defun automata-branch-i (var range fail ns-list dup-list body-list)
328 ((null ns-list) fail)
329 ((null (cdr ns-list))
330 (if (natset-include-p (car ns-list) range)
331 (apply 'automata-seq-exp (car body-list))
332 `(if ,(natset-gen-pred-exp (car ns-list) var range)
333 ,(apply 'automata-seq-exp (car body-list))
336 (let (tmp tmpn tmpd cut)
340 (setq cut (natset-union cut (natset-boundary-set (car tmpn)))
346 (setq tmp (natset-minmax (car tmpn))
347 tmp (natset-sub tmp (natset-start-set tmp))
348 cut (natset-sub cut tmp)))
349 (setq tmpn (cdr tmpn)
351 (setq cut (natset-sub cut (natset-boundary-set (natset-minmax range))))
352 (if (null (setq cut (natset-enum cut)))
353 `(if ,(natset-gen-pred-exp (car ns-list) var range)
354 ,(apply 'automata-seq-exp (car body-list))
355 ,(automata-branch-i var
356 (natset-sub range (car ns-list))
361 (let* ((mid (nth (/ (length cut) 2) cut))
362 (lower (natset-seg 0 (1- mid)))
363 (higher (natset-seg mid))
364 ns-list1 dup-list1 body-list1
365 ns-list2 dup-list2 body-list2
368 (if (natset-has-intersection-p lower (car ns-list))
369 (setq ns-list1 (cons (natset-intersection (car ns-list) lower) ns-list1)
370 dup-list1 (cons (car dup-list) dup-list1)
371 body-list1 (cons (car body-list) body-list1)))
372 (if (natset-has-intersection-p higher (car ns-list))
373 (setq ns-list2 (cons (natset-intersection (car ns-list) higher) ns-list2)
374 dup-list2 (cons (car dup-list) dup-list2)
375 body-list2 (cons (car body-list) body-list2)))
376 (setq ns-list (cdr ns-list)
377 dup-list (cdr dup-list)
378 body-list (cdr body-list)))
379 ;;(if (or (null ns-list1) (null ns-list2)) (error "divide fail"))
381 ,(automata-branch-i var
382 (natset-intersection range lower)
383 fail ns-list1 dup-list1 body-list1)
384 ,(automata-branch-i var
385 (natset-intersection range higher)
386 fail ns-list2 dup-list2 body-list2))))))))
395 (lex-scan-unibyte-save))
400 (lex-scan-unibyte-save))
404 (lex-scan-unibyte-read pc))
406 ((9 10) 5) ((32 33) 5))
410 (lex-scan-unibyte-save)
411 (lex-scan-unibyte-read pc))
414 ((0 9) 3) ((11 13) 3) ((14 32) 3) ((33) 3)
419 (lex-scan-unibyte-save)
420 (lex-scan-unibyte-read pc))
422 ((0 9) 3) ((10 11) 3) ((11 13) 3) ((14 32) 3) ((33) 3)
428 (lex-scan-unibyte-save)
429 (lex-scan-unibyte-read pc))
431 ((0 9) 3) ((10 11) 3) ((11 13) 3) ((14 32) 3) ((33) 3)
433 ((9 10) 1) ((32 33) 1)))))
440 (lex-scan-unibyte-save)
441 (lex-scan-unibyte-read pc))
443 ((0 9) 3) ((10 11) 3) ((11 13) 3) ((14 32) 3) ((33) 3)
445 ((9 10) 1) ((32 33) 1))
449 (lex-scan-unibyte-save))
454 (lex-scan-unibyte-save)
455 (lex-scan-unibyte-read pc))
458 ((0 9) 3) ((11 13) 3) ((14 32) 3) ((33) 3)
463 (lex-scan-unibyte-save)
464 (lex-scan-unibyte-read pc))
466 ((0 9) 3) ((10 11) 3) ((11 13) 3) ((14 32) 3) ((33) 3)
471 (lex-scan-unibyte-read pc))
473 ((9 10) 5) ((32 33) 5))
477 (lex-scan-unibyte-save))
484 '((0 (progn (lex-match 3) (lex-scan-unibyte-save) (lex-scan-unibyte-read pc)) (lex-fail) ((9 10 32 33) 1) ((13 14) 2) ((0 9 10 13 14 32 33) 3))
485 (1 (progn (lex-match 1) (lex-scan-unibyte-save)) (lex-fail))
486 (2 (progn (lex-match 3) (lex-scan-unibyte-save) (lex-scan-unibyte-read pc)) (lex-fail) ((13 14) 2) ((0 9 11 13 14 32 33) 3) ((10 11) 4))
487 (3 (progn (lex-match 3) (lex-scan-unibyte-save) (lex-scan-unibyte-read pc)) (lex-fail) ((13 14) 2) ((0 9 10 13 14 32 33) 3))
488 (4 (progn (lex-scan-unibyte-read pc)) (lex-fail) ((9 10 32 33) 5))
489 (5 (progn (lex-match 2) (lex-scan-unibyte-save)) (lex-fail)))
492 '((5 . 5) (4 . 4) (3 . 3) (2 . 2) (1 . 1) (0 . 0))
494 [(4 1) (2) (3) nil nil]
496 [(0) (3 2) (4) (5) (1)]))