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"