public PilaGramatica(NoTerminal simboloInicial) { this.elementosPila = new List <ElementoGramatica>(); this.elementosPila.Add(Terminal.ElementoEOF()); this.elementosPila.Add(simboloInicial); }
internal ArbolSemantico(NoTerminal nt) { nodoRaiz = new NodoStart(null, nt); nodoRaiz.CrearTablaSimbolos(); nodoActual = nodoRaiz; }
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 NodoTablaAnalisisGramatica(NoTerminal nt, Terminal t, Produccion prod) { this.NoTerminal = nt; this.Terminal = t; this.Produccion = prod; this.EsSinc = false; this.DescripcionError = string.Empty; }
public NodoTablaAnalisisGramatica(NoTerminal nt, Terminal t, string sinc) { this.NoTerminal = nt; this.Terminal = t; this.EsSinc = true; this.Produccion = null; this.DescripcionError = sinc; }
public NodoTablaPrimeros(NoTerminal noTerminal, Produccion produccion, List <Terminal> terms) { this.prod = produccion; this.nt = noTerminal; this.terminales = new List <Terminal>(); this.terminales = terms; this.modificado = true; }
public void AgregarPrimeros(NoTerminal nt, List <Terminal> termsPrim, Produccion prod) { foreach (Terminal t in termsPrim) { if (t.NoEsLambda() && prod.Der != null) { this.produccionesDeLaTabla.Add(new NodoTablaAnalisisGramatica(nt, t, prod)); } } }
private List <Terminal> PrimerosDe(NoTerminal nt, Produccion prod) { List <Terminal> listaTerminales = new List <Terminal>(); NodoTablaPrimeros nd = this.ObtenerNodo(nt, prod); listaTerminales.AddRange(nd.Terminales); return(listaTerminales); }
private IEnumerable <NodoTablaPrimeros> ObtenerNodos(NoTerminal nt) { return(this.nodos.FindAll( delegate(NodoTablaPrimeros _nd) { return _nd.NT.Equals(nt); } )); }
private NodoTablaPrimeros ObtenerNodo(NoTerminal nt, Produccion prod) { return(this.nodos.Find( delegate(NodoTablaPrimeros _nd) { return _nd.NT.Equals(nt) && _nd.Prod.Equals(prod); } )); }
public RetornoPrimeros Primeros(NoTerminal nt, Produccion prod, bool enDerecha) { if (enDerecha) { //return PrimerosDerecha(nt, prod); return(PrimerosParaSiguientes(nt, prod)); } else { return(PrimerosIzquierda(nt, prod)); } }
internal void AgregarSincronizacion(NoTerminal nt, List <Terminal> termsSig) { foreach (Terminal t in termsSig) { StringBuilder strBldr = new StringBuilder("Descarto el no terminal ").Append(nt.ToString()); strBldr.Append(" de la pila ").Append(" pq viene el terminal ").Append(t.ToString()); if (this.BuscarNodo(nt, t) == null) { NodoTablaAnalisisGramatica nodo = new NodoTablaAnalisisGramatica(nt, t, strBldr.ToString()); this.produccionesDeLaTabla.Add(nodo); } } }
private RetornoPrimeros PrimerosIzquierda(NoTerminal nt, Produccion prod) { RetornoPrimeros retorno = new RetornoPrimeros(); if (prod.Der != null) { retorno.Terminales.AddRange(this.PrimerosDe(nt, prod)); } else { retorno.Terminales.Add(Terminal.ElementoVacio()); } return(retorno); }
public void AgregarSiguientes(NoTerminal nt, List <Terminal> termsSig) { foreach (Terminal t in termsSig) { Produccion prod = new Produccion(); prod.Izq = nt; Terminal term = new Terminal(); term.Componente = new ComponenteLexico(); term.Componente.Token = ComponenteLexico.TokenType.Ninguno; prod.Der.Add(term); this.produccionesDeLaTabla.Add(new NodoTablaAnalisisGramatica(nt, t, prod)); } }
private List <Terminal> PrimerosDe(NoTerminal nt) { List <Terminal> listaTerminales = new List <Terminal>(); foreach (NodoTablaPrimeros nd in this.ObtenerNodos(nt)) { foreach (Terminal t in nd.Terminales) { if (!listaTerminales.Contains(t)) { listaTerminales.Add(t); } } } return(listaTerminales); }
private NodoTablaAnalisisGramatica EncontrarNodo(NoTerminal x, Terminal y) { return(this.produccionesDeLaTabla.Find( delegate(NodoTablaAnalisisGramatica _nodo) { if (_nodo.Terminal.Equals(y) && _nodo.NoTerminal.Equals(x)) { return true; } else { return false; } } )); }
//Metodo publico, que se fija el primero del NoTerminal elegido en la parte derecha produccion private RetornoPrimeros PrimerosDerecha(NoTerminal nt, Produccion prod) { RetornoPrimeros retorno = new RetornoPrimeros(); List <Terminal> terminales = new List <Terminal>(); int i = prod.Der.IndexOf(nt); Debug.Assert(i >= 0, "El indice del metodo Primeros en TablePrimeros era menor a 0", "el terminal " + nt.ToString() + " no figura en la derecha de la prod " + prod.ToString()); bool parar = false; while (i < prod.Der.Count && !parar) { if (prod.Der[i].GetType() == typeof(NoTerminal)) { List <Terminal> terminalesAux = new List <Terminal>(); terminalesAux = this.PrimerosDe((NoTerminal)prod.Der[i]); terminales.AddRange(terminalesAux); if (!terminales.Contains(Terminal.ElementoVacio())) { parar = true; } } else { terminales.Add((Terminal)prod.Der[i]); parar = true; } i++; } if (!parar) { retorno.EsNecesarioSiguiente = true; retorno.NoTerminal = prod.Izq; } retorno.Terminales = terminales; return(retorno); }
public override string ToString() { StringBuilder strBldr = new StringBuilder(string.Empty); strBldr.Append(NoTerminal.ToString()); strBldr.Append(","); strBldr.Append(Terminal.ToString()); strBldr.Append(" "); if (EsSinc) { strBldr.Append("Sinc"); } else { strBldr.Append(Produccion.ToString()); } return(strBldr.ToString()); }
public Produccion BuscarEnTablaProduccion(NoTerminal x, Terminal y, bool reportarErrores, bool generaProdVacia) { NodoTablaAnalisisGramatica nodo = this.EncontrarNodo(x, y); if (nodo != null) { if (!nodo.EsSinc) { return(nodo.Produccion); } else { if (reportarErrores) { this.ErrorSintacticoSinMostrar(y.Componente.Fila, y.Componente.Columna, y, nodo.DescripcionError, false, true); } return(null); } } else { if (reportarErrores) { if (!generaProdVacia) { this.ErrorSintactico(y.Componente.Fila, y.Componente.Columna, y, true, false); } else { Produccion prod = new Produccion(); prod.Izq = x; Terminal term = new Terminal(); term.Componente = new ComponenteLexico(); term.Componente.Token = ComponenteLexico.TokenType.Ninguno; prod.Der.Add(term); return(prod); } } return(null); } }
public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return(false); } // safe because of the GetType check NodoTablaAnalisisGramatica nodo = (NodoTablaAnalisisGramatica)obj; // use this pattern to compare reference members if (NoTerminal.Equals(nodo.NoTerminal.ToString()) && Terminal.Equals(nodo.Terminal.ToString())) { return(true); } else { return(false); } }
private RetornoPrimeros PrimerosParaSiguientes(NoTerminal nt, Produccion prod) { RetornoPrimeros retorno = new RetornoPrimeros(); if (prod.Der != null) { retorno.Terminales.AddRange(this.PrimerosDe(nt)); } else { retorno.Terminales.Add(Terminal.ElementoVacio()); } if (retorno.Terminales.Contains(Terminal.ElementoVacio())) { retorno.EsNecesarioSiguiente = true; retorno.NoTerminal = nt; } return(retorno); }
private Terminal BuscarTerminalApropiadoBasadoEnTopePila(NoTerminal nt) { Terminal retorno; switch (nt.Nombre) { case "MULT": case "MULTS": case "EXP": case "EXPR": if (cantParentesisAbiertos > 0) { retorno = Terminal.ElementoParentesisClausura(); } else { retorno = Terminal.ElementoFinSentencia(); } break; case "IDASIGN": retorno = Terminal.ElementoFinSentencia(); break; case "EXPRPRPROC": case "EXPRPRPROCED": case "EXPRBOOLEANAS": case "EXPRBOOLEXTRA": retorno = Terminal.ElementoParentesisClausura(); break; default: retorno = Terminal.ElementoFinSentencia(); break; } return(retorno); }
private void AnalizarLugarDeLaPilaYDescartarHastaTerminalQueCorresponda(NoTerminal nt, Terminal t, bool generaProdVacia) { Terminal termBuscar = BuscarTerminalApropiadoBasadoEnTopePila(nt); //string error = CaptarMensajeErrorApropiado(nt, t); Produccion prod = tabla.BuscarEnTablaProduccion(nt, termBuscar, false, generaProdVacia); if (prod != null) { StringBuilder strbldr = new StringBuilder(string.Empty); strbldr.Append("Se esperaba "); strbldr.Append(termBuscar.Componente.Lexema); throw new ErrorSintacticoException(strbldr.ToString(), AnalizadorLexico.FilaActual(), AnalizadorLexico.ColumnaActual(), true, false, true, true, termBuscar ); } else { StringBuilder strbldr = new StringBuilder(string.Empty); strbldr.Append(EnumUtils.stringValueOf(t.Componente.Token)); strbldr.Append(" no tiene lugar en la sentencia."); throw new ErrorSintacticoException(strbldr.ToString(), AnalizadorLexico.FilaActual(), AnalizadorLexico.ColumnaActual(), false, true, false); } }
public WordsCollection Analiza() { WordsCollection currentSymbol = new WordsCollection(); //Simbolo Actual obtenido del int x = 0; //Fila int y = 0; //Columna int r = 0; //Resultado (regla, desplazamiento o aceptacion) Estado fila = new Estado(0); int pops = 0; //Cantidad de elementos que produce la regla bool error = false; //Bandera que detiene el ciclo bool newSymbol = true; //Decide si se necesita un nuevo simbolo del Lexico o no //Inicializa cola ColaSintactica.Push(new Estado(0)); Node Root = new Node(); //Ciclo que ejecuta el analisis sintactico while (!error) { if (newSymbol) { currentSymbol = ALexico.sigSimbolo(); } //x = (int)pila.Peek(); x = ((Estado)pila.Peek()).transicion; y = currentSymbol.TypeId; r = TablaLR[x, y]; Node nodo = new Node(); nodo = null; if (r > 0) { //Desplazamiento //pila.Push(currentSymbol); pila.Push(new Terminal(currentSymbol.Word)); //pila.Push(r); pila.Push(new Estado(r)); newSymbol = true; } else if (r < 0) { //Regla r = Math.Abs(r) - 1; if (r == 0) { //Cadena Aceptada break; } // Obtencion de la cantidad de POPs a realizar en la cola. switch (r) { //case 1: //<programa> ::= <Definiciones> //nodo=new programa(pila); // break; case 3: //<Definiciones> ::= <Definicion> <Definiciones> case 16: //<DefLocales> ::= <DefLocal> <DefLocales> case 20: //<Sentencias> ::= <Sentencia> <Sentencias> case 32: //<Argumentos> ::= <Expresion> <ListaArgumentos> pila.Pop(); //quita estado Node aux = (Node)pila.Pop(); //quita <definiciones> pila.Pop(); //quita estado nodo = (Node)pila.Pop(); //quita <definicion> if (nodo != null) { nodo.Siguiente = aux; } break; case 1: case 4: //<Definicion> ::= <DefVar> case 5: //<Definicion> ::= <DefFunc> case 17: //<DefLocal> ::= <DefVar> case 18: //<DefLocal> ::= <Sentencia> case 35: //<Atomo> ::= <LlamadaFunc> case 39: //<SentenciaBloque> ::= <Sentencia> case 40: //<SentenciaBloque> ::= <Bloque> case 50: //<Expresion> ::= <Atomo> pila.Pop(); //quita estado nodo = (Node)pila.Pop(); //quita defvar break; case 6: // <DefVar> ::= tipo id <ListaVar> ; nodo = new DefVar(ref pila); break; case 8: //<ListaVar> ::= , id <ListaVar> pila.Pop(); //quita estado Node lvar = ((Node)pila.Pop()); pila.Pop(); //quita estado nodo = new Identificador(((Terminal)pila.Pop()).nodo.Simbolo); //quita id nodo.Siguiente = lvar; pila.Pop(); //quita estado pila.Pop(); //quita la coma break; case 9: //<DefFunc> ::= tipo id ( <Parametros> ) <BloqFunc> nodo = new DefFunc(ref pila); break; case 11: //<Parametros> ::= tipo id <ListaParam> nodo = new Parametros(ref pila); break; case 13: //<ListaParam> ::= , tipo id <ListaParam> nodo = new Parametros(ref pila); pila.Pop(); //quita estado; pila.Pop(); //quita la coma break; case 14: //<BloqFunc> ::= { <DefLocales> } case 30: //<Bloque> ::= { <Sentencias> } case 41: //<Expresion> ::= ( <Expresion> ) pila.Pop(); //quita estado pila.Pop(); //quita } pila.Pop(); //quita estado nodo = ((Node)pila.Pop()); //quita <deflocales> o <sentencias> pila.Pop(); pila.Pop(); //quita la { break; case 21: //<Sentencia> ::= id = <Expresion> ; nodo = new Asignacion(ref pila); break; case 22: //<Sentencia> ::= if ( <Expresion> ) <SentenciaBloque> <Otro> nodo = new If(ref pila); break; case 23: //<Sentencia> ::= while ( <Expresion> ) <Bloque> nodo = new While(ref pila); break; case 24: //<Sentencia> ::= do <Bloque> while ( <Expresion> ) ; nodo = new DoWhile(ref pila); break; case 25: //<Sentencia> ::= for id = <Expresion> : <Expresion> : <Expresion> <SentenciaBloque> nodo = new For(ref pila); break; case 26: //<Sentencia> ::= return <Expresion> ; nodo = new Return(ref pila); break; case 27: //<Sentencia> ::= <LlamadaFunc> ; pila.Pop(); pila.Pop(); //quita ; pila.Pop(); nodo = ((Node)pila.Pop()); //quita llamadafunc break; case 29: //<Otro> ::= else <SentenciaBloque> pila.Pop(); nodo = ((Node)pila.Pop()); //quita sentencia bloque pila.Pop(); pila.Pop(); //quita el else break; case 34: // <ListaArgumentos> ::= , <Expresion> <ListaArgumentos> pila.Pop(); aux = ((Node)pila.Pop()); //quita la lsta de argumentos pila.Pop(); nodo = ((Node)pila.Pop()); //quita expresion pila.Pop(); pila.Pop(); //quita la , nodo.Siguiente = aux; break; case 36: pila.Pop(); nodo = new Identificador(((Terminal)pila.Pop()).nodo.Simbolo); break; case 37: pila.Pop(); nodo = new Constante(((Terminal)pila.Pop()).nodo.Simbolo); break; case 38: nodo = new LlamadaFunc(ref pila); break; //R42 < Expresion > ::= opSuma < Expresion > //R43 < Expresion > ::= opNot < Expresion > case 42: case 43: nodo = new Operacion1(ref pila); break; //R44 < Expresion > ::= < Expresion > opMul < Expresion > //R45 < Expresion > ::= < Expresion > opSuma < Expresion > //R46 < Expresion > ::= < Expresion > opRelac < Expresion > //R47 < Expresion > ::= < Expresion > opIgualdad < Expresion > //R48 < Expresion > ::= < Expresion > opAnd < Expresion > //R49 < Expresion > ::= < Expresion > opOr < Expresion > case 44: case 45: case 46: case 47: case 48: case 49: nodo = new Operacion2(ref pila); break; //aqui cae R2,R7,R10,R12,R15,R19,R28,R31,R33, default: pops = Rules.ElementAt(r).TotalProductions; if (pops > 0) { while (pops > 0) { pila.Pop(); pila.Pop(); pops--; } } break; } //x = (int)pila.Peek(); x = ((Estado)pila.Peek()).transicion; //((Estado)pila.Peek()).numestado; y = rules.ElementAt(r).Id; //columna= idreglas[regla]; NoTerminal nt = new NoTerminal(y); //NoTerminal NT =new NoTerminal(idreglas[regla]); //nt.nodo = nodo; //pila.Push(rules.ElementAt(r).Id); pila.Push(nodo); r = tablaLR[x, y]; //transicion = tabla[fila][columna]; //pila.Push(r); pila.Push(new Estado(r)); newSymbol = false; Root = nodo; } else { //Error error = true; } } Root.validatipos(ASemantico.Simbolos, ASemantico.Errores); if (error) { currentSymbol.ErrorSintactico = true; } if (ASemantico.Errores.Count > 0) { currentSymbol.ErrorSemantico = true; currentSymbol.Errores = ASemantico.Errores; error = true; } return(error ? currentSymbol : null); }
private string CaptarMensajeErrorApropiado(NoTerminal nt, Terminal t) { string x; return(string.Empty); }
internal NodoTablaAnalisisGramatica BuscarNodo(NoTerminal nt, Terminal t) { return(this.EncontrarNodo(nt, t)); }
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); }
private bool PerteneceNoTerminalesNoEscapeables(NoTerminal nt) { return(nt.Nombre.Equals("EXPR") || nt.Nombre.Equals("BLQ") || nt.Nombre.Equals("PROCEDIMIENTO") || nt.Nombre.Equals("PROCED")); }
public RetornoPrimeros() { this.terminales = new List <Terminal>(); this.esNecesarioSiguiente = false; this.noTerminal = null; }
public void AgregarNodo(NoTerminal nt, Produccion prod, List <Terminal> terms) { this.nodos.Add(new NodoTablaPrimeros(nt, prod, terms)); }