datatypes.fsm: add a fsm_graph.v tool (#13723)
parent
424ef0b2b8
commit
9495aacf3e
|
@ -19,3 +19,36 @@ When that happens:
|
|||
|
||||
After all transitions are checked, and thus the state is changed, the client-specified
|
||||
`on_run()` handler of the now current state is called.
|
||||
|
||||
## Plot States and Transitions
|
||||
This module includes a tool for generating dot diagrams from .v source code,
|
||||
that defines a FSM. The tool is located in [fsm_graph.v](tools/fsm_graph.v).
|
||||
|
||||
Here is an example of how to generate a .dot file with the graph and transitions:
|
||||
```bash
|
||||
v run vlib/datatypes/fsm/tools/fsm_graph.v -f vlib/datatypes/fsm/fsm_test.v > graph.dot
|
||||
```
|
||||
|
||||
You can convert the generated .dot file to a PNG file with Graphviz's `dot`
|
||||
conversion tool:
|
||||
```bash
|
||||
v run vlib/datatypes/fsm/tools/fsm_graph.v -f vlib/datatypes/fsm/fsm_test.v > graph.dot
|
||||
dot -Tpng graph.dot > graph.png
|
||||
xdg-open graph.png
|
||||
```
|
||||
|
||||
You can also visualise it with Graphviz (the `dot` command)
|
||||
& ImageMagick (the `display` command):
|
||||
```bash
|
||||
v run vlib/datatypes/fsm/tools/fsm_graph.v -f vlib/datatypes/fsm/fsm_test.v | dot -Tpng | display
|
||||
```
|
||||
|
||||
To view the .dot file, you can also use any of the
|
||||
[Graphviz Graphical Interfaces](https://graphviz.org/resources/#graphical-interfaces)
|
||||
and `xdot` in particular:
|
||||
```bash
|
||||
v run vlib/datatypes/fsm/tools/fsm_graph.v -f vlib/datatypes/fsm/fsm_test.v | xdot -
|
||||
```
|
||||
|
||||
In all of the above examples, you can replace `vlib/datatypes/fsm/fsm_test.v`
|
||||
with the path to your own .v code that imports and uses `fsm`.
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import os
|
||||
import flag
|
||||
|
||||
pub fn read_file(file string) ?[]string {
|
||||
if os.is_file(file) {
|
||||
text := os.read_lines(file) or {
|
||||
return error(@MOD + '.' + @STRUCT + '.' + @FN + ' Could not read "$file": "$err.msg()"')
|
||||
}
|
||||
return text
|
||||
}
|
||||
return ['']
|
||||
}
|
||||
|
||||
pub fn extract_transitions(line string) ?string {
|
||||
mut result := ' '
|
||||
first_comma := line.index(',') ?
|
||||
second_comma := line.index_after(',', first_comma + 1)
|
||||
|
||||
from := line[..first_comma]
|
||||
to := line[first_comma + 1..second_comma]
|
||||
condition := line[second_comma + 1..]
|
||||
|
||||
return result + from + ' -> ' + to + ' [label=' + condition + '];'
|
||||
}
|
||||
|
||||
pub fn get_transitions(line string) ?string {
|
||||
mut raw_text := line[line.index_any('(') + 1..line.index_any(')')]
|
||||
raw_text = raw_text.replace("'", '').replace(' ', '')
|
||||
return extract_transitions(raw_text)
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
mut fp := flag.new_flag_parser(os.args)
|
||||
file := fp.string('file', `f`, '', 'input V file with transitions to generate graph from.')
|
||||
lines := read_file(file) ?
|
||||
println('digraph fsm {')
|
||||
for line in lines {
|
||||
if line.contains('add_transition') {
|
||||
println(get_transitions(line) ?)
|
||||
}
|
||||
}
|
||||
|
||||
println('}')
|
||||
}
|
Loading…
Reference in New Issue