예제 #1
0
    def visitLanguage(self, ctx: RegularParser.LanguageContext):
        # Construct the final NFA by connecting the terms to single start and final states
        # Take note of each concatenated machine
        concatenated_machines = []

        for termComponent in ctx.getChildren():
            if type(termComponent) is RegularParser.TermContext:
                concatenated_machines.append(self.visitTerm(termComponent))

        # Create a new initial state
        new_init_state = Machine.assign_state_name()

        # Create a new final state
        new_final_state = Machine.assign_state_name()

        # Create a new state table, merging all the state tables of the concatenated machines, then connecting the new
        # initial state to all the old initial states of the concatenated machines, then finally connecting the old
        # final states of the machines to the new final state
        new_state_table = {new_init_state: {}, new_final_state: {}}

        for concatenated_machine in concatenated_machines:
            # Merge its state table with the new state table
            new_state_table.update(concatenated_machine.state_table)

            # Create an epsilon transition from the new initial state to the old initial state of the concatenated
            # machine
            new_state_table[new_init_state][Machine.assign_epsilon_transition(
            )] = concatenated_machine.init_state

            # Create an epsilon transition from the old final state of the concatenated machine to the new final state
            new_state_table[concatenated_machine.final_states[0]][
                Machine.assign_epsilon_transition()] = new_final_state

        return Machine(concatenated_machines[0].alphabet, new_state_table,
                       new_init_state, [new_final_state])
예제 #2
0
    def visitKleeneClosure(self, ctx: RegularParser.KleeneClosureContext):
        # Get the operand of the Kleene closure
        # And take note of its machine form
        if ctx.symbol() is not None:
            # Get the symbol's corresponding machine
            machine = self.visitSymbol(ctx.symbol())
        else:
            # Get the parenthesized language's corresponding machine
            machine = self.visitParenthesizedLanguage(
                ctx.parenthesizedLanguage())

        # Then construct the appropriate Kleene closure form from the given machine
        # Get the machine's state table
        state_table = machine.state_table

        # Construct a new initial state
        new_init_state = Machine.assign_state_name()

        # Construct a new final state
        new_final_state = Machine.assign_state_name()

        # Construct a new state table for what would be the Kleene closure form of the machine
        new_state_table = {new_init_state: {}, new_final_state: {}}

        # Merge the operand state table with the new state table
        new_state_table.update(state_table)

        # Create an epsilon transition from the final state to the initial state of the operand machine
        new_state_table[machine.final_states[0]][
            Machine.assign_epsilon_transition()] = machine.init_state

        # Create an epsilon transition from the new initial state to the old initial state
        new_state_table[new_init_state][
            Machine.assign_epsilon_transition()] = machine.init_state

        # Create an epsilon transition from the old final state to the new final state
        new_state_table[machine.final_states[0]][
            Machine.assign_epsilon_transition()] = new_final_state

        # Finally, create an epsilon transition from the new initial state to the new final state
        new_state_table[new_init_state][
            Machine.assign_epsilon_transition()] = new_final_state

        return Machine(machine.alphabet, new_state_table, new_init_state,
                       [new_final_state])