def visit_repetition(self, repetition):
        """
        Converts a repeated regular exprsesion into an equivalent NFA.
        Pushes the NFA onto a stack.
        @param repetition: a Regex.Repetition object representing the repeated expression to convert.
        """
        state_machine = None
        repetition.child.accept(self)
        child_state_machine = self.state_machines.pop()

        # Create optional 0 to max-min
        repetition_min = repetition.min
        if repetition.max == Regex.Repetition.Infinity:
            # Kleene star
            inner_state_machine = copy.deepcopy(child_state_machine)
            state_machine = NonDeterministicFinite()
            state_machine.start_state.epsilon_edges.add(
                inner_state_machine.start_state)
            inner_state_machine.end_state.epsilon_edges.add(
                state_machine.end_state)
            inner_state_machine.end_state.epsilon_edges.add(
                inner_state_machine.start_state)
            if repetition.min == 0:
                state_machine.start_state.epsilon_edges.add(
                    state_machine.end_state)
            else:
                repetition_min -= 1

        elif repetition.max > repetition_min:
            state_machines = [
                copy.deepcopy(child_state_machine)
                for i in xrange(repetition.max - repetition_min)
            ]
            for state_machine in state_machines:
                state_machine.start_state.epsilon_edges.add(
                    state_machine.end_state)
            state_machine = NonDeterministicFinite.concatenate(state_machines)

        # Prepend minimal repetition
        if repetition_min > 0:
            head_state_machines = [
                copy.deepcopy(child_state_machine)
                for i in xrange(repetition_min)
            ]
            head_state_machine = NonDeterministicFinite.concatenate(
                head_state_machines)
            if state_machine is None:
                state_machine = head_state_machine
            else:
                state_machine = NonDeterministicFinite.concatenate(
                    [head_state_machine, state_machine])

        self.state_machines.append(state_machine)
 def visit_literal(self, literal):
     """
     Converts a regular expression literal into an NFA with a transition for each contained character.
     Pushes the NFA onto a stack.
     @param literal: a Regex.Literal object representing the literal to convert.
     """
     state_machine = NonDeterministicFinite()
     state_machine.start_state.edges[state_machine.end_state].update(
         literal.characters)
     self.state_machines.append(state_machine)
 def visit_alternation(self, alternation):
     """
     Converts an alternated (separated by "|") regular expressions into an equivalent NFA graph.
     Pushes the graph onto a stack.
     @param alternation: a Regex.Alternation object representing the set of alternated expressions.
     """
     child_state_machines = []
     for child in alternation.children:
         child.accept(self)
         child_state_machines.append(self.state_machines.pop())
     self.state_machines.append(NonDeterministicFinite.alternate(child_state_machines))
 def visit_alternation(self, alternation):
     """
     Converts an alternated (separated by "|") regular expressions into an equivalent NFA graph.
     Pushes the graph onto a stack.
     @param alternation: a Regex.Alternation object representing the set of alternated expressions.
     """
     child_state_machines = []
     for child in alternation.children:
         child.accept(self)
         child_state_machines.append(self.state_machines.pop())
     self.state_machines.append(
         NonDeterministicFinite.alternate(child_state_machines))
 def visit_concatenation(self, concatenation):
     """
     Converts a concatenated set of regular expressions into an equivalent NFA graph.
     Pushes the graph onto a stack.
     @param concatenation: a Regex.Concatenation object representing the set of concatenated expressions.
     """
     child_state_machines = []
     for child in concatenation.children:
         child.accept(self)
         child_state_machines.append(self.state_machines.pop())
     
     self.state_machines.append(NonDeterministicFinite.concatenate(child_state_machines))
 def visit_repetition(self, repetition):
     """
     Converts a repeated regular exprsesion into an equivalent NFA.
     Pushes the NFA onto a stack.
     @param repetition: a Regex.Repetition object representing the repeated expression to convert.
     """
     state_machine = None
     repetition.child.accept(self)
     child_state_machine = self.state_machines.pop()
     
     # Create optional 0 to max-min
     repetition_min = repetition.min
     if repetition.max == Regex.Repetition.Infinity:
         # Kleene star
         inner_state_machine = copy.deepcopy(child_state_machine)
         state_machine = NonDeterministicFinite()
         state_machine.start_state.epsilon_edges.add(inner_state_machine.start_state)
         inner_state_machine.end_state.epsilon_edges.add(state_machine.end_state)
         inner_state_machine.end_state.epsilon_edges.add(inner_state_machine.start_state)
         if repetition.min == 0:
             state_machine.start_state.epsilon_edges.add(state_machine.end_state)
         else:
             repetition_min -= 1
         
     elif repetition.max > repetition_min:
         state_machines = [copy.deepcopy(child_state_machine) for i in xrange(repetition.max - repetition_min)]
         for state_machine in state_machines:
             state_machine.start_state.epsilon_edges.add(state_machine.end_state)
         state_machine = NonDeterministicFinite.concatenate(state_machines)
         
     # Prepend minimal repetition 
     if repetition_min > 0:
         head_state_machines = [copy.deepcopy(child_state_machine) for i in xrange(repetition_min)]
         head_state_machine = NonDeterministicFinite.concatenate(head_state_machines)
         if state_machine is None:
             state_machine = head_state_machine
         else:
             state_machine = NonDeterministicFinite.concatenate([head_state_machine, state_machine])
             
     self.state_machines.append(state_machine)
 def visit_literal_except(self, literal_except):
     """
     Converts a regular expression inverse literal ([^...]) into an equivalent NFA.
     Pushes the NFA onto a stack.
     @param literal_except: a Regex.LiteralExcept object representing the inverse literal to convert.
     """
     state_machine = NonDeterministicFinite()
     state_machine.start_state.edges[state_machine.end_state].add(
         1, 0x10FFFF)
     state_machine.start_state.edges[
         state_machine.end_state].difference_update(
             literal_except.characters)
     self.state_machines.append(state_machine)
    def visit_concatenation(self, concatenation):
        """
        Converts a concatenated set of regular expressions into an equivalent NFA graph.
        Pushes the graph onto a stack.
        @param concatenation: a Regex.Concatenation object representing the set of concatenated expressions.
        """
        child_state_machines = []
        for child in concatenation.children:
            child.accept(self)
            child_state_machines.append(self.state_machines.pop())

        self.state_machines.append(
            NonDeterministicFinite.concatenate(child_state_machines))