<s> """<STR_LIT>""" <EOL> import re <EOL> from pycopia . aid import Enum , Enums <EOL> class FSMError ( Exception ) : <EOL> pass <EOL> _cre = re . compile ( "<STR_LIT:test>" ) <EOL> SREType = type ( _cre ) <EOL> del _cre <EOL> def make_states ( * args ) : <EOL> "<STR_LIT>" <EOL> return Enums ( map ( str , args ) ) <EOL> ANY = Enum ( - <NUM_LIT:1> , "<STR_LIT>" ) <EOL> class FSM ( object ) : <EOL> """<STR_LIT>""" <EOL> ANY = ANY <EOL> def __init__ ( self , initial_state = <NUM_LIT:0> ) : <EOL> self . _transitions = { } <EOL> self . _expressions = [ ] <EOL> self . default_transition = None <EOL> self . RESET = Enum ( <NUM_LIT:0> , "<STR_LIT>" ) <EOL> self . initial_state = self . RESET <EOL> self . _reset ( ) <EOL> def push ( self , v ) : <EOL> self . stack . append ( v ) <EOL> def pop ( self ) : <EOL> return self . stack . pop ( ) <EOL> def pushalt ( self , v ) : <EOL> self . altstack . append ( v ) <EOL> def popalt ( self ) : <EOL> return self . altstack . pop ( ) <EOL> def _reset ( self ) : <EOL> """<STR_LIT>""" <EOL> self . current_state = self . initial_state <EOL> self . stack = [ ] <EOL> self . altstack = [ ] <EOL> def reset ( self ) : <EOL> "<STR_LIT>" <EOL> self . _reset ( ) <EOL> def add_states ( self , * args ) : <EOL> for enum in make_states ( * args ) : <EOL> if not hasattr ( self , str ( enum ) ) : <EOL> setattr ( self , str ( enum ) , enum ) <EOL> else : <EOL> raise FSMError ( "<STR_LIT>" ) <EOL> def set_default_transition ( self , action , next_state ) : <EOL> '''<STR_LIT>''' <EOL> if action == None and next_state == None : <EOL> self . default_transition = None <EOL> else : <EOL> self . default_transition = ( action , next_state ) <EOL> add_default_transition = set_default_transition <EOL> def add_transition ( self , input_symbol , state , action , next_state ) : <EOL> '''<STR_LIT>''' <EOL> self . _transitions [ ( input_symbol , state ) ] = ( action , next_state ) <EOL> def add_expression ( self , expression , state , action , next_state , flags = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> cre = re . compile ( expression , flags ) <EOL> self . _expressions . append ( ( cre , state , action , next_state ) ) <EOL> self . _transitions [ ( SREType , state ) ] = ( self . _check_expression , None ) <EOL> def _check_expression ( self , symbol , myself ) : <EOL> for cre , state , action , next_state in self . _expressions : <EOL> mo = cre . match ( symbol ) <EOL> if state is self . current_state and mo : <EOL> if action is not None : <EOL> action ( mo , self ) <EOL> self . current_state = next_state <EOL> def add_transition_list ( self , list_input_symbols , state , action , next_state ) : <EOL> '''<STR_LIT>''' <EOL> for input_symbol in list_input_symbols : <EOL> self . add_transition ( input_symbol , state , action , next_state ) <EOL> def get_transition ( self , input_symbol , state ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> return self . _transitions [ ( input_symbol , state ) ] <EOL> except KeyError : <EOL> try : <EOL> return self . _transitions [ ( ANY , state ) ] <EOL> except KeyError : <EOL> try : <EOL> return self . _transitions [ ( SREType , state ) ] <EOL> except KeyError : <EOL> if self . default_transition is not None : <EOL> return self . default_transition <EOL> else : <EOL> raise FSMError ( '<STR_LIT>' % ( input_symbol , ) ) <EOL> def process ( self , input_symbol ) : <EOL> """<STR_LIT>""" <EOL> action , next_state = self . get_transition ( input_symbol , self . current_state ) <EOL> if action is not None : <EOL> action ( input_symbol , self ) <EOL> if next_state is not None : <EOL> self . current_state = next_state <EOL> def step ( self , token ) : <EOL> """<STR_LIT>""" <EOL> action , next_state = self . get_transition ( token , self . current_state ) <EOL> if action is not None : <EOL> rv = action ( token , self ) <EOL> if rv is None : <EOL> if next_state is not None : <EOL> self . current_state = next_state <EOL> else : <EOL> self . current_state = rv <EOL> elif next_state is not None : <EOL> self . current_state = next_state <EOL> def process_string ( self , s ) : <EOL> for c in s : <EOL> self . process ( c ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> pass </s>
