The FSM grammar section

The fsm section is the main section of the grammar description file. Its purpose is to describe all the states and transitions together with their input events and guards. It also defines which executable actions are to be invoked on each transition between states. From this list of grammar rules, the parser generator program creates an executable finite state machine that is capable of recognising the specified input events or tokens that cause state transitions away from each state, and capable of generating errors as soon as an unrecognised input event occurs for a given state.

Here is an example of part of a simple state machine grammar, which when parsed by a parser generator creates a state machine that controls a traffic light protected pedestrian crossing. Notice how the grammar section begins with the keyword fsm, and that the keyword is followed by the name of the starting state in the state machine, in this case 'Green'.

Following the fsm keyword and its starting state argument, the whole body of the state machine description is contained between curly braces.

options
{
    // assembly references, etc. in here ...
}
events
{
    TIMERTICK,
    BUTTONPRESS
}
guards
{
    ButtonWasPressed
}
fsm(Green)
{
    // The AllRed state is used when both traffic and
    // pedestrians are barred from crossing. This is
    // the state the controller is in while waiting
    // for slower pedestrians to complete their crossing.

    AllRed: 
        TIMERTICK RedAndYellow
        { SetLightRedAndYellow(); SetRedAndYellowTimer(); }
    |   BUTTONPRESS AllRed
        { RecordButtonPressed(); }
    ;

    // This is an English traffic light! In England
    // the lights go to both red and yellow lit up
    // for a few seconds between being red and green.

    RedAndYellow: 
        TIMERTICK TimedGreen
        { SetLightGreen(); SetGreenTimer(); }
    |   BUTTONPRESS RedAndYellow
        { RecordButtonPressed(); }
    ;

    // Once the lights have gone green, there is a
    // minimum interval they must remain green before
    // the controller will respond to the next button press.

    TimedGreen: 
        TIMERTICK[ButtonWasPressed] Yellow
        { SetLightYellow(); SetYellowTimer(); }
    |   BUTTONPRESS TimedGreen
        { RecordButtonPressed(); }
    |   TIMERTICK[!ButtonWasPressed] Green
    ;

    // After the minimum interval for the lights on green
    // has expired, the lights will stay on green indefinitely
    // unless a pedestrian presses the request to cross button.

    Green: 
        BUTTONPRESS Yellow
        { SetLightYellow(); RecordButtonPressed(); SetYellowTimer(); }
    ;

    // The yellow light is displayed for a few seconds between
    // green and red to tell traffic to stop at the light if
    // it is safe for them to do so.

    Yellow: 
        BUTTONPRESS Yellow
        { RecordButtonPressed(); }
    |   TIMERTICK RedWalk
        {
            SetLightRed(); SetLightWalk();
            ClearButtonPress(); SetWalkTimer();
        }
    ;

    // Once the lights have gone to red, we allow
    // pedestrians to cross the road.

    RedWalk: 
        BUTTONPRESS RedWalk
    |   TIMERTICK AllRed
        { SetLightDontWalk(); SetAllRedTimer(); }
    ;
}