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
|
After all transitions are checked, and thus the state is changed, the client-specified
|
||||||
`on_run()` handler of the now current state is called.
|
`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