Lecrapouille / PlantUMLStatecharts

[Tool][Functional] Generate state machine in C++ from PlantUML statecharts
GNU General Public License v3.0
6 stars 1 forks source link
cpp finite-state-machine fsm generator plantuml state-machine statechart statecharts translator uml

PlantUML Statecharts (State Machine) Translator

A Python3 tool parsing PlantUML statecharts scripts and generating C++11 code with its unit tests.

This repository contains:

The Python script offers you:

Here is an example of PlantUML code source, generating this kind of diagram, this tool is able to parse (Click on the figure to see the PlantUML code source):

Gumball

This repository also contains several more evolved examples of statecharts the tool can parse. For people not sure how state machines work, there are several links explaining them given in the last section of this document.

Limitation: what the tools cannot offer to you

Prerequisite

python3 -m pip install networkx lark

Command line

./statecharts.py <plantuml statechart file> <langage> [name]

Where:

Example:

./statecharts.py foo.plantuml cpp controller

Will create a FooController.cpp file with a class name FooController.

Compile Examples

cd examples
make -j8

Examples are compiled into the build folder as well as their PNG file. You can run binaries. For example:

./build/Gumball

PlantUML Statecharts syntax

This tool does not pretend to parse the whole PlantUML syntax or implement the whols UML statecharts standard. Here is the basic PlantUML statecharts syntax it can understand:

Note: I added some sugar syntax:

I added some syntax to help generate extra C++ code. They start with the ' keyword which is a PlantUML single-line comment so they will not produce syntax error when PlantUML is parsing the file but, on our side, we exploit them.

Things that I did not understand about state machines before this project

In the beginning, I did not understand the differences between the State/Transition diagram (STD) from the Structured Analysis for Real-Time methodology with the UML statechart. In STD actions are made by transitions, while in UML actions are made by transitions or by states. I was confused.

What I understood after: in 1956 there were two kinds of state machines: Moore in where actions were called from states and Mealy where actions were called from transitions. They describe exactly the same system and you can translate a Moore machine into a Mealy machine and vice versa, without losing any expressiveness cite. In 1984, Harel mixed the two syntaxes plus added some features (composite ...) and named it statecharts. Finally UML integrated statecharts in their standard.

Some tools like the one explained in this document simplify the statecharts graph to get a Mealy graph before generating the code. In the case of our translator, to keep the code simple to read, the state machine is not simplified and actions are made by states and by transitions.

Another point of confusion hat is the difference between action and activity. The action is instantaneous: it does not consume time (contrary to the activity). The activity can be seen as a thread that is preempted by any external events the state reacts to. The thread is halted when the activity is done or when the system switches state. Therefore, an activity shall not be seen by a periodic external update event since its code does not necessarily be repeated.

My last point of confusion concerned the order of execution of actions in transitions and in states. I explain it in the next section.

Rule of execution in Statecharts

Let's suppose the C++ code of the following state machine has been generated with the C++ name class Simple.

alt statemachine

If an output transition has no explicit event and no guard is given (or if the guard is returning true) and the activity has finished then the transition is immediately made in an atomic way. In our example, if event1, event2, and guard1 were not present this would create an infinite loop.

Events shall be mutually exclusive since we are dealing in discrete time events, several events can occur during the delta time but since in this API you have to call the event and the state machine reacts immediately, the order is defined by the caller.

Details Design

The translation pipeline of the Python script is the following:

How is the generated code? The state machine, like any graph structure (nodes are states and edges are transitions) can be depicted by a matrix.

For example concerning the motor controller:

alt motor

can be depicted in the following table (guards and actions are not shown). In practice the table is usually sparse:

Set Speed Halt --
IDLE STARTING
STOPPING IDLE
STARTING SPINNING STOPPING
SPINNING SPINNING STOPPING

Our implementation is the following:

References