Exemplo n.º 1
0
Arquivo: loop.py Projeto: xxyzzzq/quex
def _get_loop_map(TheCountMap, SmList, IidLoopExit):
    """A loop map tells about the behavior of the core loop. It tells what
    needs to happen as a consequence to an incoming character. Two options:

        -- Return to loop (normal case)
        -- Enter the tail (appendix) of a parallel state machine.

    RETURNS: List of LoopMapEntry-s. 

    A LoopMapEntry consists of:

       .character_set: Character set that triggers.
       .count_action:  Count action related to the character set.
                       == None, if the character set causes 'loop exit'.
       .incidence_id:  Incidence Id of terminal that is triggered by character set.
                       -- incidence id of count action terminal, or
                       -- incidence id of couple terminal.
       .appendix_sm:   Appendix state machine
                       -- combined appendix state machines, or
                       -- None, indicating that there is none.
    """
    L = TheCountMap.loop_character_set()

    # 'couple_list': Transitions to 'couple terminals' 
    #                => connect to appendix state machines
    couple_list,     \
    appendix_sm_list = _get_LoopMapEntry_list_parallel_state_machines(TheCountMap, 
                                                                      SmList)

    L_couple = NumberSet.from_union_of_iterable(
        lei.character_set for lei in couple_list
    )

    # 'plain_list': Transitions to 'normal terminals' 
    #               => perform count action and loop.
    L_plain    = L.difference(L_couple)
    plain_list = _get_LoopMapEntry_list_plain(TheCountMap, L_plain)

    # 'L_exit': Transition to exit
    #           => remaining characters cause exit.
    L_loop = NumberSet.from_union_of_iterable(
        x.character_set for x in chain(couple_list, plain_list)
    )
    universal_set = Setup.buffer_codec.source_set
    L_exit        = L_loop.get_complement(universal_set)
    exit_list     = [ LoopMapEntry(L_exit, None, IidLoopExit, None) ]

    result = couple_list + plain_list + exit_list

    assert not any(lei is None for lei in result)
    assert not any(lei.character_set is None for lei in result)
    assert not any(lei.incidence_id is None for lei in result)
    return result, appendix_sm_list
Exemplo n.º 2
0
def _get_loop_map(TheCountMap, SmList, IidLoopExit):
    """A loop map tells about the behavior of the core loop. It tells what
    needs to happen as a consequence to an incoming character. Two options:

        -- Return to loop (normal case)
        -- Enter the tail (appendix) of a parallel state machine.

    RETURNS: List of LoopMapEntry-s. 

    A LoopMapEntry consists of:

       .character_set: Character set that triggers.
       .count_action:  Count action related to the character set.
                       == None, if the character set causes 'loop exit'.
       .incidence_id:  Incidence Id of terminal that is triggered by character set.
                       -- incidence id of count action terminal, or
                       -- incidence id of couple terminal.
       .appendix_sm:   Appendix state machine
                       -- combined appendix state machines, or
                       -- None, indicating that there is none.
    """
    L = TheCountMap.loop_character_set()

    # 'couple_list': Transitions to 'couple terminals'
    #                => connect to appendix state machines
    couple_list,     \
    appendix_sm_list = _get_LoopMapEntry_list_parallel_state_machines(TheCountMap,
                                                                      SmList)

    L_couple = NumberSet.from_union_of_iterable(lei.character_set
                                                for lei in couple_list)

    # 'plain_list': Transitions to 'normal terminals'
    #               => perform count action and loop.
    L_plain = L.difference(L_couple)
    plain_list = _get_LoopMapEntry_list_plain(TheCountMap, L_plain)

    # 'L_exit': Transition to exit
    #           => remaining characters cause exit.
    L_loop = NumberSet.from_union_of_iterable(
        x.character_set for x in chain(couple_list, plain_list))
    universal_set = Setup.buffer_codec.source_set
    L_exit = L_loop.get_complement(universal_set)
    exit_list = [LoopMapEntry(L_exit, None, IidLoopExit, None)]

    result = couple_list + plain_list + exit_list

    assert not any(lei is None for lei in result)
    assert not any(lei.character_set is None for lei in result)
    assert not any(lei.incidence_id is None for lei in result)
    return result, appendix_sm_list
