automatas.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. # copyrigth Rodrigo Garcia strysg@riseu.net
  2. # This program is free software; you can redistribute it and/or modify it
  3. # under the terms of the GNU General Public Licence as published
  4. # by the Free Software Foundation; either version 3 of the Licence,
  5. # or (at your option) any later version.
  6. # Shutter is distributed in the hope that it will be useful,
  7. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. # GNU General Public License for more details.
  10. # You should have received a copy of the GNU General Public License
  11. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. import re
  13. import collections
  14. class automata_cadenas:
  15. '''
  16. Automata generico que reconoce cadenas como expresiones
  17. regulares
  18. Ejemplo de Creacion funcion para la instruccion `mostrar':
  19. M1 = automata_cadenas(dict_FTrans, estadosFinales)
  20. Donde:
  21. dict_FTrans= {
  22. 0 : [("mostrar ",1)],
  23. 1 : [("^[a-zA-Z][a-zA-Z0-9_]*",6), (r'^"',2)],
  24. 2 : [('^\W\"', 4)],
  25. 4 : [("\."),5],
  26. 6 : [("\."),5],
  27. }
  28. En este diccionario estan las reglas que acepta cad estado
  29. la llave en el diccionario es el estado en que parte,
  30. [] es la lista de reglas, cada regla contiene una tupla
  31. () donde el primer elemento es la expresion regular que
  32. reconoce el automata y el segundo elemento es el estado
  33. al que se mueve al aceptar la expresion regular.
  34. estadosFinales = [5]
  35. Es la lista de estados finales del automata.
  36. '''
  37. K = []
  38. q0 = 0
  39. F = []
  40. estados_recorridos = []
  41. estado = 0
  42. evaluada = ''
  43. dict_FTrans = {}
  44. def __init__(self, dict_FTrans, estadosFinales):
  45. self.F = estadosFinales
  46. for f in self.F:
  47. self.K.append(f)
  48. for k in dict_FTrans.keys():
  49. self.K.append(k)
  50. self.q0 = 0
  51. self.estado = 0
  52. self.evaluada = ''
  53. self.dict_FTrans = dict_FTrans
  54. def FTrans(self, cadena): # evalua la funcion de transicion
  55. self.evaluada = cadena
  56. cad = cadena
  57. partidas = []
  58. reglas_cadena_llegadas = []
  59. # ordenando por clave (estado de partida)
  60. dict_FTrans_ordenado = collections.OrderedDict(sorted(self.dict_FTrans.items()))
  61. # haciendo el recorrido
  62. while (self.estado not in self.F) and (self.estado != -1):
  63. # se busca el estado correspondiente y se guarda sus reglas para
  64. # estados siguientes
  65. regla_actual = dict_FTrans_ordenado[self.estado]
  66. # comprobando reglas de transicion de ese estado
  67. for regla in regla_actual:
  68. estado_siguiente = regla[1]
  69. er = regla[0] # expresion regular
  70. m = re.search(er, cad)
  71. if m is not None:
  72. self.estados_recorridos.append(self.estado)
  73. # "consumiendo" cadena
  74. cad = cad[len(m.group(0)):]
  75. self.estado = estado_siguiente
  76. break
  77. else:
  78. self.estado = -1
  79. return self.estado
  80. def aceptado(self):
  81. ''' Devuelve True si la ultima expresion evaluada por
  82. este automata ha sido aceptada'''
  83. if self.estado in self.F:
  84. return True
  85. return False
  86. class M_mostrar:
  87. '''
  88. Automata que reconoce:
  89. mostrar "texto cualquiera".
  90. mostrar variable.
  91. '''
  92. K = [0,1,2,3,4,5,6] # conjunto finito de estados
  93. q0 = 0 # estado inicial
  94. F = [5] # estados finales
  95. Alfabeto = "" # cadena
  96. estados_recorridos = []
  97. estado = 0
  98. evaluada = ''
  99. def FTrans(self, cadena): # funcion de trancision
  100. ''' Funcion de trancision retorna un estado
  101. Se sabe que el automata ha aceptado la cadena
  102. si y solo si la FTrans termina en un estado final'''
  103. self.evaluada = cadena
  104. cad = cadena
  105. while (self.estado not in self.F) and (self.estado != -1):
  106. if self.estado == self.q0:
  107. if cad.startswith("mostrar "):
  108. self.estados_recorridos.append(0)
  109. cad = cad[len("mostrar "):]
  110. self.estado = 1
  111. else:
  112. self.estado = -1
  113. elif self.estado == 1:
  114. W = "^[a-zA-Z][a-zA-Z0-9_]*"
  115. m = re.search(W,cad)
  116. if cad.startswith('"'):
  117. self.estados_recorridos.append(1)
  118. cad = cad[1:]
  119. self.estado = 2
  120. elif m is not None:
  121. self.estados_recorridos.append(1)
  122. cad = cad[len(m.group(0)):]
  123. self.estado = 6
  124. else:
  125. self.estado = -1
  126. elif self.estado == 2:
  127. if cad.find('"') != -1:
  128. self.estados_recorridos.append(2)
  129. cad = cad[cad.find('"')+1:]
  130. #self.estado = 3
  131. self.estados_recorridos.append(3)
  132. self.estado = 4
  133. else:
  134. self.estado = -1
  135. elif self.estado == 4 or self.estado == 6:
  136. self.estados_recorridos.append(self.estado)
  137. if cad == ".":
  138. self.estado = 5
  139. print (cadena[len("mostrar "):-1])
  140. else:
  141. self.estado = -1
  142. return self.estado
  143. def aceptado(self):
  144. ''' Devuelve True si la ultima expresion evaluada por
  145. este automata ha sido aceptada'''
  146. if self.estado in self.F:
  147. return True
  148. return False
  149. def mostrar_errores(self):
  150. ''' Segun la ultima cadena evaluada muestra
  151. en que estado del automata se ha generado el error'''
  152. ultimoEstadoAlcanzado = self.estados_recorridos[-1]
  153. def __init__(self):
  154. self.q0 = 0
  155. self.estados_recorridos = []
  156. self.evaluada = ''
  157. class M_declarar_enteros:
  158. K = [0,1,2,3,4,5] # conjunto finito de estados
  159. q0 = 0 # estado inicial
  160. F = [5] # estados finales
  161. Alfabeto = "" # cadena
  162. estados_recorridos = []
  163. estado = 0
  164. evaluada = ''
  165. def FTrans(self, cadena):
  166. self.evaluada = cadena
  167. cad = cadena
  168. while (self.estado not in self.F) and (self.estado != -1):
  169. if self.estado == self.q0:
  170. if cad.startswith("entero "):
  171. self.estados_recorridos.append(0)
  172. cad = cad[len("entero "):]
  173. self.estado = 1
  174. else:
  175. self.estado = -1
  176. elif self.estado == 1:
  177. W = "^[a-zA-Z][a-zA-Z0-9_]*"
  178. m = re.search(W,cad)
  179. if m is not None:
  180. self.estados_recorridos.append(1)
  181. cad = cad[len(m.group(0)):]
  182. self.estado = 2
  183. else:
  184. self.estado = -1
  185. elif self.estado == 2:
  186. er = "(= )|( =)|( = )|="
  187. m = re.search(er,cad)
  188. if m is not None:
  189. self.estados_recorridos.append(self.estado)
  190. cad = cad[len(m.group(0)):]
  191. self.estado = 3
  192. else:
  193. self.estado = -1
  194. elif self.estado == 3:
  195. er = "[0-9]+"
  196. m = re.search(er,cad)
  197. if m is not None:
  198. self.estados_recorridos.append(self.estado)
  199. self.estado = 4
  200. cad = cad[len(m.group(0)):]
  201. else:
  202. self.estado = -1
  203. elif self.estado == 4:
  204. if cad == '.':
  205. self.estados_recorridos.append(self.estado)
  206. self.estado = 5
  207. # estado final
  208. print(cadena)
  209. else:
  210. self.estado = -1
  211. return self.estado
  212. def aceptado(self):
  213. ''' Devuelve True si la ultima expresion evaluada por
  214. este automata ha sido aceptada'''
  215. if self.estado in self.F:
  216. return True
  217. return False
  218. def mostrar_errores(self):
  219. ''' Segun la ultima cadena evaluada muestra
  220. en que estado del automata se ha generado el error'''
  221. ultimoEstadoAlcanzado = self.estados_recorridos[-1]