def expand_state_definition(source, loc, tokens):
    indent = " " * (col(loc,source)-1)
    statedef = []
    
    # build list of states
    states = set()
    fromTo = {}
    for tn in tokens.transitions:
        states.add(tn.fromState)
        states.add(tn.toState)
        fromTo[tn.fromState] = tn.toState
    
    # define base class for state classes
    baseStateClass = tokens.name + "State"
    statedef.extend([
        "class %s(object):" % baseStateClass,
        "    def __str__(self):",
        "        return self.__class__.__name__",
        "    def next_state(self):",
        "        return self._next_state_class()" ])
    
    # define all state classes
    statedef.extend(
        "class %s(%s): pass" % (s,baseStateClass) 
            for s in states )
    statedef.extend(
        "%s._next_state_class = %s" % (s,fromTo[s]) 
            for s in states if s in fromTo )
           
    return indent + ("\n"+indent).join(statedef)+"\n"
def expand_named_state_definition(source,loc,tokens):
    indent = " " * (col(loc,source)-1)
    statedef = []
    # build list of states and transitions
    states = set()
    transitions = set()
    
    baseStateClass = tokens.name + "State"
    
    fromTo = {}
    for tn in tokens.transitions:
        states.add(tn.fromState)
        states.add(tn.toState)
        transitions.add(tn.transition)
        if tn.fromState in fromTo:
            fromTo[tn.fromState][tn.transition] = tn.toState
        else:
            fromTo[tn.fromState] = {tn.transition:tn.toState}

    # add entries for terminal states
    for s in states:
        if s not in fromTo:
            fromTo[s] = {}
    
    # define state transition class
    statedef.extend([
        "class %sTransition:" % baseStateClass,
        "    def __str__(self):",
        "        return self.transitionName",
        ])
    statedef.extend(
        "%s = %sTransition()" % (tn,baseStateClass) 
            for tn in transitions)
    statedef.extend("%s.transitionName = '%s'" % (tn,tn) 
            for tn in transitions)

    # define base class for state classes
    excmsg = "'" + tokens.name + \
        '.%s does not support transition "%s"' \
        "'% (self, tn)"
    statedef.extend([
        "class %s(object):" % baseStateClass,
        "    def __str__(self):",
        "        return self.__class__.__name__",
        "    def next_state(self,tn):",
        "        try:",
        "            return self.tnmap[tn]()",
        "        except KeyError:",
        "            raise Exception(%s)" % excmsg,
        "    def __getattr__(self,name):",
        "        raise Exception(%s)" % excmsg,
        ])
    
    # define all state classes
    for s in states:
        statedef.append("class %s(%s): pass" % 
                                    (s,baseStateClass))

    # define state transition maps and transition methods
    for s in states:
        trns = list(fromTo[s].items())
        statedef.append("%s.tnmap = {%s}" % 
            (s, ",".join("%s:%s" % tn for tn in trns)) )
        statedef.extend([
            "%s.%s = staticmethod(lambda : %s())" % 
                                            (s,tn_,to_)
                for tn_,to_ in trns
            ])

    return indent + ("\n"+indent).join(statedef) + "\n"