public Object EvaluaLogica(ParseTreeNode raiz) { string Inicio = raiz.ToString(); ParseTreeNode[] hijos = null; if (raiz.ChildNodes.Count > 0) { hijos = raiz.ChildNodes.ToArray(); } switch (Inicio) { #region EXPLOGICA case "CONDICIONES": { if (raiz.ChildNodes.Count() == 1) //::= EXPLOGICA { Object pr = EvaluaLogica(hijos[0]); if (pr != null) { bool f = (Boolean)pr; return(f); } } break; } case "EXPLOGICA": { if (raiz.ChildNodes.Count() == 1) //::= B { return(EvaluaLogica(hijos[0])); } break; } case "B": { if (raiz.ChildNodes.Count() == 1) //::= C { return(EvaluaLogica(hijos[0])); } if (raiz.ChildNodes.Count() == 3) { Object val1 = EvaluaLogica(hijos[0]); Object val2 = EvaluaLogica(hijos[2]); bool a; bool b; if (val1 != null && val2 != null) { a = (Boolean)val1; b = (Boolean)val2; string operando = hijos[1].ToString().Replace(" (Key symbol)", ""); if (operando == "||") //OR { return(a || b); } if (operando == "!||") //NOR { return(!(a || b)); } if (operando == "&|") //XOR { if (a == b) { return(false); } else { return(true); } } } else { ErrorEnAnalisis error = new ErrorEnAnalisis("No se puede Aplicar Operaciones Logicas", "Error Semantico", hijos[1].Token.Location.Line, hijos[1].Token.Location.Column); this.errores.Add(error); } } break; } case "C": { if (raiz.ChildNodes.Count() == 1) //::= D { return(EvaluaLogica(hijos[0])); } if (raiz.ChildNodes.Count() == 3) { Object val1 = EvaluaLogica(hijos[0]); Object val2 = EvaluaLogica(hijos[2]); bool a; bool b; if (val1 != null && val2 != null) { a = (Boolean)val1; b = (Boolean)val2; string operando = hijos[1].ToString().Replace(" (Key symbol)", ""); if (operando == "&&") //AND { return(a && b); } if (operando == "!&&") //NAND { return(!(a && b)); } } else { ErrorEnAnalisis error = new ErrorEnAnalisis("No se puede Aplicar Operaciones Logicas", "Error Semantico", hijos[1].Token.Location.Line, hijos[1].Token.Location.Column); this.errores.Add(error); } } break; } case "D": { if (raiz.ChildNodes.Count() == 1) //::= RELACIONALES { try { bool prueba = (Boolean)EvaluaLogica(hijos[0]); return(prueba); } catch { return(null); } } if (raiz.ChildNodes.Count() == 2) //::= not RELACIONALES { try { bool prueba = (Boolean)EvaluaLogica(hijos[1]); return(!prueba); } catch { return(null); } } break; } #endregion #region RELACIONALES case "RELACIONALES": { if (raiz.ChildNodes.Count() == 1) //::= A { return(EvaluaLogica(hijos[0])); } break; } case "A": { if (raiz.ChildNodes.Count() == 3) { string operando = hijos[1].ToString().Replace(" (Key symbol)", ""); Elemento a = (Elemento)EvaluaLogica(hijos[0]); Elemento b = (Elemento)EvaluaLogica(hijos[2]); if (a != null && b != null) { if (a.tipo == "boolean" || b.tipo == "boolean") { ErrorEnAnalisis error = new ErrorEnAnalisis("Operador: (" + operando + ") No se puede Aplicar entre Tipo: " + a.tipo + " y " + b.tipo, "Error Semantico", hijos[1].Token.Location.Line, hijos[1].Token.Location.Column); this.errores.Add(error); } else { int valor1 = Convert.ToInt32(a.valor); int valor2 = Convert.ToInt32(b.valor); return(evaluarelacionales(valor1, valor2, operando)); //RETORNO FALSO O VERDADERO } } } if (raiz.ChildNodes.Count() == 1) { if (hijos[0].ToString().Contains("EXPR")) { Expresion ele1 = new Expresion("boolean", this.variables, this.ambito); Elemento elem = (Elemento)ele1.recorre_expresion(hijos[0]); Expresion ele2 = new Expresion("entero", this.variables, this.ambito); Elemento elem2 = (Elemento)ele2.recorre_expresion(hijos[0]); if (elem != null) { return(ConvertElementToBool(elem)); } if (elem2 != null) { return(elem2); } if (elem == null && elem2 == null) { foreach (ErrorEnAnalisis r in ele1.getErroresSemanticos()) { this.errores.Add(r); } foreach (ErrorEnAnalisis s in ele2.getErroresSemanticos()) { this.errores.Add(s); } } } if (hijos[0].ToString().Contains("EXPLOGICA")) { return(EvaluaLogica(hijos[0])); } if (hijos[0].ToString().Contains("RELACIONALES")) { return(EvaluaLogica(hijos[0])); } } break; } #endregion } return(null); }
private object generarTabla(ParseTreeNode raiz) { string Inicio = raiz.ToString(); ParseTreeNode[] hijos = null; if (raiz.ChildNodes.Count > 0) { hijos = raiz.ChildNodes.ToArray(); } switch (Inicio) { case "INICIO": //CUANDO ME ENCUENTRO EN LA PRODUCCIÓN DEL INICIO { if (raiz.ChildNodes.Count() == 5) { string visi = generarTabla(hijos[0]).ToString(); visi = visi.Replace(" (Keyword)", ""); this.visibilidad = visi; string tipo = hijos[1].ToString().Replace(" (Keyword)", ""); string nombre = hijos[2].ToString().Replace(" (identificador)", ""); this.nombre = nombre; ambitos.Push(nombre); //EXTIENDES generarTabla(hijos[3]); Simbolo nuevo = new Simbolo(nombre, tipo, visi, "No Aplica", ambitos.Peek(), false); Tabla.Add(nuevo); //ME MUEVO AL CUERPO DEL LIENZO generarTabla(hijos[4]); } break; } case "EXTIENDE": { if (raiz.ChildNodes.Count() == 2) { generarTabla(hijos[1]); } break; } case "LISTADOEX": { if (raiz.ChildNodes.Count() == 3) //::= LISTADOEX com LISTADOEX { generarTabla(hijos[0]); generarTabla(hijos[1]); } if (raiz.ChildNodes.Count() == 1) //::= identificador { String ext = hijos[0].ToString().Replace(" (identificador)", ""); this.Extends.Add(ext); } break; } case "VISIBILIDAD": { if (raiz.ChildNodes.Count() == 1) { return(hijos[0].ToString().Replace(" (Keyword)", "")); } else { return("privado"); } break; } case "CUERPOLIENZO": { if (raiz.ChildNodes.Count() == 2) { generarTabla(hijos[0]); generarTabla(hijos[1]); } break; } case "PRINCIPAL": { if (raiz.ChildNodes.Count() == 2) { //CAPTURO EL MÉTODO PRINCIPAL string nombre = hijos[0].ToString().Replace(" (Keyword)", ""); Simbolo nuevo = new Simbolo(nombre, "Main", "No Aplica", "No Aplica", ambitos.Peek(), false); Procedimiento principal = new Procedimiento(hijos[1], nombre, this.paraux); //METO PROCEDIMIENTOS NUEVOS this.procedimientos.Add(principal); //METO PROCEDMIENTOS NUEVOS ambitos.Push(nombre); Tabla.Add(nuevo); generarTabla(hijos[1]); ambitos.Pop(); //SALGO DEL AMBITO PRINCIPAL } break; } case "OTROS": { if (raiz.ChildNodes.Count() == 2) { generarTabla(hijos[0]); generarTabla(hijos[1]); } break; } case "VARGLOBALES": { if (raiz.ChildNodes.Count() == 4) { string visibi = "No Aplica"; //Me retorna si se conserva y llamo al metodo recursivamente para obtener la cadena bool conservar = seConserva(generarTabla(hijos[0]).ToString()); //debo de retornar en la producción tipo, el tipo especificado string tipo = generarTabla(hijos[2]).ToString(); this.tipo_actual_evaluado = tipo; //TIPO ACTUAL DE VARIABLES EVALUADO //me va a retornar un simbolo en la prducción tipo asignación generarTabla(hijos[3]); //mete los valores a la lista auxiliar string ambito = ambitos.Peek(); foreach (Simbolo c in auxiliar) { //aqui podría hacer las comprobaciones semánticas //SIMBOLOS c.visibilidad = visibi; c.conservar = conservar; c.tipo = tipo; c.ambito = ambito; //Tabla.Add(c); //VARIABLES: Variable var = new Variable(c.nombre, c.valor, c.tipo, c.ambito, c.conservar, true); if (VariableExisteEnAmbito(var.nombre, var.ambito)) { ErrorEnAnalisis error = new ErrorEnAnalisis("Ya existe una variable: ' " + var.nombre + " ' Declarada en ambito: ' " + ambitos.Peek() + " '", "Error Semantico", hijos[0].Token.Location.Line, hijos[0].Token.Location.Column + 3); this.erroresSemanticos.Add(error); } else { Tabla.Add(c); variables.Add(var); } } //LIBERO LA LISTA auxiliar.Clear(); tipo_actual_evaluado = null; //se reestablece el tipo global evaluado } break; } case "VARLOCALES": { if (raiz.ChildNodes.Count() == 4) { String visibi = "No Aplica"; bool conservar = seConserva(generarTabla(hijos[0]).ToString()); String tipo = generarTabla(hijos[2]).ToString(); this.tipo_actual_evaluado = tipo; //AQUI ME DIRIJO A TIPO ASIGNACIÓN: generarTabla(hijos[3]); foreach (Simbolo c in auxiliar) { c.visibilidad = visibi; c.conservar = conservar; c.tipo = tipo; c.ambito = ambitos.Peek().ToString(); if (c.esArreglo == true) { c.valor = "Varios"; c.dimensiones = this.DimensAux.Count(); List <List <int> > nueva = new List <List <int> >(); foreach (List <int> l in this.ValoresAux) { nueva.Add(l); } if (this.DimensAux.Count() > 1) { nueva.RemoveAt(0); } this.ValoresAux.Clear(); Variable vari = new Variable(c.nombre, nueva, c.tipo, c.ambito, c.conservar, false, true); foreach (int v in this.DimensAux) { vari.dimensiones.Add(v); } this.DimensAux.Clear(); if (ArregloExiste(c.nombre, c.ambito) || VariableExisteEnAmbito(c.nombre, c.ambito)) { ErrorEnAnalisis err = new ErrorEnAnalisis("Ya existe una variable: ' " + c.nombre + " ' declarada en ambito: ' " + c.ambito + " '", "Error Semantico", this.Line, this.Column); this.erroresSemanticos.Add(err); } else { Tabla.Add(c); variables.Add(vari); } } else { Variable va = new Variable(c.nombre, c.valor, c.tipo, c.ambito, c.conservar, false); if (ArregloExiste(va.nombre, va.ambito) || VariableExisteEnAmbito(va.nombre, va.ambito)) { ErrorEnAnalisis error = new ErrorEnAnalisis("Ya existe una variable: ' " + va.nombre + " ' declarada en ambito: ' " + va.ambito + " '", "Error Semantico", this.Line, this.Column); this.erroresSemanticos.Add(error); } else { Tabla.Add(c); variables.Add(va); } } //Tabla.Add(c); //AQUI EVALUARÉ SI ES UN ARREGLO PARA PROCEDER } auxiliar.Clear(); tipo_actual_evaluado = null; } break; } case "PRO_FUNC": { if (raiz.ChildNodes.Count() == 3) //PRO_FUNC ::= CONSERVAR VISIBILIDAD + PRO_FUNCP { Boolean conservar = seConserva(hijos[0].ToString()); //VIENDO SI SE CONSERVA String visibilidad = generarTabla(hijos[1]).ToString(); //OBTENIENDO VISIVILIDIAD Simbolo simbol = (Simbolo)generarTabla(hijos[2]); //SIMBOLO QUE DETERMINA SI ES FUNCION O PROCEDIMIENTO if (simbol != null) { simbol.conservar = conservar; simbol.visibilidad = visibilidad; this.Tabla.Add(simbol); } //debo de capturar los parametros que tienen this.paraux.Clear(); ambitos.Pop(); } break; } case "PRO_FUNCP": { if (raiz.ChildNodes.Count() == 1) //::= PROCEDIMIENTOS { return(generarTabla(hijos[0])); } if (raiz.ChildNodes.Count() == 2) // ::= TIPO FUNCIONES { String tipo = generarTabla(hijos[0]).ToString(); Simbolo simbol = (Simbolo)generarTabla(hijos[1]); ParseTreeNode [] subhijos = hijos[1].ChildNodes.ToArray(); List <Parametro> parameters = new List <Parametro>(); Funcion fun = new Funcion(subhijos[3], simbol.nombre, tipo, addParametersToList(parameters)); this.Funciones.Add(fun); return(simbol); } break; } case "PROCEDIMIENTOS": { if (raiz.ChildNodes.Count() == 3) { //aqui capturo procedimientos string nombre = hijos[0].ToString().Replace(" (identificador)", ""); String tipo = "Procedimiento"; if (nombre == "Principal") { tipo = "Main"; } //PARAMETROS generarTabla(hijos[1]); Simbolo simbolo = new Simbolo(nombre, tipo, "", "No Aplica", ambitos.Peek(), false); ambitos.Push(nombre); List <Parametro> parameters = new List <Parametro>(); Procedimiento pro = new Procedimiento(hijos[2], nombre, addParametersToList(parameters)); procedimientos.Add(pro); //AQUI FALTAN SENTENCIAS!!! generarTabla(hijos[2]); return(simbolo); } break; } case "FUNCIONES": { if (raiz.ChildNodes.Count() == 4) { int dim = 0; dim = (int)generarTabla(hijos[0]); //obtener la dimensión si es que tiene sino tendra 0 string nombre = hijos[1].ToString().Replace(" (identificador)", ""); //PARAMETROS generarTabla(hijos[2]); bool esarreglo = false; if (dim > 0) { esarreglo = true; } Simbolo simbolo = new Simbolo(nombre, "Funcion", "", "No Aplica", ambitos.Peek(), false, esarreglo, dim); ambitos.Push(nombre); //SENTENCIAS generarTabla(hijos[3]); return(simbolo); } break; } case "DIM": { if (raiz.ChildNodes.Count() == 3) { int retorno = 1; retorno = retorno + (int)generarTabla(hijos[2]); return(retorno); } else { return(0); } break; } case "PARAMETROS": { if (raiz.ChildNodes.Count() == 3) //:: PARAMETROS , PARAMETROS { generarTabla(hijos[0]); generarTabla(hijos[2]); } if (raiz.ChildNodes.Count() == 2) //TIPO identificador { String tipo = generarTabla(hijos[0]).ToString(); String nombre = hijos[1].ToString().Replace(" (identificador)", ""); Parametro parametro = new Parametro(nombre, tipo); this.paraux.Add(parametro); } break; } case "CONSERVAR": { if (raiz.ChildNodes.Count() == 1) { return(hijos[0].ToString().Replace(" (Keyword)", "")); } else { return(""); } //break; } case "DIMENSIONES": { if (raiz.ChildNodes.Count() == 4) //::= opb EXPR clb DIMENSIONES { Expresion exp = new Expresion("entero", this.variables, this.ambitos.Peek()); Elemento ele = (Elemento)exp.recorre_expresion(hijos[1]); if (ele != null) { this.DimensAux.Add(Convert.ToInt32(ele.valor)); } else { //ERRORES SEMANTICOS List <ErrorEnAnalisis> aux = exp.getErroresSemanticos(); foreach (ErrorEnAnalisis er in aux) { this.erroresSemanticos.Add(er); } } generarTabla(hijos[3]); } if (raiz.ChildNodes.Count() == 3) //::= opb EXPR clb { Expresion exp = new Expresion("entero", this.variables, this.ambitos.Peek()); Elemento ele = (Elemento)exp.recorre_expresion(hijos[1]); if (ele != null) { this.DimensAux.Add(Convert.ToInt32(ele.valor)); } else { //errores semanticos encontrados List <ErrorEnAnalisis> aux = exp.getErroresSemanticos(); foreach (ErrorEnAnalisis er in aux) { this.erroresSemanticos.Add(er); } } } break; } case "TIPO": { string tipo = hijos[0].ToString().Replace(" (Keyword)", ""); return(tipo); //break; } case "TIPOASIGNACION": { if (raiz.ChildNodes.Count() == 1) { //ME MUEVO A ASIGNACIÓN generarTabla(hijos[0]); } if (raiz.ChildNodes.Count() == 4) //::= arreglo ASIGNACIONARR DIMENSIONES LLENADOARR { //ME MUEVO A ASIGNACIÓN DE ARREGLO generarTabla(hijos[1]); //OBTENGO SIMBOLOS AUXILIARES generarTabla(hijos[2]); //OBTENGO LAS DIMENSIONES DEL ARREGLO generarTabla(hijos[3]); //LLENADO DEL ARREGLO CON SUS VALORES } break; } case "LLENADOARR": { if (raiz.ChildNodes.Count() == 3) //::= opl LISTADOARR cll { generarTabla(hijos[1]); if (this.ValoresAux.Count() == 0) { List <int> v = new List <int>(); foreach (int x in this.subValores) { v.Add(x); } this.ValoresAux.Add(v); subValores.Clear(); } //OJO AQUI EDITE else { List <int> z = new List <int>(); foreach (int x in this.subValores) { z.Add(x); } this.ValoresAux.Add(z); } //FIN EDICION subValores.Clear(); } break; } case "LISTADOARR": { if (raiz.ChildNodes.Count() == 3) { if (hijos[1].ToString().Contains(",")) //::= LISTADOARR com LISTADOARR { generarTabla(hijos[0]); generarTabla(hijos[2]); } else //::= opl LISTADOARR cll { List <int> nueva = new List <int>(); //CREO UNA NUEVA LISTA foreach (int x in this.subValores) //RECORRO LOS SUBVALORES Y LOS METO A LA NUEVA { nueva.Add(x); } this.ValoresAux.Add(nueva); //METO LA LISTA DE SUBVALORES A LA LISTA DE LISTAS this.subValores.Clear(); generarTabla(hijos[1]); } } if (raiz.ChildNodes.Count() == 1) //::EXPR { Expresion ex = new Expresion("entero", this.variables, this.ambitos.Peek()); Elemento el = (Elemento)ex.recorre_expresion(hijos[0]); if (el != null) { this.subValores.Add(Convert.ToInt32(el.valor)); } else { //ERRORES SEMANTICOS List <ErrorEnAnalisis> aux = ex.getErroresSemanticos(); foreach (ErrorEnAnalisis er in aux) { this.erroresSemanticos.Add(er); } } } break; } case "ASIGNACIONARR": { if (raiz.ChildNodes.Count() == 3) //::= ASIGNACIONARR com ASIGNACIONARR { generarTabla(hijos[0]); generarTabla(hijos[2]); } if (raiz.ChildNodes.Count() == 1) { //AQUI PONDRE LAS REFERENCIAS A LAS LINEAS Y COLUMNAS DE ASIGNACIÓN this.Line = hijos[0].Token.Location.Line; this.Column = hijos[0].Token.Location.Column; string nombre = hijos[0].ToString().Replace(" (identificador)", ""); Simbolo sim = new Simbolo(nombre, "", "", "", this.ambitos.Peek(), false, true, 0); this.auxiliar.Add(sim); } break; } case "ASIGNACION": { if (raiz.ChildNodes.Count() == 1) //ASIGNAICIÓN SOLO PRODUCE UN IDENTIFICADOR { //AQUI PONDRE LAS REFERENCIAS A LAS LINEAS Y COLUMNAS DE ASIGNACIÓN this.Line = hijos[0].Token.Location.Line; this.Column = hijos[0].Token.Location.Column; Simbolo aux = new Simbolo(); aux.nombre = hijos[0].ToString().Replace(" (identificador)", ""); aux.valor = null; auxiliar.Add(aux); //AÑADO A LISTA AUXILIAR } if (raiz.ChildNodes.Count() == 2) //CUANDO VIENE UNA ASIGNACIÓN DE UNA VARIABLE CON SU VALOR { //PENDIENTE DE VERIFICAR SU VALOR this.Line = hijos[0].Token.Location.Line; this.Column = hijos[0].Token.Location.Column; Simbolo aux = new Simbolo(); aux.nombre = hijos[0].ToString().Replace(" (identificador)", ""); //evaluo una nueva expresión Expresion expr = new Expresion(this.tipo_actual_evaluado, this.variables, ambitos.Peek()); Elemento ele = (Elemento)expr.recorre_expresion(hijos[1]); if (ele != null) { aux.valor = ele.valor; //RECORRO LA EXPRESIÓN PARA OBTENER EL VALOR this.auxiliar.Add(aux); //añado a la lista auxiliar } else { //SEMANTICOS List <ErrorEnAnalisis> errores = expr.getErroresSemanticos(); foreach (ErrorEnAnalisis er in errores) { //MessageBox.Show(er.getError() + " | Linea: " + er.getLinea() + " | Columna: " + er.getColumna()); List <ErrorEnAnalisis> aux1 = expr.getErroresSemanticos(); foreach (ErrorEnAnalisis err in aux1) { this.erroresSemanticos.Add(err); } } } } if (raiz.ChildNodes.Count() == 3) //ASIGNACIÓN PRODUCE UN LISTADO DE IDS { generarTabla(hijos[0]); //ME VOY A ASIGNACIÓN DE UN HIJO generarTabla(hijos[2]); //ASIGNACIÓN RECURSIVA } break; } case "SENTENCIAS": { if (raiz.ChildNodes.Count() == 2) { if (hijos[0].ToString().Contains("VARLOCALES")) { generarTabla(hijos[0]); generarTabla(hijos[1]); } else //CUALQUIER OTRA PRODUCCIÓN QUE VENGA SE IRA A SENTENCIAS PARA BUSCAR MÁS ASIGNACIONES { generarTabla(hijos[0]); generarTabla(hijos[1]); } } break; } case "SENTENCIA_SI": { generarTabla(hijos[2]); //SOLO DE PASO break; } case "SENTENCIA_MIENTRAS": { generarTabla(hijos[2]); //SOLO DE PASO break; } case "SENTENCIA_PARA": { generarTabla(hijos[4]); //SOLO DE PASO break; } case "SENTENCIA_HACER": { generarTabla(hijos[1]); //SOLO DE PASO break; } case "SENTENCIASP": { if (raiz.ChildNodes.Count == 2) { if (hijos[0].ToString().Contains("VARLOCALES")) { generarTabla(hijos[0]); generarTabla(hijos[1]); } else { generarTabla(hijos[0]); generarTabla(hijos[1]); } } break; } } return(""); }