コード例 #1
0
        private List <ErrorCompilacion> AnalizarPila()
        {
            List <ErrorCompilacion> retorno = new List <ErrorCompilacion>();

            if (Pila.ObtenerTope().GetType() == typeof(NoTerminal))
            {
                Terminal   t  = CadenaEntrada.ObtenerPrimerTerminal();
                NoTerminal nt = (NoTerminal)Pila.ObtenerTope();

                bool generaProdVacia = false;

                //Que es esto??
                if (!PerteneceNoTerminalesNoEscapeables(nt))
                {
                    generaProdVacia = gramatica.NoTerminalGeneraProduccionVacia(nt);
                }

                //Buscar en la tabla arroja excepciones sintacticas si encuentra errores.
                Produccion prod = tabla.BuscarEnTablaProduccion(nt, t, true, generaProdVacia);

                if (prod != null)
                {
                    // flanzani 8/1/2012
                    // Esto es para ver que no se este operando la pila para llegar a un error sintactico, descartando cosas
                    // Si encuentra un problema, devuelve true, y se crea un error sintactico para descartar el tope de la cadena.
                    bool dejarDeOperarPilaYTirarError = ChequearQueNoSeEsteOperandoLaPilaParaUnErrorSintactico(prod);


                    if (dejarDeOperarPilaYTirarError)
                    {
                        // flanzani 8/1/2012
                        // Este metodo se fija si el estado de la pila es pq falta un token solo, y se fija basandose en que es
                        // el tope de la pila, para ver que terminal tengo que buscar y decir que falta ese para descartar ese
                        AnalizarLugarDeLaPilaYDescartarHastaTerminalQueCorresponda(nt, t, generaProdVacia);
                    }

                    Pila.TransformarProduccion(prod);
                }
            }
            else
            {
                if (!((Terminal)Pila.ObtenerTope()).NoEsLambda())
                {
                    Terminal t = Terminal.ElementoVacio();
                    t.Componente.Fila    = AnalizadorLexico.FilaActual();
                    t.Componente.Columna = AnalizadorLexico.ColumnaActual();

                    if (HabilitarSemantico)
                    {
                        retorno = ArbolSemantico.CalcularAtributos(t);
                    }


                    Pila.DescartarTope();
                }
            }

            return(retorno);
        }
コード例 #2
0
        public void ReiniciarAnalizadorSintactico()
        {
            EstadoSintactico.Reiniciar();

            Pila          = new PilaGramatica(gramatica.SimboloInicial);
            CadenaEntrada = new CadenaEntrada();

            ArbolSemantico      = new ArbolSemantico(gramatica.SimboloInicial);
            Pila.ArbolSemantico = ArbolSemantico;

            finArch = false;
            cantErroresSintacticos = 0;
            cantParentesisAbiertos = 0;

            HabilitarSemantico = true;
        }
コード例 #3
0
        private void ChequearTokensRepetidosEnCadena(Terminal term)
        {
            if (CadenaEntrada.TieneTerminalRepetidoEnPrimerLugarErroneo(cantParentesisAbiertos))
            {
                if (term.Equals(Terminal.ElementoParentesisClausura()))
                {
                    //Le sumo uno asi restauro el equilibrio
                    cantParentesisAbiertos++;
                }
                StringBuilder strbldr = new StringBuilder("Se encontro ");
                strbldr.Append(EnumUtils.stringValueOf(term.Componente.Token));
                strbldr.Append(" repetido.");

                throw new ErrorSintacticoException(strbldr.ToString(),
                                                   AnalizadorLexico.FilaActual(),
                                                   AnalizadorLexico.ColumnaActual(),
                                                   false,
                                                   true,
                                                   false);
            }
        }
コード例 #4
0
 public bool EsFinAnalisisSintactico()
 {
     return(CadenaEntrada.EsFinDeCadena() && Pila.EsFinDePila());
 }