Exemplo n.º 3
0
    def get_incidence_id_map(self, BeyondIncidenceId=None):
        """RETURNS: A list of pairs: (character_set, incidence_id) 
             
           All same counting actions are referred to by the same incidence id.

           If BeyondIncidenceId is given, then the remaining set of characters
           is associated with 'BeyondIncidenceId'.
        """
        result = [ (x.character_set, x.incidence_id) for x in self.__map ]

        if BeyondIncidenceId is None:
            return result

        all_set    = NumberSet.from_union_of_iterable(x.character_set for x in self.__map)
        beyond_set = all_set.get_complement(Setup.buffer_codec.source_set)
        if not beyond_set.is_empty(): 
            result.append((beyond_set, BeyondIncidenceId))
        return result
Exemplo n.º 4
0
    def get_incidence_id_map(self, BeyondIncidenceId=None):
        """RETURNS: A list of pairs: (character_set, incidence_id) 
             
           All same counting actions are referred to by the same incidence id.

           If BeyondIncidenceId is given, then the remaining set of characters
           is associated with 'BeyondIncidenceId'.
        """
        result = [(x.character_set, x.incidence_id) for x in self.__map]

        if BeyondIncidenceId is None:
            return result

        all_set = NumberSet.from_union_of_iterable(x.character_set
                                                   for x in self.__map)
        beyond_set = all_set.get_complement(Setup.buffer_codec.source_set)
        if not beyond_set.is_empty():
            result.append((beyond_set, BeyondIncidenceId))
        return result
Exemplo n.º 5
0
def _get_loop_map(loop_config, CaMap, SmList, IidLoopExit, L_subset):
    """A loop map tells about the behavior of the core loop. It tells what
    needs to happen as a consequence to an incoming character. Two options:

    L_subset = NumberSet containing characters that are actually part of 
               the loop. 'None' => all characters of 'CaMap' are considered.

        -- Return to loop (normal case)
        -- Enter the tail (appendix) of a parallel state machine.

    RETURNS: List of LoopMapEntry-s. 

    A LoopMapEntry consists of:

       .character_set: Character set that triggers.
       .count_action:  Count action related to the character set.
                       == None, if the character set causes 'loop exit'.
       .iid_couple_terminal:  Incidence Id of terminal that is triggered by character set.
                       -- incidence id of count action terminal, or
                       -- incidence id of couple terminal.
       .appendix_sm:   Appendix state machine
                       -- combined appendix state machines, or
                       -- None, indicating that there is none.
    """
    assert all(
        _state_machine_tagged_with_matching_incidence_ids(sm) for sm in SmList)
    # State machines are not to be transformed at this point in time
    assert all(not _exists_bad_lexatom_detector_state(sm) for sm in SmList)

    CaMap.prune(Setup.buffer_encoding.source_set)
    L = CaMap.union_of_all()

    L_couple = NumberSet.from_union_of_iterable(
        sm.get_beginning_character_set() for sm in SmList)

    # 'plain_list': Transitions to 'normal terminals'
    #               => perform count action and loop.
    L_plain = L.difference(L_couple)
    if L_subset is not None: L_plain.intersect_with(L_subset)
    L_loop = L_plain.union(L_couple)
    L_exit = L_loop.get_complement(Setup.buffer_encoding.source_set)

    plain_list = _get_LoopMapEntry_list_plain(loop_config, CaMap, L_plain)

    exit_list = []
    if not L_exit.is_empty():
        exit_list.append(
            LoopMapEntry(L_exit,
                         IidLoopExit,
                         Code=loop_config.cmd_list_CA_GotoTerminal(
                             None, IidLoopExit)))

    # 'couple_list': Transitions to 'couple terminals'
    #                => connect to appendix state machines
    couple_list,               \
    combined_appendix_sm_list, \
    appendix_cmd_list_db       = parallel_state_machines.do(loop_config, CaMap, SmList)

    assert L_couple.is_equal(
        NumberSet.from_union_of_iterable(lei.character_set
                                         for lei in couple_list))

    result = LoopMap(
        couple_list,  # --> jump to appendix sm-s
        plain_list,  # --> iterate to loop start
        exit_list)  # --> exit loop

    return result, combined_appendix_sm_list, appendix_cmd_list_db
Exemplo n.º 6
0
 def union_of_all(self):
     return NumberSet.from_union_of_iterable(
         number_set for number_set, ca in self
     )
Exemplo n.º 7
0
 def loop_character_set(self):
     return NumberSet.from_union_of_iterable(x.character_set for x in self.__map)
Exemplo n.º 8
0
 def loop_character_set(self):
     return NumberSet.from_union_of_iterable(x.character_set
                                             for x in self.__map)