public void NoSeEsperaba(int id, string fase, ElementoDFD elemento) { Token tempToken = ValoresGlobales.valores().tablaDeTokens.ObtenerIdToken(id); detalle = "No se esperaba un " + tempToken.nombre + " Dentro del elemento " + elemento.tipo.ToString(); ElementoError = elemento; faseAnalisis = fase; }
} //Constructor vacio //---------------------------------------------------------------------------------------------------- // FUNCIONES PARA INGRESAR LOS DIFERENTES TIPOS DE ERRORES ENCONTRADOS DENTRO DE LA EJECUCION //---------------------------------------------------------------------------------------------------- public Error(int id, string fase, ElementoDFD elemento, TokenData tempTokendata) { Token tempToken = ValoresGlobales.valores().tablaDeTokens.ObtenerIdToken(id); detalle = "Se esperaba un " + tempToken.nombre + " en vez de " + tempTokendata.codigo + " Dentro del elemento " + elemento.tipo.ToString(); ElementoError = elemento; faseAnalisis = fase; }
//Se Guarda el archivo en un formato de texto linea por linea recorriendo el grafo actual public void GuardarArchivo(string ruta) { fileStream = new FileStream(ruta, FileMode.Create); streamWriter = new StreamWriter(fileStream); ElementoDFD tempElemento = ValoresGlobales.valores().elementoRaiz; Recorrer(tempElemento); streamWriter.Close(); }
//Funcion recursiva que se utiliza para generar las inserciones dentro del archivo de texto //Segun la conformacion del grafo private void Recorrer(ElementoDFD elemento) { if (elemento == null) { return; } switch (elemento.tipo) { case Elemento.Eif: streamWriter.WriteLine(elemento.tipo.ToString()); streamWriter.WriteLine(elemento.datos); streamWriter.WriteLine("derecha"); Recorrer(elemento.derecha); streamWriter.WriteLine("izquierda"); Recorrer(elemento.izquierda); elemento = elemento.centro; streamWriter.WriteLine(elemento.tipo.ToString()); Recorrer(elemento.centro); break; case Elemento.EndIf: return; break; case Elemento.inicio: streamWriter.WriteLine(elemento.tipo.ToString()); Recorrer(elemento.centro); break; case Elemento.fin: streamWriter.WriteLine(elemento.tipo.ToString()); return; break; case Elemento.EndWhile: case Elemento.Endfor: streamWriter.WriteLine(elemento.tipo.ToString()); Recorrer(elemento.centro); break; default: streamWriter.WriteLine(elemento.tipo.ToString()); streamWriter.WriteLine(elemento.datos); Recorrer(elemento.centro); break; } }
public void AnalizarTipos() { Stack <ElementoDFD> elementoIf = new Stack <ElementoDFD>(); //Se obtien la regerencia al grafo formado para por el analizador sintactico tempElemento = ValoresGlobales.valores().elementoRaiz; //A continuacion se procede a realizar un analisis semantico el cual consistira en esta etapa //En la verificacion de los tipos de datos dentro de las cadenas while (tempElemento.tipo != Elemento.fin) {//Se verificaa el tipo de elemento que se esta analizando para luego proceder a analizar la validez de las variables switch (tempElemento.tipo) { case Elemento.Asignacion: VerificarAsignacion(); break; case Elemento.Escritura: verificarEscritura(); break; case Elemento.Lectura: verificarLectura(); break; case Elemento.Eif: //En este caso se procede a realizar un analisis con un stack para recorrer los elementos internos dentro del if VerificarIf(); if (tempElemento.derecha != null) { tempElemento = tempElemento.derecha; elementoIf.Push(tempElemento); continue; } else if (tempElemento.izquierda != null) { tempElemento = tempElemento.izquierda; elementoIf.Push(tempElemento); continue; } break; case Elemento.EndIf: //Se espera que el elemento sea el fin del if para indicar el fin del analisis recursivo if (elementoIf.Count > 0) { if (tempElemento.padre.derecha == elementoIf.Peek()) { tempElemento = tempElemento.padre.izquierda; elementoIf.Pop(); continue; } } break; case Elemento.EWhile: //Para la funcion while se utiliza la funcion de verificacion del if ya que esta //es identica a la del if por la forma EXP COMP EXP VerificarIf(); break; default: break; } tempElemento = tempElemento.centro; //Se procede a analizar el siguiente elemento del grafo } }
public void GenerarEjecutable(string nombre) { //Se prepara el entorno para la generacion de codigo MSIL para luego ser compilado //Se establece el dominio del aplicativo en el cual va a ser compilado en este caso //se trabaja con el mismo del programa AppDomain appDomain = AppDomain.CurrentDomain; //Esta se utiliza para dar los parametros acerca de la informacion del compilable //En este caso nos sirve para poner el nombre asignado al ensamblado AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = nombre; //Esta clase nos permite crear un ejecutable dinamicamente es decir crear un ejecutable //Desde el programa siempre y cuando se utilice MSLI y las clases ILGenerator para poder //Proporcionar el lenguaje intermedio con el cual trabaja AssemblyBuilder assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save); //Esto nos permite crear un modulo dinamico que luego sera utilizado por TypeBuilder ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Modulo", nombre + ".exe"); //Esta se encarga de crear la definicion de la ruta y el metodo inicial dentro de nuestro programa TypeBuilder typeBuilder = moduleBuilder.DefineType("MiTipo", TypeAttributes.Public); //Este es el discreptor principal que engloba todos los parametros anteriores //Para ser utilizado con el MSIL MethodBuilder methodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, null, null); //Linea de codigo que proporciona la linea de entrada en la cual se ejecutar //La funcion principal en este caso el "Main" assemblyBuilder.SetEntryPoint(methodBuilder); //Se entrega a la clase ILGenerator los parametros para poder crear un ejecutable una vez terminado //EL ingreso de todo el codigo para crear el codigo MSLI il = methodBuilder.GetILGenerator(); //Se comienza a formar el codigo apartir del Arbol que se creo en los analizadores obteniendo el elemento Raiz ElementoDFD raiz = ValoresGlobales.valores().elementoRaiz; //Ahora se comienza a recorrer todo el arbol para generar el codigo de acuerdo a la estructura planteada Stack <ElementoDFD> elementoIf = new Stack <ElementoDFD>(); Stack <Label> ifSi = new Stack <Label>(); Stack <Label> ifEnd = new Stack <Label>(); Stack <Label> EndWhile = new Stack <Label>(); Stack <Label> BeginWhile = new Stack <Label>(); tempElemento = raiz; //Mientras no se llege al final del grafo while (tempElemento.tipo != Elemento.fin) { switch (tempElemento.tipo) { case Elemento.Asignacion: GenerarAsignaciones(); break; case Elemento.Escritura: GenerarEscritura(); break; case Elemento.Lectura: GenerarLectura(); break; case Elemento.Eif: IngresarOperaciones(PolacaInversa(tempElemento.tokenDataRef[0])); IngresarOperaciones(PolacaInversa(tempElemento.tokenDataRef[2])); Label if_si = il.DefineLabel(); Label if_fin = il.DefineLabel(); ifSi.Push(if_si); ifEnd.Push(if_fin); switch (tempElemento.tokenDataRef[1].tokenInfo.id) { case 38: // == il.Emit(OpCodes.Beq, if_si); break; case 39: // <= il.Emit(OpCodes.Ble, if_si); break; case 40: // >= il.Emit(OpCodes.Bge, if_si); break; case 41: // < il.Emit(OpCodes.Blt, if_si); break; case 42: // > il.Emit(OpCodes.Bgt, if_si); break; case 43: // != il.Emit(OpCodes.Bne_Un, if_si); break; } if (tempElemento.derecha != null) { tempElemento = tempElemento.derecha; elementoIf.Push(tempElemento); continue; } else if (tempElemento.izquierda != null) { il.Emit(OpCodes.Br, ifEnd.Peek()); il.MarkLabel(ifSi.Pop()); tempElemento = tempElemento.izquierda; continue; } else { il.Emit(OpCodes.Br, ifEnd.Peek()); il.MarkLabel(ifSi.Pop()); } break; case Elemento.EndIf: if (elementoIf.Count > 0) { if (tempElemento.padre.derecha == elementoIf.Peek()) { il.Emit(OpCodes.Br, ifEnd.Peek()); il.MarkLabel(ifSi.Pop()); tempElemento = tempElemento.padre.izquierda; elementoIf.Pop(); continue; } } il.MarkLabel(ifEnd.Pop()); break; case Elemento.EWhile: Label end_while = il.DefineLabel(); Label begin_while = il.DefineLabel(); Label si_while = il.DefineLabel(); EndWhile.Push(end_while); BeginWhile.Push(begin_while); il.MarkLabel(begin_while); IngresarOperaciones(PolacaInversa(tempElemento.tokenDataRef[0])); IngresarOperaciones(PolacaInversa(tempElemento.tokenDataRef[2])); switch (tempElemento.tokenDataRef[1].tokenInfo.id) { case 38: // == il.Emit(OpCodes.Beq, si_while); break; case 39: // <= il.Emit(OpCodes.Ble, si_while); break; case 40: // >= il.Emit(OpCodes.Bge, si_while); break; case 41: // < il.Emit(OpCodes.Blt, si_while); break; case 42: // > il.Emit(OpCodes.Bgt, si_while); break; case 43: // != il.Emit(OpCodes.Bne_Un, si_while); break; } il.Emit(OpCodes.Br, end_while); il.MarkLabel(si_while); break; case Elemento.EndWhile: il.Emit(OpCodes.Br, BeginWhile.Pop()); il.MarkLabel(EndWhile.Pop()); break; } tempElemento = tempElemento.centro; } //Codigo para hacer una pausa al final del codigo mediante una lectura de teclado il.Emit(OpCodes.Call, metodoLeer); //Hace la devolucion del CPU a la computadora il.Emit(OpCodes.Ret); //Se crea el ejecutable apartir del codigo MSLI creado anteriormente typeBuilder.CreateType(); assemblyBuilder.Save(nombre + ".exe"); }
//Se recorre todo el arbol y se va verificando los elementos agregados a este public void GenerarArbol() { Stack <ElementoDFD> elementoIf = new Stack <ElementoDFD>(); tempElemento = ValoresGlobales.valores().elementoRaiz; while (tempElemento.tipo != Elemento.fin) { switch (tempElemento.tipo) { case Elemento.Asignacion: //Se limpian las referencias del arbol tempElemento.tokenDataRef.Clear(); //Se obtiene los parametros de las cadenas para poder proceder a realizar el analisis lexico if (tempElemento.datos != null) { string[] cadena = tempElemento.datos.Split('\n'); if (cadena.Length > 1) { tempElemento.tokenDataRef.Add(SintaxisAsignacion(cadena[0])); } ; if (cadena.Length > 2) { tempElemento.tokenDataRef.Add(SintaxisAsignacion(cadena[1])); } ; if (cadena.Length > 3) { tempElemento.tokenDataRef.Add(SintaxisAsignacion(cadena[2])); } ; } break; case Elemento.Escritura: tempElemento.tokenDataRef.Clear(); tempElemento.tokenDataRef.Add(SintaxisExpresionSalida(tempElemento.datos)); break; case Elemento.Lectura: tempElemento.tokenDataRef.Clear(); string[] cadenaLectura = tempElemento.datos.Split(','); int i = 0; while (i < cadenaLectura.Length) { tempElemento.tokenDataRef.Add(SintaxisExpresionLectura(cadenaLectura[i++])); } break; case Elemento.Eif: tempElemento.tokenDataRef.Clear(); //Se agregan los datos para que el analizador trabaje analizadorLexico.AgregarCodigo(tempElemento.datos); analizadorLexico.tempElemento = tempElemento; //Se procede a verifiar la sintaxis tempElemento.tokenDataRef.Add(SintaxisExpresionIf()); if (analizadorLexico.returnToken != null) { //Se verifica si el token ingresado es uno de los esperados switch (analizadorLexico.returnToken.tokenInfo.id) { case 38: // == case 39: // <= case 40: // >= case 41: // < case 42: // > case 43: // != tempElemento.tokenDataRef.Add(analizadorLexico.returnToken); break; default: Error error2 = new Error(); error2.NoSeEsperaba(analizadorLexico.returnToken.tokenInfo.id, "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error2); break; } tempElemento.tokenDataRef.Add(SintaxisExpresionIf()); if (tempElemento.derecha != null) { tempElemento = tempElemento.derecha; elementoIf.Push(tempElemento); continue; } else if (tempElemento.izquierda != null) { tempElemento = tempElemento.izquierda; elementoIf.Push(tempElemento); continue; } } else { Error error = new Error(); error.ErrorCustom("No se han obtendido la gramatica esperada 'EXP COMPARADOR EXP' en el elemento" + tempElemento.tipo.ToString(), "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); } break; case Elemento.EndIf: if (elementoIf.Count > 0) { if (tempElemento.padre.derecha == elementoIf.Peek()) { tempElemento = tempElemento.padre.izquierda; elementoIf.Pop(); continue; } } break; case Elemento.EWhile: tempElemento.tokenDataRef.Clear(); //Se agregan los datos para que el analizador trabaje analizadorLexico.AgregarCodigo(tempElemento.datos); analizadorLexico.tempElemento = tempElemento; //Se procede a verifiar la sintaxis tempElemento.tokenDataRef.Add(SintaxisExpresionIf()); if (analizadorLexico.returnToken != null) { //Se verifica si el token ingresado es uno de los esperados switch (analizadorLexico.returnToken.tokenInfo.id) { case 38: // == case 39: // <= case 40: // >= case 41: // < case 42: // > case 43: // != tempElemento.tokenDataRef.Add(analizadorLexico.returnToken); break; default: Error error2 = new Error(); error2.NoSeEsperaba(analizadorLexico.returnToken.tokenInfo.id, "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error2); break; } tempElemento.tokenDataRef.Add(SintaxisExpresionIf()); } else { Error error = new Error(); error.ErrorCustom("No se han obtendido la gramatica esperada 'EXP COMPARADOR EXP' en el elemento" + tempElemento.tipo.ToString(), "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); } break; default: break; } tempElemento = tempElemento.centro; } }
public void ErrorCustom(string mensaje, string fase, ElementoDFD elemento) { detalle = mensaje; ElementoError = elemento; faseAnalisis = fase; }