code: def expand_state_definition(source, loc, tokens):
      
      indent = " " * (pp.col(loc, source) - 1)
      statedef = []
  
      # build list of states
      states = set()
      fromTo = {}
      for tn in tokens.transitions:
          states.add(tn.from_state)
          states.add(tn.to_state)
          fromTo[tn.from_state] = tn.to_state
  
      # define base class for state classes
      baseStateClass = tokens.name
      statedef.extend([
          "class %s(object):" % baseStateClass,
          "    def __str__(self):",
          "        return self.__class__.__name__",
  
          "    @classmethod",
          "    def states(cls):",
          "        return list(cls.__subclasses__())",
  
          "    def next_state(self):",
          "        return self._next_state_class()",
      ])
  
      # define all state classes
      statedef.extend("class {0}({1}): pass".format(s, baseStateClass) for s in states)
  
      # define state->state transitions
      statedef.extend("{0}._next_state_class = {1}".format(s, fromTo[s]) for s in states if s in fromTo)
  
      statedef.extend([
          "class {baseStateClass}Mixin:".format(baseStateClass=baseStateClass),
          "    def __init__(self):",
          "        self._state = None",
  
          "    def initialize_state(self, init_state):",
          "        self._state = init_state",
  
          "    @property",
          "    def state(self):",
          "        return self._state",
  
          "    # get behavior/properties from current state",
          "    def __getattr__(self, attrname):",
          "        attr = getattr(self._state, attrname)",
          "        return attr",
  
          "    def __str__(self):",
          "       return '{0}: {1}'.format(self.__class__.__name__, self._state)",
          ])
  
      return indent + ("\n" + indent).join(statedef) + "\n"
docs: Parse action to convert statemachine to corresponding Python classes and methods