Exemplo n.º 1
0
    def concatenate_nfa(self, nfa: NFA, char_to_concatenate: str) -> NFA:
        """
        concatenate_nfa
        Concatenate a regex char to an existing NFA.

        :param nfa: The existing NFA.
        :param char_to_concatenate: Character from regex to concatenate.
        :return: The resulting NFA.
        """

        # As states are added, update the last state to connect from
        # if this isn't the first char of the regex (only a start state), add an epsilon transition.
        if len(nfa.states) > 1:
            self.last_state = nfa.add_epsilon_connector(self.last_state)

        # add the last state as an last close group
        self.last_closed_group = self.last_state

        # Connect to to new state on concat_char
        if self.union_in_progress:
            self.last_state = nfa.add_normal_char(
                self.last_state, char_to_concatenate, True,
                self.union_in_progress[-1][1])
        elif self.last_star:
            self.last_state = nfa.add_normal_char(self.last_state,
                                                  char_to_concatenate, True,
                                                  self.last_star[-1])
            self.last_star = self.last_star[:-1]

        else:
            self.last_state = nfa.add_normal_char(self.last_state,
                                                  char_to_concatenate, True,
                                                  self.open_groups[-1])

        return nfa
Exemplo n.º 2
0
    def union_nfa(self, nfa: NFA, unioning_state: State = None) -> None:
        """
        union_nfa
        Add a union from the last open group (or initial state) to existing NFA.

        :param nfa: The existing NFA.
        :param unioning_state: An optional state to union from (otherwise: last open group)
        """

        start_union = unioning_state if unioning_state else self.open_groups[-1]

        self.union_in_progress.append((start_union, self.last_state))
        logging.debug('Opening union: ' + str((start_union, self.last_state)))

        if start_union in nfa.accepting_states:
            nfa.accepting_states.remove(start_union)

        # If my open group is at the initial state, make a new state
        if start_union == nfa.initial_state:
            self.last_state = nfa.replace_initial()
        # Otherwise, connect a new epsilon path out of the
        # open group state for the other part of the union
        else:
            self.last_state = nfa.add_epsilon_connector(start_union)