def generateAP(self, string): stack = Stack() marker = True returnTransition = [] returnProductions = [] newTransition = '' newString = '' # Variables de graphviz arrayEdges = [] nodeTemp = '' nodeParent = {} nodesParents = [] dot = Digraph(comment=f"{self.getName()}", format="png") dot.attr(rankdir='TB', size='8,5') dot.attr('node', shape='circle') print(f"Cadena a evaluar: {string}") print(f"En la pila hay {stack.getItems()}") self.generateReport('epsilon', string, self.transitions[0]['string']) newString = string j = 65 for transition in self.transitions: if transition["first"]["from"] == "p": stack.push(transition["last"]["input"]) # Hacemos el grafo un estado inicial dot.node(chr(j), transition["last"]["input"]) if stack.getLastItem() in self.getNonTerminals(): nodeParent['key'] = chr(j) nodeParent['value'] = stack.getLastItem() nodesParents.append(nodeParent) nodeParent = {} nodeTemp = chr(j) j = j + 1 break newTransition = transition['string'] if ' ' in string: string = string.split(' ') i = 0 for letter in string: indicator = False if i >= 2: string = string[1:] newString = list(string) if len(string) > 0: newString.pop(0) if letter in self.terminals: for transition in self.transitions: if transition["first"]["from"] == "q": if stack.getLastItem( ) == transition["first"]["output"]: if letter == transition['last']['input'][0]: newTransition = transition['string'] stack.pop() word = transition["last"]["input"][::-1] for l in word: indicator = True stack.push(l) if stack.getItems() == 'epsilon': marker = False print("Cadena Invalida") returnTransition.append("Cadena Invalida") break else: continue else: for trans in self.transitions: if (trans["first"]["output"] == stack.getLastItem()): if (letter == trans["last"]["input"][0] or letter == trans["last"]["input"]): newTransition = trans['string'] # Asignamos el siguiente contador a la letra y # lo metemos en el array concatenado a la letra temporal dot.node(chr(j), stack.getLastItem()) # Guardamos los nodos padres clave: valor en un array if stack.getLastItem( ) in self.getNonTerminals(): nodeParent['key'] = chr(j) nodeParent[ 'value'] = stack.getLastItem() nodesParents.append(nodeParent) nodeParent = {} # Agregamos un nuevo nodo al array de nodos arrayEdges.append(nodeTemp + chr(j)) j = j + 1 stack.pop() if len(letter) > 1: stack.push(letter) else: word = trans["last"]["input"][::-1] for l in word: stack.push(l) print( f"Pila actual: {stack.getItems()}") self.generateReport( stack.getItems(), newString, newTransition) returnTransition.append( stack.getLastItem()) indicator = True break if trans["last"]["input"] == 'epsilon': # Mandamos un nodo con lo que sale dot.node(chr(j), letter) arrayEdges.append(nodeTemp + chr(j)) # Termino de nodo newTransition = trans['string'] self.generateReport( stack.getItems(), newString, newTransition) stack.pop() indicator = True break if trans["last"]["input"][ 0] in self.non_terminals: newTransition = trans['string'] self.generateReport( stack.getItems(), newString, newTransition) stack.pop() for l in trans["last"]["input"][::-1]: stack.push(l) indicator = True break if not indicator: marker = False break if letter == stack.getLastItem(): break if trans['first']['output'] == letter: break print(f"Pila actual: {stack.getItems()}") returnTransition.append(stack.getLastItem()) # self.generateReport(stack.getItems(), newString, newTransition) # if not indicator: # marker = False # break if stack.getItems() == 'epsilon': marker = False print("Cadena Invalida") returnTransition.append("Cadena Invalida") break if marker == False: break if letter == stack.getLastItem(): if stack.getLength() > 1: nodeChild = letter stack.pop() for parent in nodesParents: if stack.getLastItem() in parent['value']: dot.node(chr(j), nodeChild) arrayEdges.append(parent['key'] + chr(j)) nodeTemp = parent['key'] break if len(stack.getItems()) == 0: break else: print(f"La letra {letter} no existe en el alfabeto") returnTransition.append("Cadena Invalida") break i = i + 1 j = j + 1 if marker: if len(stack.getItems()) > 0: while True: if len(stack.getItems()) == 0: break for trans in self.transitions: if (trans["first"]["output"] == stack.getLastItem()): if trans['first']['readed'] == 'epsilon' or trans[ 'last']['input'] == 'epsilon': print(f"Pila actual: {stack.getItems()}") returnTransition.append(stack.getLastItem()) newTransition = trans['string'] self.generateReport(stack.getItems(), '--------', newTransition) stack.pop() break if marker: print('Cadena Valida') returnTransition.append("Cadena Valida") if len(stack.getItems()) == 0: self.generateReport('epsilon', '---------', 'q,epsilon,epsilon;f,epsilon') self.generateReport('-------', '---------', 'Aceptacion') else: self.generateReport(stack.getItems(), string, 'Aceptacion') else: print("Cadena Invalida") dot.edges(arrayEdges) dot.render(filename="three") return returnTransition