123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- # copyrigth Rodrigo Garcia strysg@riseu.net
- # This program is free software; you can redistribute it and/or modify it
- # under the terms of the GNU General Public Licence as published
- # by the Free Software Foundation; either version 3 of the Licence,
- # or (at your option) any later version.
- # Shutter is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- import re
- import collections
- class automata_cadenas:
- '''
- Automata generico que reconoce cadenas como expresiones
- regulares
- Ejemplo de Creacion funcion para la instruccion `mostrar':
- M1 = automata_cadenas(dict_FTrans, estadosFinales)
-
- Donde:
- dict_FTrans= {
- 0 : [("mostrar ",1)],
- 1 : [("^[a-zA-Z][a-zA-Z0-9_]*",6), (r'^"',2)],
- 2 : [('^\W\"', 4)],
- 4 : [("\."),5],
- 6 : [("\."),5],
- }
-
- En este diccionario estan las reglas que acepta cad estado
- la llave en el diccionario es el estado en que parte,
- [] es la lista de reglas, cada regla contiene una tupla
- () donde el primer elemento es la expresion regular que
- reconoce el automata y el segundo elemento es el estado
- al que se mueve al aceptar la expresion regular.
- estadosFinales = [5]
- Es la lista de estados finales del automata.
- '''
- K = []
- q0 = 0
- F = []
- estados_recorridos = []
- estado = 0
- evaluada = ''
- dict_FTrans = {}
-
- def __init__(self, dict_FTrans, estadosFinales):
- self.F = estadosFinales
- for f in self.F:
- self.K.append(f)
- for k in dict_FTrans.keys():
- self.K.append(k)
- self.q0 = 0
- self.estado = 0
- self.evaluada = ''
- self.dict_FTrans = dict_FTrans
-
- def FTrans(self, cadena): # evalua la funcion de transicion
- self.evaluada = cadena
- cad = cadena
- partidas = []
- reglas_cadena_llegadas = []
- # ordenando por clave (estado de partida)
- dict_FTrans_ordenado = collections.OrderedDict(sorted(self.dict_FTrans.items()))
-
- # haciendo el recorrido
- while (self.estado not in self.F) and (self.estado != -1):
- # se busca el estado correspondiente y se guarda sus reglas para
- # estados siguientes
- regla_actual = dict_FTrans_ordenado[self.estado]
-
- # comprobando reglas de transicion de ese estado
- for regla in regla_actual:
- estado_siguiente = regla[1]
-
- er = regla[0] # expresion regular
- m = re.search(er, cad)
-
- if m is not None:
- self.estados_recorridos.append(self.estado)
- # "consumiendo" cadena
- cad = cad[len(m.group(0)):]
- self.estado = estado_siguiente
- break
- else:
- self.estado = -1
- return self.estado
- def aceptado(self):
- ''' Devuelve True si la ultima expresion evaluada por
- este automata ha sido aceptada'''
- if self.estado in self.F:
- return True
- return False
-
- class M_mostrar:
- '''
- Automata que reconoce:
- mostrar "texto cualquiera".
- mostrar variable.
- '''
- K = [0,1,2,3,4,5,6] # conjunto finito de estados
- q0 = 0 # estado inicial
- F = [5] # estados finales
- Alfabeto = "" # cadena
- estados_recorridos = []
- estado = 0
- evaluada = ''
- def FTrans(self, cadena): # funcion de trancision
- ''' Funcion de trancision retorna un estado
- Se sabe que el automata ha aceptado la cadena
- si y solo si la FTrans termina en un estado final'''
- self.evaluada = cadena
- cad = cadena
- while (self.estado not in self.F) and (self.estado != -1):
- if self.estado == self.q0:
- if cad.startswith("mostrar "):
- self.estados_recorridos.append(0)
- cad = cad[len("mostrar "):]
- self.estado = 1
- else:
- self.estado = -1
- elif self.estado == 1:
- W = "^[a-zA-Z][a-zA-Z0-9_]*"
- m = re.search(W,cad)
- if cad.startswith('"'):
- self.estados_recorridos.append(1)
- cad = cad[1:]
- self.estado = 2
- elif m is not None:
- self.estados_recorridos.append(1)
- cad = cad[len(m.group(0)):]
- self.estado = 6
- else:
- self.estado = -1
- elif self.estado == 2:
- if cad.find('"') != -1:
- self.estados_recorridos.append(2)
- cad = cad[cad.find('"')+1:]
- #self.estado = 3
- self.estados_recorridos.append(3)
- self.estado = 4
- else:
- self.estado = -1
- elif self.estado == 4 or self.estado == 6:
- self.estados_recorridos.append(self.estado)
- if cad == ".":
- self.estado = 5
- print (cadena[len("mostrar "):-1])
- else:
- self.estado = -1
- return self.estado
-
- def aceptado(self):
- ''' Devuelve True si la ultima expresion evaluada por
- este automata ha sido aceptada'''
- if self.estado in self.F:
- return True
- return False
- def mostrar_errores(self):
- ''' Segun la ultima cadena evaluada muestra
- en que estado del automata se ha generado el error'''
- ultimoEstadoAlcanzado = self.estados_recorridos[-1]
- def __init__(self):
- self.q0 = 0
- self.estados_recorridos = []
- self.evaluada = ''
- class M_declarar_enteros:
- K = [0,1,2,3,4,5] # conjunto finito de estados
- q0 = 0 # estado inicial
- F = [5] # estados finales
- Alfabeto = "" # cadena
- estados_recorridos = []
- estado = 0
- evaluada = ''
- def FTrans(self, cadena):
- self.evaluada = cadena
- cad = cadena
- while (self.estado not in self.F) and (self.estado != -1):
- if self.estado == self.q0:
- if cad.startswith("entero "):
- self.estados_recorridos.append(0)
- cad = cad[len("entero "):]
- self.estado = 1
- else:
- self.estado = -1
- elif self.estado == 1:
- W = "^[a-zA-Z][a-zA-Z0-9_]*"
- m = re.search(W,cad)
- if m is not None:
- self.estados_recorridos.append(1)
- cad = cad[len(m.group(0)):]
- self.estado = 2
- else:
- self.estado = -1
- elif self.estado == 2:
- er = "(= )|( =)|( = )|="
- m = re.search(er,cad)
-
- if m is not None:
- self.estados_recorridos.append(self.estado)
- cad = cad[len(m.group(0)):]
- self.estado = 3
- else:
- self.estado = -1
- elif self.estado == 3:
- er = "[0-9]+"
- m = re.search(er,cad)
- if m is not None:
- self.estados_recorridos.append(self.estado)
- self.estado = 4
- cad = cad[len(m.group(0)):]
- else:
- self.estado = -1
- elif self.estado == 4:
- if cad == '.':
- self.estados_recorridos.append(self.estado)
- self.estado = 5
- # estado final
- print(cadena)
- else:
- self.estado = -1
- return self.estado
-
- def aceptado(self):
- ''' Devuelve True si la ultima expresion evaluada por
- este automata ha sido aceptada'''
- if self.estado in self.F:
- return True
- return False
- def mostrar_errores(self):
- ''' Segun la ultima cadena evaluada muestra
- en que estado del automata se ha generado el error'''
- ultimoEstadoAlcanzado = self.estados_recorridos[-1]
-
|