State Machine Interface


Four Implementation Plans (C Comment Parser)


Nested Switch Implementation

enum Signal                        // enumeration for CParser signals
{
  CHAR_SIG, STAR_SIG, SLASH_SIG
};
enum State                         // enumeration for CParser states 
{
   CODE, SLASH, COMMENT, STAR
}; 
 
class CParser1
{
  private:
    State myState;                        // the scalar state-variable
    long myCommentCtr;                    // comment character counter
    /* ... */                             // other CParser1 attributes
  public: 
    void init()
    {
      myCommentCtr = 0; tran(CODE);   // default transiton
    }
    void dispatch(Signal sig);
    void tran(State target)
    {
      myState = target;
    }
    long getCommentCtr() const
    {
      return myCommentCtr;
    }
};
void CParser1::dispatch(Signal sig)
{
  switch (myState)
  {
    case CODE:
      switch (sig)
      {
        case SLASH_SIG:
          tran(SLASH);                          // transition to SLASH
          break;
      }
      break;
    case SLASH:
      switch (sig)
      {
        case STAR_SIG:
          myCommentCtr += 2;            // SLASH-STAR count as comment
          tran(COMMENT);                      // transition to COMMENT
          break;
        case CHAR_SIG:
        case SLASH_SIG:
          tran(CODE);                               // go back to CODE
          break;
      }
      break;
    case COMMENT:
      switch (sig)
      {
        case STAR_SIG:
          tran(STAR);                            // transition to STAR
          break;
        case CHAR_SIG:
        case SLASH_SIG:
          ++myCommentCtr;                    // count the comment char
          break; 
      }
      break;
    case STAR:
      switch (sig)
      {
        case STAR_SIG:
          ++myCommentCtr;                     // count STAR as comment
          break;
        case SLASH_SIG:
          myCommentCtr += 2;            // count STAR-SLASH as comment
          tran(CODE);                            // transition to CODE
          break;
        case CHAR_SIG:
          myCommentCtr += 2;                // count STAR-? as comment
          tran(COMMENT);                         // go back to COMMENT
          break;
       }
       break;
  }
}

Nested Switch Implementation - Conclusions


State Table Implementation


State Table Implementation - Conclusions


State Design Pattern (OO Approach)


State Design Pattern - Conclusions


Simplified State Design Pattern

Design Pattern

  • Separate event handlers
  • Design of event demultiplexing via sub-class design
  • Runtime demultiplexing via polymorphism
    Fig 3.4

Simplified Design Pattern

  • Combine event handling into dispatch()
  • Demultiplexing events done in various overrides of dispatch()
  • Claim of "generic"
    Fig 3.5

Optimized Approach

  • Combines ideas from
    1. Nested Switch
    2. State Table
    3. Simplified State Design Pattern
  • class Fsm
    1. Plays role of context class from Simplified State Design Pattern
    2. Plays role of event processor from State Table
    3. Represents states as (pointers to) state handler methods
    Fig 3.6


Optimized Approach - Conclusions

  • Requires enumerating events
  • State-specific behavior partitioned/localized in separate handler methods
  • Direct/efficient access to state machine attributes from state handler methods (friendship nor required)
  • Small memory footprint (one address myState represents instance of Fsm)
  • Code reuse: class Fsm
  • Efficient state transitions (re-assign pointer myState)
    Fig 3.6
  • Event dispatch performance:
    1. Replaces one layer of switch from Nested Switch with pointer-to-member-function
      (from O((log n)x(log n)) to O(log k)), where k < n)
    2. switch (inside handler method) can be replaced with table in places where temporal performance is an issue, achieving O(1)
  • Scalable/flexible:
    1. Add state: add state handler method
    2. Add event: append event to enumeration, add case/code to relevant state handler methods
  • Not hierarchical

Exceptions and FSM


Pointer to Member Functions and Efficiency


Guards, Junctions, Choice Points


Entry and Exit Actions