コード例 #5
0
        private void RellenarCadenaEntrada()
        {
            if (!finArch)
            {
                Terminal t = Terminal.ElementoVacio();

                while ((CadenaEntrada.Count < cantElementosCadenaEntrada) && (!t.Equals(Terminal.ElementoEOF())))
                {
                    t            = new Terminal();
                    t.Componente = AnalizadorLexico.ObtenerProximoToken();

                    //Controlo que no haya un error lexico en el token que acabo de traer.
                    //Si hay error directamente me salteo el paso, no se inserta en la cadena, y no toco la pila.
                    if (t.Equals(Terminal.ElementoError()))
                    {
                        //throw new ErrorLexicoException(string.Format("El caracter {0} no es reconocido por el lenguaje GarGar", t.Componente.Lexema), t.Componente.Fila, t.Componente.Columna);
                        string lexemaError;
                        if (string.IsNullOrEmpty(t.Componente.CaracterErroneo))
                        {
                            lexemaError = t.Componente.Lexema.Split(new char[] { ' ' })[0];
                        }
                        else
                        {
                            lexemaError = t.Componente.CaracterErroneo;
                        }

                        string errorMensaje = string.Format("El caracter {0} es invalido en este contexto", lexemaError);

                        if (t.Componente.Descripcion != null)
                        {
                            errorMensaje = t.Componente.Descripcion;
                        }

                        throw new ErrorLexicoException(errorMensaje, t.Componente.Fila, t.Componente.Columna);
                    }

                    if (t.Componente.Token == ComponenteLexico.TokenType.Numero)
                    {
                        if (t.Componente.Lexema.TrimStart()[0] == '-')
                        {
                            Terminal ultimoTerminal = CadenaEntrada.UltimoTerminalInsertado;

                            if (ultimoTerminal != null && TerminalesHelpers.EsTerminalConValor(ultimoTerminal))
                            {
                                //Para que no de error Sintactico, creo este otro token para que parezca que es una operacion negativa -

                                ComponenteLexico comp = new ComponenteLexico();
                                comp.Fila    = t.Componente.Fila;
                                comp.Columna = t.Componente.Columna;
                                comp.Lexema  = "-";
                                comp.Token   = ComponenteLexico.TokenType.RestaEntero;

                                CadenaEntrada.InsertarTerminal(new Terminal()
                                {
                                    Componente = comp
                                });

                                //Le sumo uno pq el menos ya no pertenece mas.
                                t.Componente.Columna++;

                                //Le saco el - del lexema
                                t.Componente.Lexema = t.Componente.Lexema.Remove(0, 1);
                            }
                        }
                    }



                    CadenaEntrada.InsertarTerminal(t);
                }
                if (t.Equals(Terminal.ElementoEOF()))
                {
                    finArch = true;
                }
            }
        }
コード例 #6
0
        private bool ChequearQueNoSeEsteOperandoLaPilaParaUnErrorSintactico(Produccion prod)
        {
            bool retorno      = false;
            bool pararChequeo = false;

            if (prod.ProduceElementoVacio())
            {
                int posPila = 1;
                while (!(CadenaEntrada.EsFinDeCadena() && Pila.EsFinDePila()) && (Pila.Count > posPila) && !pararChequeo)
                {
                    if (Pila.ObtenerPosicion(posPila).GetType() == typeof(Terminal))
                    {
                        Terminal term = (Terminal)Pila.ObtenerPosicion(posPila);

                        if (CadenaEntrada.ObtenerPrimerTerminal().Equals(Pila.ObtenerPosicion(posPila)))
                        {
                            //No hay error pq coincide el terminal, y se va a poder descartar en el proximo paso.
                            retorno      = false;
                            pararChequeo = true;
                        }
                        else
                        {
                            if (term.NoEsLambda())
                            {
                                //Hay error pq el terminal no coindiria con el de la cadena de entrada.
                                retorno      = true;
                                pararChequeo = true;
                            }
                        }
                    }
                    else
                    {
                        Terminal   t  = CadenaEntrada.ObtenerPrimerTerminal();
                        NoTerminal nt = (NoTerminal)Pila.ObtenerPosicion(posPila);

                        bool generaProdVacia = false;

                        //Que es esto??
                        if (!PerteneceNoTerminalesNoEscapeables(nt))
                        {
                            generaProdVacia = gramatica.NoTerminalGeneraProduccionVacia(nt);
                        }

                        Produccion prodAux = tabla.BuscarEnTablaProduccion(nt, t, false, generaProdVacia);

                        if (prodAux != null)
                        {
                            if (prodAux.ProduceElementoVacio())
                            {
                                posPila++;
                            }
                            else
                            {
                                //Significa que llegue a algo concreto con el terminal que tengo en el tope, y dejo seguir.
                                retorno      = false;
                                pararChequeo = true;
                            }
                        }
                        else
                        {
                            //Significa que en la tabla ni figura, o sea que es un error
                            retorno      = true;
                            pararChequeo = true;
                        }
                    }
                }

                if (posPila > Pila.Count)
                {
                    //Hubo error pq el terminal tope no servia para nada de la pila
                    retorno = true;
                }
            }

            return(retorno);
        }
