Example #1
0
def main():

    classes = {epsilon: frozenset([]), "a": frozenset(["a"])}

    q0 = nfastate.NFAState(0, True)
    q1 = nfastate.NFAState(1, True)
    q2 = nfastate.NFAState(2)
    q3 = nfastate.NFAState(3)
    q4 = nfastate.NFAState(4, True)
    q5 = nfastate.NFAState(5)
    q6 = nfastate.NFAState(6)
    q7 = nfastate.NFAState(7)
    q8 = nfastate.NFAState(8)

    q0.addTransition(epsilon, 1)
    q0.addTransition(epsilon, 4)

    q1.addTransition("a", 2)
    q2.addTransition("a", 3)
    q3.addTransition("a", 1)

    q4.addTransition("a", 5)
    q5.addTransition("a", 6)
    q6.addTransition("a", 7)
    q7.addTransition("a", 8)
    q8.addTransition("a", 4)

    states = {0: q0, 1: q1, 2: q2, 3: q3, 4: q4, 5: q5, 6: q6, 7: q7, 8: q8}

    nfa = NFA(classes, states)

    dfa = DFA()
    dfa.buildFromNFA(nfa)
    dfa.writeListing(sys.stdout)
Example #2
0
def main():

    q0 = nfastate.NFAState(0)
    q1 = nfastate.NFAState(1, True)
    q2 = nfastate.NFAState(2)
    q3 = nfastate.NFAState(3)
    q4 = nfastate.NFAState(4, True)
    q5 = nfastate.NFAState(5)
    q6 = nfastate.NFAState(6)
    q7 = nfastate.NFAState(7)
    q8 = nfastate.NFAState(8)

    classes = {
        "a": frozenset(["a"]), 
        "epsilon": frozenset([])
    }

    q0.addTransition("epsilon", 1)
    q0.addTransition("epsilon", 4)

    q1.addTransition("a", 2)

    q2.addTransition("a", 3)

    q3.addTransition("a", 1)

    q4.addTransition("a", 5)

    q5.addTransition("a", 6)

    q6.addTransition("a", 7)

    q7.addTransition("a", 8)

    q8.addTransition("a", 4)

    nfa = NFAStateMachine({ 0: q0, 1: q1, 2: q2, 3: q3, 4: q4, 5: q5, 6: q6, 7: q7, 8: q8 }, 0, classes)

    s = input("Please enter a string of a(s) (type done to quit): ").strip()

    while s!="done":

        strm = streamreader.StreamReader(io.StringIO(s))

        if nfa.accepts(strm):
            print("The string is accepted by the finite state machine.")
        else:
            print("The string is not accepted.")

        s = input("Please enter a string of a(s) (type done to quit): ").strip()

    print("Program Completed.")
def main():

    q0 = nfastate.NFAState(0)
    q1 = nfastate.NFAState(1)
    q2 = nfastate.NFAState(2)
    q3 = nfastate.NFAState(3)
    q4 = nfastate.NFAState(4, True)
    q5 = nfastate.NFAState(5)
    q6 = nfastate.NFAState(6)
    q7 = nfastate.NFAState(7)
    q8 = nfastate.NFAState(8)
    q9 = nfastate.NFAState(9)
    q10 = nfastate.NFAState(10, True)

    classes = {epsilon: frozenset([]), 'a': frozenset(['a'])}

    q0.addTransition(epsilon, 1)
    q0.addTransition(epsilon, 5)
    q1.addTransition("a", 2)
    q2.addTransition("a", 3)
    q3.addTransition("a", 4)
    q4.addTransition("a", 2)
    q5.addTransition("a", 6)
    q6.addTransition("a", 7)
    q7.addTransition("a", 8)
    q8.addTransition("a", 9)
    q9.addTransition("a", 10)
    q10.addTransition("a", 6)

    states = {
        0: q0,
        1: q1,
        2: q2,
        3: q3,
        4: q4,
        5: q5,
        6: q6,
        7: q7,
        8: q8,
        9: q9,
        10: q10
    }

    # classes = {epsilon: frozenset([]), "zero": frozenset(
    #     [0]), "one": frozenset([1])}

    # q0 = nfastate.NFAState(0)
    # q1 = nfastate.NFAState(1, 1)
    # q2 = nfastate.NFAState(2)

    # q0.addTransition("zero", 1)
    # q0.addTransition("one", 1)
    # q1.addTransition("one", 1)
    # q1.addTransition("zero", 0)
    # q1.addTransition("zero", 2)
    # q1.addTransition(epsilon, 2)
    # q2.addTransition("one", 1)

    # states = {0: q0, 1: q1, 2: q2}

    nfa = NFA(classes, states)

    dfa = DFA()
    dfa.buildFromNFA(nfa)
    dfa.writeListing(sys.stdout)
