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); }
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; }
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); } }
public bool EsFinAnalisisSintactico() { return(CadenaEntrada.EsFinDeCadena() && Pila.EsFinDePila()); }
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; } } }
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); }
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); }