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)
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)
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")
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")