-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
181 lines (151 loc) · 8.67 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#---------------------------------------Class-----------------------------------------
class Automata:
#Variables locales
nEstados=0 #Número de estados que tiene el autómata
estados = [] #Lista de estados del autómata
nFinales = 0 #Número de estados finales
estadosFinales = [] #Lista de estados finales
nCaracteres = 0 #Número de caracateres contenidos en el alfabeto
caracteres = [] #Lista correspondiente al alfabeto del automata
tabla = [] #Tabla de transiciones
estadoActual = [] #Estado o estados en los que se encuentra el autómata
aux = [] #Variable auxiliar para volcar valores de estados de forma temporal
def show_info(self): #Muestrar la información del automata leido
print(self.nEstados)
print(self.estados)
print(self.nFinales)
print(self.estadosFinales)
print(self.nCaracteres)
print(self.caracteres)
print("Tabla de Transiciones:")
for i in range(int(self.nEstados)):
print(self.tabla[i])
def process_empty_word(self,estado): #Procesamiento de la cadena vacía
index = self.estados.index(estado) #Obtengo la fila en la que se encuentra el estado
if self.tabla[index][-1] != ' ': #Si se llega a traves de la cadena vacía a un estado:
self.aux.append(self.estadoActual)
for i in self.tabla[index][-1]:
if i != ' ':
self.aux.append(i)
self.process_empty_word(i)
aux2 = []
for ind in self.aux:
aux2.append(ind)
flatEstates = [] #Convertir la lista de listas en una lista
for elem in aux2:
flatEstates.extend(elem)
self.estadoActual = flatEstates
return 1
else:
return 0
def process_several_states(self,char):
aux = []
for i in self.estadoActual:
if (self.process_empty_word(i)):
self.aux.clear()
self.estadoActual = list(set(self.estadoActual)) # Eliminación de las repeticiones
for i in self.estadoActual: # Hay que valorar todos los posibles estados actuales en los que nos encontramos
indexState = self.estados.index(i) # Obtención del valor del indice del estado actual
indexChar = self.caracteres.index(char) # Obtención del valor del indice del caracter que se esta procesando
nE = self.tabla[indexState][indexChar] # Obtengo el siguiente valor dado
nE = nE.split(" ")
for index in nE:
if index != '':
aux.append(index)
self.estadoActual = aux
def next_state(self,char,mark): #Función que dado un caractar nos devuelve el estado siguiente del automata
if (mark>0 and len(self.estadoActual)>1):
self.process_several_states(char)
else:
if mark == 0:
if (self.process_empty_word(self.estadoActual)):
self.aux.clear()
self.estadoActual = list(set(self.estadoActual))
self.process_several_states(char)
return
else:
indexState = self.estados.index(self.estadoActual) # Obtención del valor del indice del estado actual
else:
if(self.process_empty_word(self.estadoActual[0])):
self.aux.clear()
self.estadoActual = list(set(self.estadoActual))
self.process_several_states(char)
return
else:
indexState = self.estados.index(self.estadoActual[0]) # Obtención del valor del indice del estado actual
indexChar = self.caracteres.index(char) # Obtención del valor del indice del caracter que se esta procesando
nE = self.tabla[indexState][indexChar] # Obtengo el siguiente valor dado
nE = nE.split(" ")
aux = []
for index in nE:
if index != '':
aux.append(index)
self.estadoActual = aux
def process_word(self, word): #Funcón que procesa la palabra que entra en el autómata
self.estadoActual = self.estados[0]
print(self.estadoActual, end=", ")
mark = 0
for x in word:
if not self.caracteres.__contains__(x): #Si alguno de los caracteres no pertenece al alfabeto se lanza un mensaje de error
print("Alguno de los caracteres no pertenece al Alfabeto")
break
else:
self.next_state(x,mark)
mark+=1
for i in self.estadoActual: #Vuelvo a analizar los estados en los que me encuentro con la cadena vacía
if (self.process_empty_word(i)):
self.aux.clear()
self.estadoActual = list(set(self.estadoActual)) # Eliminación de las repeticiones
self.estadoActual.sort() # Ordeno por orden alfabético
print(self.estadoActual, end=", ")
def reset(self):
self.estadoActual = self.estados[0]
#------------------------------------Fin Class-------------------------------------------
#----------------------------------------------Funciones------------------------------------
# Función encargada de leer el fichero y guardar las casteristicas del autómata
def read_file(Automata,file):
fichero = open(file,"r") #Apertura del fichero con la descripción del autómata
lines = fichero.readlines() #Guardo las líneas del fichero en la variables lines
aux = 0 #Variable para saber en que linea estoy leyendo
for line in lines: #Recorro las lineas con la variables line
line = line.replace('\n',"") #Elimino todos los \n de las líneas
if line[0]=='#': #Si la linea empieza por #
x=line.split(' ') #Separo por espacios
for i in x:
if (i[0]=='#' and aux == 0): #primera línea, primer elemento --> nº estados
a=i.replace("#","")
automata.nEstados = a
elif aux == 0: #Resto de elementos de la primera línea -->Estados
automata.estados.append(i)
if (i[0]=='#' and aux == 1): #segunda línea, primer elemento --> nº estados Finales
b=i.replace("#","")
automata.nFinales = b
elif aux == 1: #Resto de elementos de la segunda línea -->Estados Finales
automata.estadosFinales.append(i)
if (i[0]=='#' and aux == 2): #tercera línea, primer elemento --> nº caracteres
c=i.replace("#","")
automata.nCaracteres = c
elif aux == 2: #Resto de elementos de la tercera línea -->Caracteres
automata.caracteres.append(i)
aux = aux + 1 #Siguiente línea
elif (line[0]!='#' and line[0]!='-'): #Parte de la tabla de transiciones
x=line.split('#') #Separo por #
for i in (automata.nCaracteres):
del x[-1] #elimino el ultimo caracter ""
automata.tabla.append(x) #añado el elemento a la tabla
#----------------------------------------------Fin funciones----------------------------------------------------
# -------------------------------------------------Main---------------------------------------------------------
while(True):
print("")
print("______________________________________")
print("| IMPLEMENTADOR DE AUTOMATAS FINITOS |")
print("______________________________________")
word = input("Palabra a procesar (o 'q' para salir): ") #Palabra de prueba: 152ac22bd1c2c
automata = Automata() # Instacia de la clase autómata
if word == "q":
break
else:
read_file(automata,"definicionAutomata4.txt")
#automata.show_info() #Descomentar si se quiere ver la información del automata definido en el fichero
automata.process_word(word)
automata.reset() #Reseteo el estado actual al inicial