Example #4
0
    def buildMachine(self, instream):
        def operate(op, opStack, stateStack):

            #print "Operating..."
            #print "The operator is ", op.getOpChar()

            if (op.getOpChar() == '('):
                opStack.push(Operator('('))
                return

            while op.precedence() <= opStack.peek().precedence():
                topOp = opStack.pop()

                opChar = topOp.getOpChar()

                #print "The topOp is ", opChar

                if opChar == '|':
                    b1, b2 = stateStack.pop()
                    a1, a2 = stateStack.pop()
                    firstId = newState()
                    secondId = newState()
                    self.states[firstId].addTransition(epsilon, a1)
                    self.states[firstId].addTransition(epsilon, b1)
                    self.states[a2].addTransition(epsilon, secondId)
                    self.states[b2].addTransition(epsilon, secondId)
                    stateStack.push((firstId, secondId))
                elif opChar == '.':
                    b1, b2 = stateStack.pop()
                    a1, a2 = stateStack.pop()
                    firstId = newState()
                    secondId = newState()
                    self.states[firstId].addTransition(epsilon, a1)
                    self.states[a2].addTransition(epsilon, b1)
                    self.states[b2].addTransition(epsilon, secondId)
                    stateStack.push((firstId, secondId))
                elif opChar == '*':
                    a1, a2 = stateStack.pop()
                    firstId = newState()
                    secondId = newState()
                    self.states[firstId].addTransition(epsilon, a1)
                    self.states[firstId].addTransition(epsilon, secondId)
                    self.states[a2].addTransition(epsilon, secondId)
                    self.states[secondId].addTransition(epsilon, firstId)
                    stateStack.push((firstId, secondId))
                elif opChar == '(':
                    # do nothing
                    if (op.getOpChar() == ')'):
                        return

            opStack.push(op)

        def evaluateRegExpression(reader):
            opStack = stack.Stack()
            stateStack = stack.Stack()

            opStack.push(Operator("("))

            while not reader.peek(";"):
                token = reader.getToken()
                if token in "(+|.*)":
                    #if reader.peek("(") or reader.peek(")") or reader.peek(".") or reader.peek("*") or reader.peek("|"):
                    op = Operator(token)
                    operate(op, opStack, stateStack)

                else:  # it is a character class set name
                    firstId = newState()
                    secondId = newState()
                    self.states[firstId].addTransition(token, secondId)
                    stateStack.push((firstId, secondId))

            operate(Operator(')'), opStack, stateStack)

            if (not opStack.isEmpty()):
                raise Exception("Malformed Regular Expression")

            return stateStack.pop()

        def newState():
            self.numStates += 1
            aState = nfastate.NFAState(self.numStates)
            self.states[self.numStates] = aState
            return self.numStates

        reader = streamreader.StreamReader(instream)
        startStates = []

        reader.skipComments()

        if reader.peek("#CLASSES"):
            #print("Found #CLASSES")
            reader.readUpTo("\n")
            while (not reader.peek("#")):
                # The "#" marks the beginning of the next section. Either KEYWORDS or TOKENS. KEYWORDS are optional.
                reader.skipComments()

                # We could have keywords right after a comment. So if keyword section is found, don't read
                # any more character classes.
                if not reader.peek("#KEYWORDS"):
                    className = reader.readIdentifier()
                    reader.readUpTo("=")
                    if reader.peek("^"):
                        anticlass = True
                        reader.readUpTo("^")
                        classSet = orderedcollections.OrderedSet(range(256))
                    else:
                        anticlass = False
                        classSet = orderedcollections.OrderedSet()

                    done = False

                    while not done:

                        if reader.peek("'"):
                            # Found a character constant
                            reader.readUpTo("'")
                            character = reader.readUpTo("'")[0]
                            #print(character)
                            ordVal = ord(character)

                        else:
                            ordVal = reader.readInt()

                        # Add the end of the range if there is a range of characters
                        if reader.peek(".."):
                            reader.readUpTo("..")

                            if reader.peek("'"):
                                reader.readUpTo("'")
                                character = reader.readUpTo("'")[0]
                                #print(character)
                                lastOrdVal = ord(character)
                            else:
                                lastOrdVal = reader.readInt()
                        else:
                            lastOrdVal = ordVal

                        # Now build the set
                        for i in range(ordVal, lastOrdVal + 1):
                            if anticlass:
                                classSet.remove(i)
                            else:
                                classSet.add(i)

                        if reader.peek(","):
                            reader.readUpTo(",")
                        else:
                            done = True

                    #print(className)

                    #Add the class to the class dictionary
                    self.classes[className] = classSet

                    reader.readUpTo(";")

        #print("These are the classes")
        #print(self.classes)
        # keyword and token id numbers
        idnum = 0
        keywordsPresent = False

        if reader.peek("#KEYWORDS"):
            reader.readUpTo("#KEYWORDS")
            keywordsPresent = True
            reader.skipComments()

            while (not reader.peek("#TOKENS")):
                #idnum = reader.readInt()
                #reader.readUpTo(":")
                reader.readUpTo("'")
                keyword = reader.readUpTo("'")[:-1].strip()
                #print(idnum,keyword)
                self.keywords[keyword] = idnum
                idnum += 1
                reader.readUpTo(";")
                reader.skipComments()

        #print(self.keywords)
        reader.readUpTo("#TOKENS")
        reader.skipComments()
        readingFirstToken = True

        while not (reader.peek("#PRODUCTIONS") or reader.peek("#END")
                   or reader.peek("#DEFINITIONS")):
            #idnum = reader.readInt()
            #reader.readUpTo(":")
            if reader.peek("'"):
                # Then the token was specified as a string like this:
                # '>=';
                reader.readUpTo("'")
                token = reader.readUpTo("'")[:-1].strip()
                previousId = newState()
                startStateId = previousId

                for c in token:
                    nextId = newState()
                    classSet = orderedcollections.OrderedSet([ord(c)])
                    if not (c in self.classes and self.classes[c] == classSet):
                        self.classes[c] = classSet
                    self.states[previousId].addTransition(c, nextId)
                    previousId = nextId

                self.states[nextId].setAccepting(idnum)
                startStates.append(startStateId)
                reader.readUpTo(";")
                self.tokens[idnum] = token
                idnum += 1
                if readingFirstToken and keywordsPresent:
                    raise Exception(
                        "First Token must be identifier token for matching keywords!"
                    )

            else:
                # The token was specified as a regular expression like this:
                # identifier = letter.(letter|digit)*;

                name = reader.readUpTo("=")[:-1].strip()
                self.tokens[idnum] = name
                if readingFirstToken:
                    self.firstTokenId = idnum
                    readingFirstToken = False

                startStateId, stopStateId = evaluateRegExpression(reader)

                self.states[stopStateId].setAccepting(idnum)
                idnum += 1
                startStates.append(startStateId)

                reader.readUpTo(";")
                reader.skipComments()

        # Create a 0th State as the start state
        startState = nfastate.NFAState(0)
        self.numStates += 1
        self.states[0] = startState

        for startId in startStates:
            self.states[0].addTransition(epsilon, startId)

        self.startStateId = 0

        reader.readUpTo("#END")
