def __template_state(txt, TheTemplate, SMD): """Generate the template state that 'hosts' the templated states. """ state = TheTemplate state_index = TheTemplate.core().state_index TriggerMap = state.transitions().get_trigger_map() if TheTemplate.uniform_state_entries_f(): txt.extend(input_block.do(state_index, False, SMD)) txt.extend( acceptance_info.do(state, state_index, SMD, ForceSaveLastAcceptanceF=True)) else: label_str = " __quex_assert_no_passage();\n" + \ get_label("$entry", state_index) + ":\n" txt.append(label_str) state_index_str = None if not TheTemplate.uniform_state_entries_f(): # Templates that need to implement more than one state need to return to # dedicated state entries, if the state entries are not uniform. state_index_str = "template_%i_map_state_key_to_state_index[template_state_key]" % state_index txt.extend( transition_block.do(TriggerMap, state_index, SMD, ReturnToState_Str=state_index_str)) txt.extend(drop_out.do(state, state_index, SMD))
def __template_state(txt, TheTemplate, SMD): """Generate the template state that 'hosts' the templated states. """ state = TheTemplate state_index = TheTemplate.core().state_index TriggerMap = state.transitions().get_trigger_map() if TheTemplate.uniform_state_entries_f(): txt.extend(input_block.do(state_index, False, SMD)) txt.extend(acceptance_info.do(state, state_index, SMD, ForceSaveLastAcceptanceF=True)) else: label_str = " __quex_assert_no_passage();\n" + \ get_label("$entry", state_index) + ":\n" txt.append(label_str) state_index_str = None if not TheTemplate.uniform_state_entries_f(): # Templates that need to implement more than one state need to return to # dedicated state entries, if the state entries are not uniform. state_index_str = "template_%i_map_state_key_to_state_index[template_state_key]" % state_index txt.extend(transition_block.do(TriggerMap, state_index, SMD, ReturnToState_Str=state_index_str)) txt.extend(drop_out.do(state, state_index, SMD))
def do(state, StateIdx, SMD=False): """Produces code for all state transitions. Programming language is determined by 'Language'. """ assert isinstance(state, State) assert SMD.__class__.__name__ == "StateMachineDecorator" assert len(state.transitions().get_epsilon_target_state_index_list()) == 0, \ "Epsilon transition contained target states: state machine was not made a DFA!\n" + \ "Epsilon target states = " + repr(state.transitions().get_epsilon_target_state_index_list()) InitStateF = StateIdx == SMD.sm().init_state_index LanguageDB = Setup.language_db # (*) Dead End States # i.e. states with no further transitions. dead_end_state_info = SMD.dead_end_state_db().get(StateIdx) if dead_end_state_info != None: state_stub = __dead_end_state_stub(dead_end_state_info, SMD) # Some states do not need 'stubs' to terminal since they are straight # forward transitions to the terminal. if len(state_stub) == 0: return [] return [ get_label("$entry", StateIdx), ":\n", " ", LanguageDB["$debug-state"](StateIdx, SMD.forward_lexing_f()) ] + state_stub # (*) Normal States TriggerMap = state.transitions().get_trigger_map() assert TriggerMap != [] # Only dead end states have empty trigger maps. # # => Here, the trigger map cannot be empty. txt = [] txt.extend(input_block.do(StateIdx, InitStateF, SMD)) txt.extend(acceptance_info.do(state, StateIdx, SMD)) txt.extend(transition_block.do(TriggerMap, StateIdx, SMD)) txt.extend(drop_out.do(state, StateIdx, SMD)) txt.extend(get_epilog(StateIdx, InitStateF, SMD)) return txt
def __path_walker(txt, PathWalker, SMD): """Generates the path walker, that walks along the character sequence. """ PathList = PathWalker.path_list() Skeleton = PathList[0].skeleton() PathWalkerID = PathWalker.core().state_index if PathWalker.uniform_state_entries_f(): # (1) Input Block (get the new character) txt.extend(input_block.do(PathWalkerID, False, SMD)) # (2) Acceptance information/Store Input positions txt.extend(acceptance_info.do(PathWalker, PathWalkerID, SMD, ForceSaveLastAcceptanceF=True)) else: txt.append(" __quex_assert_no_passage();\n") txt.append(get_label("$entry", PathWalkerID) + ":\n") txt.append(" __quex_debug(\"path walker %i\");\n" % PathWalkerID) # (3) Transition Map # (3.1) The comparison with the path's current character # If terminating zero is reached, the path's end state is entered. if PathWalker.uniform_state_entries_f(): next_state = [ "goto %s;\n" % get_label_of_address(PathWalkerID, U=True) ] end_state = __end_state_router(PathWalker, SMD) else: next_state = [ __state_router(PathWalker, SMD) ] end_state = [" "] + next_state txt.append(" ") txt.append(LanguageDB["$if =="]("*path_iterator")) txt.append(" ") txt.append(LanguageDB["$increment"]("path_iterator")) txt.append("\n") txt.append(" ") txt.extend(next_state) txt.append(" ") txt.append(LanguageDB["$elseif"] \ + LanguageDB["$=="]("*path_iterator", "QUEX_SETTING_PATH_TERMINATION_CODE") \ + LanguageDB["$then"]) txt.extend(end_state) txt.append(" ") txt.append(LanguageDB["$endif"]) txt.append("\n") # (3.2) Transition map of the 'skeleton' trigger_map = PathWalker.transitions().get_trigger_map() if len(trigger_map) == 0: # (This happens, for example, if there are only keywords and no # 'overlaying' identifier pattern.) # Even if the skeleton/trigger map is empty there must be something # that catches the 'buffer limit code'. # => Define an 'all drop out' trigger_map and then, # => Adapt the trigger map, so that the 'buffer limit' is an # isolated single interval. trigger_map = [ (Interval(-sys.maxint, sys.maxint), None) ] state_index_str = None if not PathWalker.uniform_state_entries_f(): state_index_str = "path_walker_%i_state[path_iterator - path_walker_%i_base]" % (PathWalkerID, PathWalkerID) txt.extend(transition_block.do(trigger_map, PathWalkerID, SMD, ReturnToState_Str=state_index_str)) # (4) The drop out (nothing matched) # (Path iterator has not been increased yet) txt.extend(drop_out.do(PathWalker, PathWalkerID, SMD)) return