SMDL
Last Published: 10/21/2005 05:51:25
 

State Machine Description Language (SMDL) System User Manual

Introduction

The SMDL system provides a code-generation tool and runtime to convert SMDL scripts into Java (future versions will likely support C++ as well).  A tool, smdl.Tool, produces a state machine implementation from an SMDL script into a Java abstract class.

The SMDL

The SMDL, as its name implies, is a language for describing state machines. The principle concepts in the language are states and transitions. A state is the state of an object; an object can only be in one state at a time (e.g. waking or sleeping). A state may be a superstate and house a number of substates. Superstates are abstract and have no implementation. Substates, or at least terminating substates (substates that have no children), are concrete. A transition is either an event, a guard, a guarded_event or a timeout. A transition may cause an object to change state, to invoke an action or both.

Here's a state machine for traffic lights:

   options
    {
        className=Lights;
        stateMachineSuffix=StateMachine;
        startState=out_of_service;
        actionReturnType=boolean;
        actionExceptionSpecification=SMDLException;
        defaultEventHandler=invalid;
    }
    state(out_of_service)
    {
        enter(offAll)
        event(start, in_service)
        event(stop, out_of_service)
    }
    state(in_service)
    {
        event(stop, out_of_service)
        event(start, out_of_service)
        state(red)
        {
            enter(onRed)
            timeout(3 seconds, offRed, green)
            event(pedestrian, countPedestrians, red)
        }
        state(yellow)
        {
            enter(onYellow)
            timeout(1 seconds, offYellow, red)
            event(pedestrian, countPedestrians, yellow)
        }
        state(green)
        {
            enter(onGreen)
            timeout(3 seconds, offGreen, yellow)
            event(pedestrian, countPedestrians, green)
        }
    }

This example has a total of five states, one of which is a superstate (in_service) and three of which are substates (red, yellow and green). It has an options section, which provides a mechanism for controlling the output generated by the code-generation tool. Options in the options section are a bit like pragmas in C++: they are more tolerated by the language than part of it.

options

The options section starts with the keyword "options" and starts and ends with a curly brace. Within the optins section, an arbitrary number of variables can be defined with the form name=value;. Note that each variable definition is terminated by a semicolon. The complete syntax for an options section is:

options {
  name1=value1;
  name2=value2;
}

The options section can appear at the start of an SMDL script, before any state sections or as the first element in a state section. In the former case, the options section defines global settings; in the latter, state specific variables. Examples of global variables are "className" or "stateMachineSuffix".  Note that even though an options section is allowed within a state section, the current tool ignores such sections.

Recognized value names are:

NameDescription
classNameDefine the class name for the generated state machine output.
packageDefine a Java package name for the generated state machine output.
stateMachineSuffixDefine a class name suffix for the generated state machine output.
Option Keywords


state

   state(state_name)
    {
        transition1(...)
        transition2(...)
    }

The name is mandatory. The body of the state section is filled with one or more transitions. As noted earlier, a state may be a superstate to other substates. The following form is valid:

   state(state_name)
    {
        options
        {
            name1=value1;
            name2=value2;
        }
        transition1(...)
        state(state_name2)
        {
            options
            {        
                name1=value1;
            }
            transition1(...)
            transition2(...)
        }
        state(state_name3)
        {
            transition1(...)
            transition3(...)
        }
    }

Transitions

Transitions are statements within state bodies that define how a given states react to external events, timeouts, boolean conditions or some combination of the foregoing. The transitions enter and exit arguably are not transitions since they implicitly do not cause a state transition.

Action Lists

All transitions can define actions. Actions are member functions or sequences of member functions that are invoked whenever a transition occurs. The action member functions are merely declared in SMDL output. The programmer must define them.

An action list consists of two or more actions bound together by logical and operators. An example, action sequence is:

   goOffHook && generateDialTone

A simple action or any simple action in an action sequence may be preceded by the "!" operator, which inverts the result of the action:

   action1 && !action2

Guard Lists

Guard lists are similar to action lists. A guard list consists of a single conditional test or a sequence of conditional tests. Each element in a sequence of conditional tests may be bound together by logical and or logical or operators:

   isMale && isUnderAge
    isMale || isUnderAge

Each of the conditional tests defined in a guard list corresponds to a member function that the programmer defines.

enter / exit

An enter statement defines an action that is invoked whenever a state is entered. An exit statement defines an action that is invoked whenever a state is left. They have the forms respectively: enter(action) and exit(action).

event

An event has an id, an optional action and a transition state. Whenever the event identified by the id occurs, the action is invoked, if defined, and the object changes state from the current state to the transition state. An event has the following form: event(ID, [action,] next_state).

timeout