Example #5
0
 def newState():
     self.numStates += 1
     aState = nfastate.NFAState(self.numStates)
     self.states[self.numStates] = aState
     return self.numStates
    def buildMachine(self, instream):

        #######################################################################
        # The newState function should be called to create any new state. It enters
        # the state information into the self.states dictionary for use later. Then
        # it returns the state Id (its state number) of the newly created state.
        #######################################################################

        def newState():
            self.numStates += 1
            aState = nfastate.NFAState(self.numStates)
            self.states[self.numStates] = aState
            return self.numStates

        #######################################################################
        # The operate function is given an:
        #   op : the operator
        #
        #   opStack: the stack of operators
        #
        #   stateStack: the stack of first,last states (which is the operand stack)
        #   the function does not return anything. Instead it operates on the two
        #   stacks as described in the two stack calculator algorithm.
        #
        # For each new state be sure to call the newState() function to enter
        # the new state in the self.states dictionary correctly.
        #######################################################################

        def operate(op, opStack, stateStack):
            precedence = {'(': 0, '|': 1, '.': 2, '*': 3, ')': 0}

            if op == '(':
                opStack.push(op)
                return None
            elif opStack.isEmpty():
                return None
            else:
                topOp = opStack.pop()
                opStack.push(topOp)
                while precedence[op] <= precedence[topOp]:
                    topOp = opStack.pop()
                    if topOp == '*':
                        q0ID, q1ID = stateStack.pop()

                        startStateID = newState()
                        endStateID = newState()
                        startState = self.states[startStateID]
                        endState = self.states[endStateID]

                        q0 = self.states[q0ID]
                        q1 = self.states[q1ID]

                        startState.addTransition(epsilon, q0ID)
                        startState.addTransition(epsilon, q1ID)
                        q1.addTransition(epsilon, endStateID)
                        endState.addTransition(epsilon, startStateID)

                        stateStack.push((startStateID, endStateID))

                    elif topOp == '.':
                        q0ID, q1ID = stateStack.pop()

                        startStateID = newState()
                        endStateID = newState()
                        startState = self.states[startStateID]
                        endState = self.states[endStateID]

                        q0 = self.states[q0ID]
                        q1 = self.states[q1ID]

                        startState.addTransition(epsilon, q0ID)
                        q1.addTransition(epsilon, endStateID)

                        stateStack.push((startStateID, endStateID))

                    elif topOp == '|':
                        q0ID, q1ID = stateStack.pop()
                        q2ID, q3ID = stateStack.pop()

                        startStateID = newState()
                        endStateID = newState()
                        startState = self.states[startStateID]
                        endState = self.states[endStateID]

                        q0 = self.states[q0ID]
                        q1 = self.states[q1ID]
                        q2 = self.states[q2ID]
                        q3 = self.states[q3ID]

                        q1.addTransition(epsilon, endStateID)
                        q3.addTransition(epsilon, endStateID)
                        startState.addTransition(epsilon, q0ID)
                        startState.addTransition(epsilon, q2ID)

                        stateStack.push((startStateID, endStateID))

                    elif topOp == '(':
                        return None

                opStack.push(op)

        #######################################################################
        # The evaluateRegExpression function is given the StreamReader called
        # reader and reads the regular expression and returns a tuple of start,stop state
        # for the expression. The stop state will be set to an accepting state by the code
        # that calls this function. When this function is called the regular expression must be
        # read. For instance in the line
        #
        # identifier = letter.(letter|digit)*;
        #
        # everything up to the = has already been read. You need to write code to read the
        # regular expression up to the semicolon (i.e. ;) and then run your regular expression
        # calculator code on it to build an NFA from this. To create each new state be sure to call
        # the newState() function to create it so the state gets entered into the self.states dictionary
        # correctly.
        #######################################################################

        def evaluateRegExpression(reader):
            operatorStack = stack.Stack()
            operandStack = stack.Stack()
            operatorStack.push('(')

            token = reader.getToken()
            while token != ';':
                if token in "(|.*":
                    operate(token, operatorStack, operandStack)
                else:
                    startStateID = newState()
                    endStateID = newState()
                    startState = self.states[startStateID]
                    endState = self.states[endStateID]

                    startState.addTransition(token, endStateID)
                    operandStack.push((startStateID, endStateID))

                token = reader.getToken()

            operate(')', operatorStack, operandStack)
            startStateID, endStateID = operandStack.pop()
            reader.unreadChar(';')
            return startStateID, endStateID

        ####################################################
        # This is the start of the buildMachine code here
        ####################################################

        reader = streamreader.StreamReader(instream)
        startStates = []

        reader.skipComments()

        if reader.peek("#CLASSES"):
            # print("Found #CLASSES")
            reader.readUpTo("\n")
            while (not reader.peek("#")):
                # The "#" marks the beginning of the next section. Either
                # KEYWORDS or TOKENS. KEYWORDS are optional.
                reader.skipComments()

                # We could have keywords right after a comment. So if keyword section is found, don't read
                # any more character classes.
                if not reader.peek("#KEYWORDS"):
                    className = reader.readIdentifier()
                    reader.readUpTo("=")
                    if reader.peek("^"):
                        anticlass = True
                        reader.readUpTo("^")
                        classSet = orderedcollections.OrderedSet(range(256))
                    else:
                        anticlass = False
                        classSet = orderedcollections.OrderedSet()

                    done = False

                    while not done:

                        if reader.peek("'"):
                            # Found a character constant
                            reader.readUpTo("'")
                            character = reader.readUpTo("'")[0]
                            # print(character)
                            ordVal = ord(character)

                        else:
                            ordVal = reader.readInt()

                        # Add the end of the range if there is a range of
                        # characters
                        if reader.peek(".."):
                            reader.readUpTo("..")

                            if reader.peek("'"):
                                reader.readUpTo("'")
                                character = reader.readUpTo("'")[0]
                                # print(character)
                                lastOrdVal = ord(character)
                            else:
                                lastOrdVal = reader.readInt()
                        else:
                            lastOrdVal = ordVal

                        # Now build the set
                        for i in range(ordVal, lastOrdVal + 1):
                            if anticlass:
                                classSet.remove(i)
                            else:
                                classSet.add(i)

                        if reader.peek(","):
                            reader.readUpTo(",")
                        else:
                            done = True

                    # print(className)

                    # Add the class to the class dictionary
                    self.classes[className] = classSet

                    reader.readUpTo(";")

        #print("These are the classes")
        # print(self.classes)
        # keyword and token id numbers
        idnum = 0
        keywordsPresent = False

        if reader.peek("#KEYWORDS"):
            reader.readUpTo("#KEYWORDS")
            keywordsPresent = True
            reader.skipComments()

            while (not reader.peek("#TOKENS")):
                #idnum = reader.readInt()
                # reader.readUpTo(":")
                reader.readUpTo("'")
                keyword = reader.readUpTo("'")[:-1].strip()
                # print(idnum,keyword)
                self.keywords[keyword] = idnum
                idnum += 1
                reader.readUpTo(";")
                reader.skipComments()

        # print(self.keywords)
        reader.readUpTo("#TOKENS")
        reader.skipComments()
        readingFirstToken = True

        while not (reader.peek("#PRODUCTIONS") or reader.peek("#END")
                   or reader.peek("#DEFINITIONS")):
            #idnum = reader.readInt()
            # reader.readUpTo(":")
            if reader.peek("'"):
                # Then the token was specified as a string like this:
                # '>=';
                reader.readUpTo("'")
                token = reader.readUpTo("'")[:-1].strip()
                previousId = newState()
                startStateId = previousId

                for c in token:
                    nextId = newState()
                    classSet = orderedcollections.OrderedSet([ord(c)])
                    if not (c in self.classes and self.classes[c] == classSet):
                        self.classes[c] = classSet
                    self.states[previousId].addTransition(c, nextId)
                    previousId = nextId

                self.states[nextId].setAccepting(idnum)
                startStates.append(startStateId)
                reader.readUpTo(";")
                self.tokens[idnum] = token
                idnum += 1
                if readingFirstToken and keywordsPresent:
                    raise Exception(
                        "First Token must be identifier token for matching keywords!"
                    )

            else:
                # The token was specified as a regular expression like this:
                # identifier = letter.(letter|digit)*;

                name = reader.readUpTo("=")[:-1].strip()
                self.tokens[idnum] = name
                if readingFirstToken:
                    self.firstTokenId = idnum
                    readingFirstToken = False

                # You must write the evaluateRegExpression(reader) function
                # that reads a regular expression using the reader StreamReader
                # object and returns its start and stop state ids.
                startStateId, stopStateId = evaluateRegExpression(reader)

                self.states[stopStateId].setAccepting(idnum)
                idnum += 1
                startStates.append(startStateId)

                reader.readUpTo(";")
                reader.skipComments()

        # Create a 0th State as the start state
        startState = nfastate.NFAState(0)
        self.numStates += 1
        self.states[0] = startState

        for startId in startStates:
            self.states[0].addTransition(epsilon, startId)

        self.startStateId = 0

        reader.readUpTo("#END")