[= AutoGen5 Template -*- Mode: text -*-
fsm=%s-att.fsm
=]
[=#
FSM-PURPOSE:
This template will produce an FSM description suitable for use with
the AT&T Research FSM tools. One of those programs will produce a
PostScript drawing and ps2pdf can be used to produce PDF output.
Use this something like as follows:
autogen -L ~/ag/autofsm -Tatt-fsm example.def
arcopt='-i example-att.arc -o example-att.arc'
fsmcompile ${arcopt} -S example-att.ste example-att.fsm | \
fsmdraw ${arcopt} -s example-att.ste > example.dot
dot -Tps example.dot > example.ps
ps2pdf example.ps example.pdf
The "/1" appearing in the output are default transition costs.
You can get different costs by specifying a cost attribute for
each transition. For example:
cost = 0.123;
This template is not part of the AutoGen distribution.
It is available within the separately downloadable package: AutoFSM.
YOU SUPPLY:
One additional attribute with the "transition" values: "cost".
Otherwise, all costs will default to "1".
\=]
[= (out-push-new (string-append (base-name) "-att.ste")) \=]
INIT 0
[=
FOR state
=][=
(sprintf "%-14s %d\n" (string-upcase! (get "state")) (+ 1 (for-index)))
=][=
ENDFOR state
\=]
DONE [= (+ 1 (count "state")) =]
[=
(out-pop) (out-push-new (string-append (base-name) "-att.arc"))
=][=
FOR event
=][=
(sprintf "%-14s %d\n" (string-upcase! (get "event")) (for-index))
=][=
ENDFOR
=][=
(out-pop)
;;; Initialize every possible transition as invalid
;;;
(define tr_name "")
(define pfx (string->c-name! (string-downcase!
(if (exist? "prefix") (get "prefix") (base-name)) )))
(define PFX (string-upcase pfx))
(define Pfx (string-capitalize pfx))
(shellf
"ev_list='%s' ; st_list='INIT %s'
for f in $ev_list ; do for g in $st_list
do eval FSM_TRANS_${g}_to_${f}='%s_ST_INVALID'
export FSM_TRANS_${g}_to_${f}
done ; done"
(string-upcase! (join " " (stack "event")))
(string-upcase! (join " " (stack "state")))
PFX )
(define tev "")
(define tst "")
(define ttype "")
(define next "")
=][=#
;;; Now replace the initial values with proper ones gotten from
;;; the trasition definitions.
;;;
;;; It is actually possible to have multiple specifications for a
;;; single state/event pair, however the last state/event assignment
;;; will supply the value for the transition table. Different
;;; transitions may also specify the same transition method. For
;;; that, we unique sort the list and eliminate dups that way. The
;;; unique-ified list is used to produce the callout table.
;;;
=][=
FOR transition =][=
IF (== (get "tst") "*") =][=
;; This transition applies for all states
;;
(set! tev (string-upcase! (get "tev")))
(set! ttype (if (exist? "ttype") (get "ttype")
(string-append "${f}_" tev) ))
(set! next (if (exist? "next") (string-upcase! (get "next")) "${f}"))
(shellf
"for f in ${st_list} ; do
eval FSM_TRANS_${f}_to_%s=\\'%s_ST_%s %s\\'
done"
tev PFX next (if (exist? "cost") (get "cost") "1.0")) =][=
ELIF (== (get "tev") "*") =][=
;; This transition applies for all transitions in a certain state
;;
(set! tst (string-upcase! (get "tst")))
(set! ttype (if (exist? "ttype")
(string-upcase! (get "ttype")) (string-append tst "_${f}") ))
(set! next (if (exist? "next") (string-upcase! (get "next")) tst))
(shellf
"for f in ${ev_list} ; do
eval FSM_TRANS_%s_to_${f}=\\'%s_ST_%s %s\\'
done"
tst PFX next (if (exist? "cost") (get "cost") "1.0")) =][=
ELSE =][=
FOR tst =][=
(set! tst (string-upcase! (get "tst")))
(set! next (if (exist? "next") (string-upcase! (get "next")) tst))
=][=
FOR tev =][=
(set! tev (string-upcase! (get "tev")))
(shellf "FSM_TRANS_%s_to_%s='%s_ST_%s %s'"
tst tev PFX next (if (exist? "cost") (get "cost") "1.0")) =][=
ENDFOR tev =][=
ENDFOR tst =][=
ENDIF tst or ttkn as '*' =][=
ENDFOR transition =][=
(define trans-ct
(shellf
"env | egrep '^FSM_TRANS_' | \
sed '/=.*%s_ST_INVALID/d;' | \
sort -u > .fsm.xlist
echo `wc -l < .fsm.xlist` "
PFX
) )
(shellf "
eval `sed 's/ */=/' %s-att.ste`
while read line
do
v=`echo $line|sed 's/_to_.*//;s/^FSM_TRANS_//'`
eval v=\\${$v}
echo ${v} `echo $line | sed 's/^FSM_TRANS_//;s/_to_/ /;s/=.[A-Z]*_ST_/ /'`
done < .fsm.xlist | sort -n > .fsm.list
" (base-name))
(shell "
while read _ initial token result cost _
do printf '%-14s %-14s %-14s %s\n' ${initial} ${result} ${token} ${cost}
done < .fsm.list
rm -f .fsm.*list
")
=]
DONE