コード例 #1
0
        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);
                        }
                    }
                }
            }
        }
コード例 #2
0
        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);
                        }
                    }
                }
            }
        }
コード例 #3
0
        private EstadoD crearEstado0(Automata afn)
        {
            EstadoD p = new EstadoD(0);

            this.cerraduraS(afn, p);
            return(p);
        }
コード例 #4
0
 private Boolean hayCamino(EstadoD estado, Caracter carac, Regla rr)
 {
     if (this.estadoFuturo(estado, carac, rr) > -1)
     {
         return(true);
     }
     return(false);
 }
コード例 #5
0
 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);
 }
コード例 #6
0
        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);
        }
コード例 #7
0
 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);
 }
コード例 #8
0
 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);
 }
コード例 #9
0
        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);
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
        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;
                    }
                }
            }
        }
コード例 #12
0
        /// <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();
                    }
                }
            }
        }