コード例 #7
0
        internal List <ErrorCompilacion> AnalizarUnSoloPaso()
        {
            List <ErrorCompilacion> retorno = new List <ErrorCompilacion>();

            if (!(CadenaEntrada.EsFinDeCadena() && Pila.EsFinDePila()))
            {
                RellenarCadenaEntrada();

                if (Pila.ObtenerTope().GetType() == typeof(Terminal))
                {
                    Terminal term = (Terminal)Pila.ObtenerTope();

                    if (CadenaEntrada.ObtenerPrimerTerminal().Equals(Pila.ObtenerTope()))
                    {
                        if (term.Componente.Token == ComponenteLexico.TokenType.ParentesisApertura)
                        {
                            cantParentesisAbiertos++;
                        }
                        else if (term.Componente.Token == ComponenteLexico.TokenType.ParentesisClausura)
                        {
                            cantParentesisAbiertos--;
                        }

                        //flanzani 8/1/2012
                        //tokens repetidos
                        //Antes de pasar por el semantico, lo que hago es fijarme si el terminal justo no esta repetido,
                        //pq eso me caga todo el parseo de errores del sintactico
                        //Esto puede arrojar una excepcion sintactica
                        ChequearTokensRepetidosEnCadena(term);

                        if (HabilitarSemantico)
                        {
                            retorno = ArbolSemantico.CalcularAtributos(CadenaEntrada.ObtenerPrimerTerminal());
                        }

                        Pila.DescartarTope();

                        GlobalesCompilador.UltFila = CadenaEntrada.ObtenerPrimerTerminal().Componente.Fila;
                        GlobalesCompilador.UltCol  = CadenaEntrada.ObtenerPrimerTerminal().Componente.Columna;

                        EstadoSintactico.AgregarTerminal(term);

                        CadenaEntrada.EliminarPrimerTerminal();
                    }
                    else
                    {
                        if (term.NoEsLambda())
                        {
                            StringBuilder strbldr = new StringBuilder(string.Empty);
                            strbldr.Append("Se esperaba ");
                            strbldr.Append(EnumUtils.stringValueOf(term.Componente.Token));
                            strbldr.Append(" pero se encontro ");
                            strbldr.Append(EnumUtils.stringValueOf(CadenaEntrada.ObtenerPrimerTerminal().Componente.Token));
                            strbldr.Append(".");

                            if (term.Equals(Terminal.ElementoFinSentencia()))
                            {
                                //Descarto el ; de la pila pq asumo que simplemente se le olvido
                                strbldr.Append(" Se asume fin de sentencia para continuar con analisis.");
                            }

                            throw new ErrorSintacticoException(strbldr.ToString(),
                                                               AnalizadorLexico.FilaActual(),
                                                               AnalizadorLexico.ColumnaActual(),
                                                               true,
                                                               false,
                                                               false);
                        }
                        else
                        {
                            retorno = AnalizarPila();
                        }
                    }
                }
                else
                {
                    retorno = AnalizarPila();
                }
            }

            return(retorno);
        }