A timeout defines an interval, an optional action and a transition state. The timeout interval can be expressed in either seconds or milliseconds as the forms indicate: timeout(number seconds, [action,] next_state) or timeout(number milliseconds, [action,] next_state).

guarded_event

A guarded_event is similar to an event with the addition of a guard parameter. It has the form: guarded_event(event_id, guard, [action,] next_state). The guard parameter is very similar to an action parameter.

SMDL Keywords

The SMDL defines the following keywords:

  • do
  • enter
  • exit
  • event
  • state
  • guarded_event
  • guard
  • timeout
  • options

SMDL BNF

The SMDL Baukus-Naur Form (BNF) resembles the following:

program = [ options ] 1*( state )

state = "state" "(" identifier ")" "{" 
  [ options ] 
  1*(guard|guarded_event|timeout|enter|exit|event) 
  [ do ]
  *( state ) 
"}"

options = "options" "{" 1* ( assignment ) "}"

guard = "guard" "(" guard, [action_list ","] next_state ")"

timeout = "timeout" "(" digits ( "seconds" | "milliseconds" ), [action_list "," ] next_state ")"

do = "do" "(" identifier ")"

enter = "enter" "(" action_list ")"

exit = "exit" "(" action_list ")"

guarded = "guard" "(" guard_list, [action_list "," ] next_state ")"

guarded_event = "guarded_event" "(" identifier, guard_list, [action_list "," ] next_state ")"

event = "event" "(" identifier, [action "," ] next_state ")"

action_list = [ "!" ] identifier *( "&&" [ "!" ] identifier )

guard_list = [ "!" ] identifier *( ( "&&" | "||" ) [ "!" ] identifier )

next_state = identifier

assignment = identifier "=" identifier ";"

identifier = 1*(alpha|digit|"_"|".")

quoted-string = <"> *(alpha|digit|SP|HT) <

digits = 1*digit

digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"


The SMDL tool

The SMDL distribution includes a Java-based tool for compiling SMDL scripts into Java code. It takes an SMDL script as input and outputs Java source code. It is invoked as follows:

java -jar /path-to-jar/smdl.jar filename.smdl

Typically, the SMDL jar is provided in the lib subdirectory. If you have installed the SMDL distribution in /usr/local/smdl, for example, the SMDL tool is invoked with the following command:

java -jar /usr/local/smdl/lib/smdl.jar filename.smdl

Running the tool on Linux

A shell script to invoke the SMDL tool is provided in the bin subdirectory of the distribution.

If your Linux distribution provides a /etc/profile.d directory, you may wish to customize the shell environment to find this shell script automatically.

Assuming the distribution is installed in /usr/local/smdl, for example, you could create a script, smdl.sh and install it in /etc/profile.d with the following contents:

#!/bin/sh
export SMDL_HOME=/usr/local/smdl
export PATH="$PATH:/usr/local/smdl/bin"

SMDL Tool Support Jar files

The SMDL tool requires some support jars to run. These include:

  • antlr.jar
  • commons-cli-1.0.jar

These support jars are included in the distribution and provided along with smdl.jar in the lib directory.

Future Direction

There are a lot of shortcomings in the existing version. The most significant might be the lack of a mechanism to describe default event handlers globally or on a state-by-state basis. The other obvious shortcoming is the lack of C++ support. Here's a more complete list:

  • default event handlers
  • C++ support
  • runtime to maintain state transition history
  • include a start state option
  • verify on Linux and Solaris platforms
  • provide escape mechanism for passing user-defined code verbatim from smdl script to output
  • named timeouts (to allow programmatic control of timer restarts)
  • state description string parameter
  • generate SDML from a case-tool
  • generate a UML drawing of a state machine from an SDML script
  • translate SCXMLSCXML documents into SMDL state machines

If you have recommendations, bug fixes or other ideas for improvements in the language, the tool or the runtime, please contact the author, John Poplett.

Acknowledgements

I wrote the SMDL system with ANTLR , a kind of parser generator that provides an interesting alternative to YACC and LEX and that produces output in Java. Some of the syntax of SDML was stolen from ANTLR. I wholeheartedly encourage you to have a look at it.

I also recommend UML Distilled, Second Edition. A Brief Guide To The Standard Object Modeling Language by Martin Fowler. Addison-Wesley. ISBN 0-201-65783-X.

Steven Robertson, Michael Corrigan, Ed Federmeyer, Jaideep Abichandani, Hariram Ravandhu and Jerry Devries are good friends and colleagues with whom I have shared ideas over the years. They helped with the concepts used in the SMDL and SMDL system but are not to blame for any shortcomings in the implementation.

This manual page was created with the Bluefish HTML editor.