private void cerraduraS(Automata afn, EstadoD p) { //Crear la pila LinkedList <Nodo> pila = new LinkedList <Nodo>(); //Agregar el estado 0 a la pila; pila.AddFirst(afn.start); //Agregar el estado 0 a el subconjunto p.suconjunto.Add(afn.start.num + "", afn.start); while (pila.Count != 0) { Nodo superior = pila.First.Value; pila.RemoveFirst(); foreach (Transicion t in superior.transiciones) { //Solo transiciones con ε if (t.simbolo.Equals("ε")) { //Tiene que no estar en subconjunto el estado if (p.suconjunto.ContainsKey(t.destino.num + "") == false) { p.suconjunto.Add(t.destino.num + "", t.destino); pila.AddLast(t.destino); } } } } }
private void cerraduraT(List <Nodo> estadosT, EstadoD p) { //Crear la pila LinkedList <Nodo> pila = new LinkedList <Nodo>(); //Meter todos los estados T en la pila //Meter todos los estados T en suconjuntos de P foreach (Nodo item in estadosT) { pila.AddLast(item); if (!p.suconjunto.ContainsKey(item.num.ToString())) { p.suconjunto.Add(item.num.ToString(), item); } } while (pila.Count != 0) { Nodo superior = pila.First.Value; pila.RemoveFirst(); foreach (Transicion t in superior.transiciones) { //Solo transiciones con ε if (t.simbolo.Equals("ε")) { //Tiene que no estar en subconjunto el estado if (p.suconjunto.ContainsKey(t.destino.num + "") == false) { p.suconjunto.Add(t.destino.num + "", t.destino); pila.AddLast(t.destino); } } } } }
private EstadoD crearEstado0(Automata afn) { EstadoD p = new EstadoD(0); this.cerraduraS(afn, p); return(p); }
private Boolean hayCamino(EstadoD estado, Caracter carac, Regla rr) { if (this.estadoFuturo(estado, carac, rr) > -1) { return(true); } return(false); }
public Boolean hay_estado_T_sin_marcar(List <EstadoD> estadosD) { foreach (EstadoD item in estadosD) { if (item.marcado == false) { this.estado_T = item; return(true); } } return(false); }
private void algoritmoSubconjuntos(Regla regla) { //Crear la lista de estadosD -> de AF"D" //LinkedList<EstadoD> estados_D = regla.estadosD; List <EstadoD> estados_D = regla.estadosD; //Crear la particion 0 + cerraduraS //estados_D.AddFirst(this.crearEstado0(regla.afn)); estados_D.Add(this.crearEstado0(regla.afn)); while (hay_estado_T_sin_marcar(regla.estadosD)) { estado_T.marcado = true; foreach (String simbolo_a in regla.afn.listaSimbolos.Values) { //U = ε_cerradura(mover(T, a)); EstadoD U = e_cerradura_move_T_a(estado_T, simbolo_a, estados_D.Count); //si U no esta en estadosD if (esta_U_en_estadosD(U, estados_D) == false) { if (U.suconjunto.Count == 0) { continue; } //U = no marcado U.marcado = false; //Move[.....] = U Move m; estado_T.movimientos.TryGetValue(simbolo_a, out m); m.particion = U; //Meter U a estadosD //estados_D.AddLast(U); estados_D.Add(U); } else { Move m; estado_T.movimientos.TryGetValue(simbolo_a, out m); m.particion = estado_T_igual; //Move[.....] = particion que ya esta en estadosD } } } buscarAceptacion(estados_D, regla.afn.end.num); }
public Boolean subconjuntosIguales(EstadoD vs, EstadoD U) { if (U.suconjunto.Count == vs.suconjunto.Count) { foreach (var item in U.suconjunto.Keys) { if (vs.suconjunto.ContainsKey(item) == false) { return(false); } } return(true); } return(false); }
public Boolean esta_U_en_estadosD(EstadoD pu, List <EstadoD> estados_D) { //Ir por cada estado de estados_D //Comparar si ese estado == estado U //si son iguales retonar true y guardar en estado_T_igual = estado foreach (EstadoD estado in estados_D) { if (this.subconjuntosIguales(estado, pu)) { //Si existe un estado igual this.estado_T_igual = estado; return(true); } } return(false); }
public EstadoD e_cerradura_move_T_a(EstadoD T, String a, int numero) { //Crear la particion U (Estado posible a agregar) EstadoD U = new EstadoD(numero); Move move = new Move(T, a); //Armando el Move[estado_T, simbolo_a] = {n1, n2, n3, ...., nn} foreach (Nodo nodo in T.suconjunto.Values) { foreach (Transicion transis in nodo.transiciones) { String s = transis.simbolo; if (s.Equals(a)) { //Evalua si la transicion tiene el mismo simbolo move.addTransicion(transis.destino); continue; } if (s.Contains("[:") == true && s.Contains("~")) { //Evaluar series //evaluar si contiene [:, ~, :] String s2 = s.Replace("[", "").Replace(":", "").Replace("~", ","); String[] t = s2.Split(','); int iserie = this.toAscii(t[0]); int fserie = this.toAscii(t[1]); int sserie = this.toAscii(a); if (sserie >= iserie && sserie <= fserie) { move.addTransicion(transis.destino); continue; } } if (a.Equals("salto") || a.Equals("retorno") || a.Equals("tab") || a.Equals("espacio")) { if (s.Equals("blanco")) { move.addTransicion(transis.destino); continue; } } if (a.Equals("blanco")) { if (s.Equals("salto") || s.Equals("retorno") || s.Equals("tab") || s.Equals("espacio")) { move.addTransicion(transis.destino); continue; } } if (!a.Equals("salto") && !a.Equals("retorno")) { if (s.Equals("todo")) { move.addTransicion(transis.destino); continue; } } } } if (T.movimientos.ContainsKey(a) == false) { T.movimientos.Add(a, move); } //U = particion con subconjunto que se llega con Move[.....] this.cerraduraT(move.listaTransiciones, U); return(U); }
/// <summary> /// Analizar los movimiento que puede hacer un estado con el caracter /// si movimiento.particion ==null /// es decir que no hay movimiento valido :D /// </summary> /// <param name="estado">Estado donde se encuentra el analizador</param> /// <param name="carac">Caracter con el cual se quiere desplazar a otro estado</param> /// <returns>indica el estado futuro a donde ha de llegar con el caracter</returns> private int estadoFuturo(EstadoD estado, Caracter carac, Regla rr) { //El movimiento move[T, a] = U //T, es el estado en el que me encuentro //a, es el simolo de transicion //U, es el estado a donde voy a llegar, si U==NULL error, no hay movimiento con dicho simbolo, pero //habra validar que no este en [:todos:], x~y, etc. String c = carac.caracter; if (estado.movimientos.ContainsKey(c)) { Move movimiento; estado.movimientos.TryGetValue(c, out movimiento); if (movimiento.particion != null) { int estadofuturo = movimiento.particion.num; this.string_simbolo = c + ""; return(estadofuturo); } } //Paso, no hay movimientos con el caracter //puede que sea un escape, o este dentro los rangos //Si fuera No Sensitivo el lenguaje //hay que pasar caracter a minuscula int ascii_caracter = toAscii(c); foreach (Move movimiento in estado.movimientos.Values) { if (movimiento.particion == null) { continue; } this.string_simbolo = (movimiento.simbolo).ToString(); //Validar que sea comilla doble " if (movimiento.simbolo.Equals("comilla_d")) { if (ascii_caracter == 34 || ascii_caracter == 249) { return(movimiento.particion.num); } } //Validar que sea comilla simple ' if (movimiento.simbolo.Equals("comilla_s")) { if (ascii_caracter == 39 || ascii_caracter == 96 || ascii_caracter == 236) { return(movimiento.particion.num); } } //Puede estar dentro un rango el caracter if (movimiento.simbolo.Contains("[") && movimiento.simbolo.Contains("]")) { String s2 = movimiento.simbolo.Replace("[", "").Replace("~", ",").Replace("]", ""); String [] t = s2.Split(','); int iserie = this.toAscii(t[0]); int fserie = this.toAscii(t[1]); if (ascii_caracter >= iserie && ascii_caracter <= fserie) { return(movimiento.particion.num); } } //Validar salto de linea if (movimiento.simbolo.Equals("salto") || c == "\n") { if (ascii_caracter == 10) { return(movimiento.particion.num); } } //Validar que sea un retorno de carro if (movimiento.simbolo.Equals("retorno") || c == "\r") { if (ascii_caracter == 13) { return(movimiento.particion.num); } } //Validar que sea una tabulacion if (movimiento.simbolo.Equals("tab")) { if (ascii_caracter == 9 || c == "\t") { return(movimiento.particion.num); } } //Validar que sea un espacio en blanco //Este existe si se llamo a al expresion [:blanco:], en el archivo dx //entonces el se hace un or con todos los blancos(salto, retorno, tab, espacio) if (movimiento.simbolo.Equals("espacio")) { if (ascii_caracter == 32 || c == " ") { return(movimiento.particion.num); } } //Talves sea el caso especia de que se uso la expresion [:todo:] //por lo que si se puede haber movimiento con cualquier simbolo que no sea //retorno=13 y salto=10 if (movimiento.simbolo.Equals("todo")) { if (ascii_caracter != 10 && ascii_caracter != 13) { return(movimiento.particion.num); } } } return(-1); }
private void moverme2(Regla regla, List <Caracter> listacaracteres, TokenD lexema, Indice piterador) { int i_original = piterador.i; int iestado = 0; Caracter ccaracter; List <EstadoD> listaestados = regla.estadosD; for (piterador.i = i_original; piterador.i < listacaracteres.Count; piterador.i = piterador.i + 1) { ccaracter = listacaracteres[piterador.i]; Console.WriteLine("Iterador: " + piterador.i.ToString() + ". Caracter: " + ccaracter.caracter + ", Estado: " + iestado.ToString()); EstadoD estado_actual = null; foreach (EstadoD item in listaestados) { if (item.num == iestado) { estado_actual = item; break; } } if (estado_actual == null) { MessageBox.Show("Se arruino!!"); return; } iestado = this.estadoFuturo(estado_actual, ccaracter, regla); //Transicion, IMPosible, no hay camino a seguir if (iestado == -1) { //Error, pero si //Es estado aceptacion, acepto el lexema, retrocedo el inidice en 1, salgo de la funcion if ((estado_actual.aceptacion == true) || (lexema.aceptado == true)) { lexema.aceptado = true; piterador.i = piterador.i - 1; this.pintarCelda(estado_actual.num, Color.LightGreen, regla); return; } //Si llego aqui no estamos en estado de aceptacion, //ser rechaza el lexema lexema.aceptado = false; this.pintarCelda(estado_actual.num, Color.Red, regla); return; } //Transicion, Posible, hay camino a seguir if (iestado > -1) { lexema.valor += ccaracter.caracter; if (estado_actual.aceptacion) { this.pintarCelda(iestado, Color.LightGreen, regla); lexema.aceptado = true; } else { this.pintarCelda(iestado, Color.Yellow, regla); lexema.aceptado = false; } } } }
/// <summary> /// La aplicacion tienen n automatas /// Se evalua si hay un posible camino dentro de cada automata /// si es asi se mueve dentro del automata /// Si no hay camino o hay un error dentro un automata recien entrado /// se busca el siguiente automata para ser aceptado /// /// si se finaliza todos los automata y no fue aceptado se guarda un error del tipo DLEX, xq no /// no se puede aceptar la cadena en ninguna regla escrita /// /// el error es LEXICO, este se crea si la cadena se acepta en al regla de "error" escrito en el lenguaje dx /// </summary> /// <param name="listacaracteres"></param> private void moverme(List <Caracter> listacaracteres) { Indice iterador = new Indice(0); int i_anterior = iterador.i; TokenD lexema; Caracter caracter; for (iterador.i = 0; iterador.i < listacaracteres.Count; iterador.i = iterador.i + 1) { lexema = new TokenD(); i_anterior = iterador.i; //Buscar Camino dentro de la lista de reglas //Cada regla tiene asociada un automata List <Regla> reglas = this.arch.reglas; int index_reglas = 0; for (index_reglas = 0; index_reglas < reglas.Count; index_reglas++) { caracter = listacaracteres[i_anterior]; lexema = new TokenD(caracter.linea, caracter.columna); Regla regla = reglas[index_reglas]; //regla.estadosD. //Obtener el estado 0 EstadoD estado_0 = regla.estadosD[0]; if (this.hayCamino(estado_0, caracter, regla)) { this.ejecutar_otros(regla); //PASAR AL ANALISIS DENTRO DEL AUTOMATA this.moverme2(regla, listacaracteres, lexema, iterador); } else { this.ejecutar_otros(regla); if ((index_reglas + 1) == reglas.Count) { //Evaluar si yano queda mas automatas = error //NO ENCONTRE CAMINO this.guardarError_error_sin_regla(caracter); break; } else { //Aun hay automatas por recorrer continue; } } //Si llego aqui, el caracter si entro dentro un automata //Si lexema = aceptado, //guardo lexeman //salgo del for y continuo con el sig. caracter if (lexema.aceptado) { this.guardarLexema(regla, lexema); //this.limpiarTabla(); break; } //Si lexema = error && no quedan mas automatas //guardo el error, retroceo el indice hasta el anterior aceptado //ENCONTRE CAMINO PERO NO FUE ACEPTADO if (lexema.aceptado == false && (index_reglas + 1) == reglas.Count) { guardarError_error_sin_regla(caracter); iterador.i = i_anterior; //this.limpiarTabla(); break; } //Si lexema = error && aun quedan mas automatas //retrocedo el indice hasta el ultimo aceptado if (lexema.aceptado == false) { if (i_anterior == listacaracteres.Count - 1) { break; } iterador.i = i_anterior; //this.limpiarTabla(); } } } }