private void btnCompilar_Click(object sender, EventArgs e) { ValoresGlobales.valores().LimpiarDatos(); ValoresGlobales.valores().elementoRaiz = ucdfd1.ObtenerRaiz(); AnalizadorSintactico analisSintactico = new AnalizadorSintactico(); AnalizadorSemantico analisisSemantico = new AnalizadorSemantico(); GenerarCodigo generarCodigo = new GenerarCodigo(); analisSintactico.GenerarArbol(); if (!ValoresGlobales.valores().tablaDeErrores.Existen()) { analisisSemantico.AnalizarTipos(); } //Se verifica si existen errores o no dentro del codigo antes de compilarlo if (!ValoresGlobales.valores().tablaDeErrores.Existen()) { if (txtNombre.Text == "") { txtNombre.Text = "Ejecutable"; } generarCodigo.GenerarEjecutable(txtNombre.Text); System.Diagnostics.Process.Start(txtNombre.Text + ".exe"); } else { FrmTablaDeErrores frmTablaDeErrores = new FrmTablaDeErrores(); frmTablaDeErrores.Show(); } }
public bool verificarNumero() { returnToken = null; int punto = 0; union = ""; union += codigo[pos]; //Se comienza a formar la palabras pos++; //Se pasa a la siguiente posicion if (pos < codigo.Length) { //Se verifica que no sea el final de la cadena //Ahora como comenzamos a verificar que sea una palabra //Verificamos si es un numero o "." while (char.IsDigit(codigo[pos]) || codigo[pos] == '.') { if (codigo[pos] == '.') { punto++; } //Procegimos a concatenar y verificar el siguiente caracter union += codigo[pos]; pos++; if (pos == codigo.Length) { break; // si llegamos al final salimos de ella } } } if (punto > 1) { return(false); } returnToken = new TokenData(union, ValoresGlobales.valores().tablaDeTokens.ObtenerToken("numDecimal")); return(true); }
private void verificarLectura() { TokenData tempTokenData; foreach (TokenData tokenref in tempElemento.tokenDataRef) { tempTokenData = tokenref; //Mientras no se llege al final while (tempTokenData != null) { if (tempTokenData.tokenInfo.id == 53) { tempTokenData.tokenInfo = ValoresGlobales.valores().tablaDeSimbolos.ObtenerToken(tempTokenData.codigo); } switch (tempTokenData.tokenInfo.id) { case 58: //cadena case 29: // + case 59: //Variable numeros case 60: //Variable caracteres break; case 53: //Identificador //Se verifica el tipo de dato para ver si coincide o no Error errorIdentificador = new Error(); errorIdentificador.ErrorCustom("La variable : '" + tempTokenData.codigo + "' No se ha declarado", "Semantico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(errorIdentificador); break; } tempTokenData = tempTokenData.tokenDataRef; } } }
//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(); }
private TokenData SintaxisAsignacion(string cadena) { TokenData returnTokenData = new TokenData(); //Se agrega el codigo a ser analizado por el analizador lexico analizadorLexico.tempElemento = tempElemento; analizadorLexico.AgregarCodigo(cadena); //Variable temporal para almacenar el tokendata TokenData tempTokenData; int[] patron = { 53, 37 }; int posPatron = 0; bool er = true; while (analizadorLexico.ObtenerToken()) { tempTokenData = analizadorLexico.returnToken; if (posPatron < patron.Length) { if (patron[posPatron] == tempTokenData.tokenInfo.id) { if (posPatron == 0) { returnTokenData = tempTokenData; } else { returnTokenData.tokenDataRef = tempTokenData; } posPatron++; } else { //Agregando el error correspondiente ValoresGlobales.valores().tablaDeErrores.errores.Add(new Error(patron[posPatron], "Sintactico", tempElemento, tempTokenData)); } } else { returnTokenData.tokenDataRef.tokenDataRef = SintaxisExpresionesAsignacion(); if (returnTokenData.tokenDataRef.tokenDataRef != null) { er = false; } } } if (er == true) { Error error = new Error(); error.ErrorCustom("Expresion ingresada incorrecta dentro del elemento" + tempElemento.tipo.ToString(), "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); } return(returnTokenData); }
private void FrmTablaDeErrores_Load_1(object sender, EventArgs e) { error = ValoresGlobales.valores().tablaDeErrores.errores.ToArray(); int i = 0; foreach (Error tempError in error) { DGrid.Rows.Add(); DGrid.Rows[i].Cells[0].Value = i.ToString(); DGrid.Rows[i].Cells[1].Value = tempError.faseAnalisis; DGrid.Rows[i].Cells[2].Value = tempError.detalle; i++; } }
private void BtnGuardar_Click(object sender, EventArgs e) { SaveFile = new SaveFileDialog(); SaveFile.Filter = "txt files (*.txt)|*.txt"; SaveFile.DefaultExt = "txt"; SaveFile.Title = "Guardar Archivo DFD"; SaveFile.ShowDialog(); // If the file name is not an empty string open it for saving. if (SaveFile.FileName != "") { ValoresGlobales.valores().elementoRaiz = ucdfd1.ObtenerRaiz(); GuardarCargarDFD guardar = new GuardarCargarDFD(); guardar.GuardarArchivo(SaveFile.FileName); } }
private void button2_Click_2(object sender, EventArgs e) { OpenFile = new OpenFileDialog(); OpenFile.Filter = "txt files (*.txt)|*.txt"; OpenFile.FilterIndex = 2; if (OpenFile.ShowDialog() == DialogResult.OK) { try { ValoresGlobales.valores().elementoRaiz = ucdfd1.ObtenerRaiz(); GuardarCargarDFD guardar = new GuardarCargarDFD(); ucdfd1.CargarDFD(guardar.Leer(OpenFile.FileName)); } catch (Exception ex) { MessageBox.Show("Error No se logro abrir el archivo deseado probablemente el formato no es el adecuado"); } } }
public bool verificarCadena() { returnToken = null; union = ""; union += codigo[pos];//Se comienza a formar el codigo de la palabra //Se incremente la posicion de la palabra pos++; if (pos + 1 > codigo.Length) { return(false); } //Se recorre la cadena para verificar que sea un dato while (codigo[pos] != '"' && pos < codigo.Length) { if (pos < codigo.Length - 1) { if (codigo[pos] == '\\' && codigo[pos + 1] == 'n') { union += '\n'; pos += 2; } else { union += codigo[pos++]; } } else { break; } } union += codigo[pos]; if (codigo[pos] != '"') { return(false); } pos++; returnToken = new TokenData(union, ValoresGlobales.valores().tablaDeTokens.ObtenerToken("cadena")); return(true); }
}//Fin de SintaxisExpresionIf() private TokenData SintaxisExpresionesAsignacion() { if (analizadorLexico.returnToken == null) { Error error = new Error(); error.ErrorCustom("Expresion ingresada No cumple la sintaxis en el elemento" + tempElemento.tipo.ToString(), "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); return(null); } switch (analizadorLexico.returnToken.tokenInfo.id) { //Caso en el que inicie con un parentesis ( ,variable o un numero case 23: case 53: case 55: case 30: return(SintaxisExpresion()); break; //En caso sea una cadena case 58: TokenData temp = analizadorLexico.returnToken; if (analizadorLexico.ObtenerToken()) { Error error = new Error(); error.ErrorCustom("Expresion ingreada no cumple requisitos de ser solamente una cadena", "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); } return(temp); break; break; } return(null); }
public bool verificarVariables() { union = ""; union += codigo[pos];//Se comienza a formar el codigo de la palabra //Se incremente la posicion de la palabra pos++; //Se recorre la cadena para verificar que sea un dato if (!(pos < codigo.Length)) { goto continuar; } while (codigo[pos] != ' ') { if (!IsNextToken()) { if (char.IsLetterOrDigit(codigo[pos]) || codigo[pos] == '_') {//Se continua agregando datos union += codigo[pos++]; if (!(pos < codigo.Length)) { break; } } else { //Codigos de escape al encontrar otro caracter a la par if (codigo[pos] == '=') { break; } if (codigo[pos] == '+') { break; } if (codigo[pos] == '-') { break; } if (codigo[pos] == '*') { break; } if (codigo[pos] == '/') { break; } if (codigo[pos] == '(') { break; } if (codigo[pos] == ')') { break; } if (codigo[pos] == ',') { break; } if (codigo[pos] == '>') { break; } if (codigo[pos] == '<') { break; } if (codigo[pos] == '!') { break; } else { return(false); } } } else { break; } } continuar: //Se procede a verificar si las variables seran registradas o no en la tabla de simbolos if (ValoresGlobales.valores().tablaDeSimbolos.VerificarSimbolo(union)) {//Se obtiene la informacion del token si esque se encontro dentro de la tabla de simbolos returnToken = new TokenData(union, ValoresGlobales.valores().tablaDeSimbolos.ObtenerToken(union)); } else {//De no estar en la tabla de simbolos se procede a ingresarlo dentro de ella con los parametros //De un identificador para poder darle seguimiento a dicha variable TokenData newToken = new TokenData(union, ValoresGlobales.valores().tablaDeTokens.ObtenerToken("identificador")); ValoresGlobales.valores().tablaDeSimbolos.AgregarToken(union, newToken); returnToken = new TokenData(union, newToken.tokenInfo); } return(true); }
//Funcion para comenzar el analisis public bool ObtenerToken() { //Se verifica si ya se llego al final de los datos a analizar if (pos == codigo.Length) { return(false); } else { //Mientras se encuentren caracters que leer while (pos < codigo.Length) { if (IsNextToken()) { //Se incrementa la posicion pos++; } else { //Se verifica si es una letra o _ if (char.IsLetter(codigo[pos]) || codigo[pos] == '_') { if (!verificarVariables()) { Error error = new Error(); error.ErrorCustom("La variable " + union + "No es valida", "Lexico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); } return(true); } else if (char.IsNumber(codigo[pos])) //Se verifica si es un numero { if (!verificarNumero()) { Error error = new Error(); error.ErrorCustom("El siguiente parametro no es valido " + union + " en el elemento" + tempElemento.tipo.ToString(), "Lexico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); } return(true); } else if (codigo[pos] == '"')//Se verifica si es una cadena { if (!verificarCadena()) { Error error = new Error(); error.ErrorCustom("La variable " + union + "No es valida", "Lexico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); } return(true); } else if (codigo[pos] == '(') //Se ingresa como token "(" { union = "("; returnToken = new TokenData(union, ValoresGlobales.valores().tablaDeTokens.ObtenerToken(union)); pos++; return(true); } else if (codigo[pos] == ')') {//Se ingresa como token ")" union = ")"; returnToken = new TokenData(union, ValoresGlobales.valores().tablaDeTokens.ObtenerToken(union)); pos++; return(true); } else if (codigo[pos] == ',') {//Se ingresa como token "," union = ","; returnToken = new TokenData(union, ValoresGlobales.valores().tablaDeTokens.ObtenerToken(union)); pos++; return(true); } else//De no ser ninguno de los anteriores se busca una concordancia con los operadores {//Para ello se verifica si esta dentro de los operadores if (!VerificarOperador()) { Error error = new Error(); error.ErrorCustom("El caractrer " + union + "No es valida no se encuentra registrado", "Lexico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); } else { return(true); } } } } } return(false); //Si no existe un token que retornar }
private bool VerificarOperador() {//Verificacion de operadores Matematicos y Logicos returnToken = null; union = ""; switch (codigo[pos]) { case '-': union += codigo[pos]; //if (codigo[pos + 1] == '-') union += codigo[pos]; break; case '+': union += codigo[pos]; //if (codigo[pos + 1] == '+') union += codigo[pos]; break; case '/': union += codigo[pos]; break; case '*': union += codigo[pos]; break; case '>': union += codigo[pos]; //if (codigo[pos + 1] == '>') union += codigo[pos]; if (codigo.Length > pos + 1) { if (codigo[pos + 1] == '=') { union += codigo[++pos]; } } break; case '<': union += codigo[pos]; //if (codigo[pos + 1] == '<') union += codigo[pos]; if (codigo.Length > pos + 1) { if (codigo[pos + 1] == '=') { union += codigo[++pos]; } } break; case '=': union += codigo[pos]; if (codigo.Length > pos + 1) { if (codigo[pos + 1] == '=') { union += codigo[++pos]; } } break; case '|': union += codigo[pos]; if (codigo.Length > pos + 1) { if (codigo[pos + 1] == '|') { union += codigo[++pos]; } } break; case '&': union += codigo[pos]; if (codigo.Length > pos + 1) { if (codigo[pos + 1] == '&') { union += codigo[++pos]; } } break; case '!': union += codigo[pos]; if (codigo.Length > pos + 1) { if (codigo[pos + 1] == '=') { union += codigo[++pos]; } } break; default: pos++; return(false); break; } //Se genera el token a regresar returnToken = new TokenData(union, ValoresGlobales.valores().tablaDeTokens.ObtenerToken(union)); pos++; return(true); }
}//Fin SintaxisExpresionLectura private TokenData SintaxisExpresionSalida(string cadena) { analizadorLexico.AgregarCodigo(cadena); analizadorLexico.tempElemento = tempElemento; TokenData raizReturn = null; TokenData tempReturn = null; Stack <int> obligatorio = new Stack <int>(); List <int> opcional = new List <int>(); //Valores opcionales iniciales opcional.Add(53); //variables opcional.Add(55); //numero opcional.Add(58); //Cadena analizadorLexico.ObtenerToken(); do { if (opcional.Contains(analizadorLexico.returnToken.tokenInfo.id)) { switch (analizadorLexico.returnToken.tokenInfo.id) { case 53: // Variables case 55: // Numeros case 58: //cadenas //Se colocan los valores opcionales a continuacion opcional.Clear(); opcional.Add(29);//variable AgregarTokenData(ref raizReturn, ref tempReturn); //Se colocan los datos obligatorios dentro del stack if (obligatorio.Count > 0) { if (obligatorio.Peek() == 58) { obligatorio.Pop(); } if (obligatorio.Peek() == 55) { obligatorio.Pop(); } if (obligatorio.Peek() == 53) { obligatorio.Pop(); } } break; case 29: //Se colocan los valores opcionales a continuacion opcional.Clear(); opcional.Add(53); //variables opcional.Add(55); //numero opcional.Add(58); //Cadena AgregarTokenData(ref raizReturn, ref tempReturn); //Datos que son obligatorios obligatorio.Push(53); obligatorio.Push(55); obligatorio.Push(58); break; default: Error error2 = new Error(); error2.NoSeEsperaba(analizadorLexico.returnToken.tokenInfo.id, "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error2); break; } } else { Error error2 = new Error(); error2.NoSeEsperaba(analizadorLexico.returnToken.tokenInfo.id, "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error2); break; } //Mientras existan tokens } while (analizadorLexico.ObtenerToken()); if (obligatorio.Count > 0) { Error error = new Error(); error.ErrorCustom("Expresion ingresada incorrecta dentro del elemento" + tempElemento.tipo.ToString(), "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error); } return(raizReturn); }
//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; } }
}//Fin VerificarEscritura() private void VerificarAsignacion() { TokenData tempTokenData; bool error = false; int id = 0; foreach (TokenData tokenref in tempElemento.tokenDataRef) { error = false; tempTokenData = tokenref.tokenDataRef; //Mientras no se llege al final while (tempTokenData != null) { if (tempTokenData.tokenInfo.id == 53) { tempTokenData.tokenInfo = ValoresGlobales.valores().tablaDeSimbolos.ObtenerToken(tempTokenData.codigo); } switch (tempTokenData.tokenInfo.id) { case 53: //Identificador //Se verifica el tipo de dato para ver si coincide o no Error errorIdentificador = new Error(); errorIdentificador.ErrorCustom("La variable : '" + tempTokenData.codigo + "' No se ha declarado", "Semantico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(errorIdentificador); error = true; break; case 55: //Numero if (!VerificarID(ref id, 59)) { Error error1 = new Error(); error1.ErrorCustom("Los tipos de datos no coinciden en" + tempElemento.tipo.ToString(), "Semantico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error1); error = true; } break; case 58: //Cadena if (!VerificarID(ref id, 60)) { Error error1 = new Error(); error1.ErrorCustom("Los tipos de datos no coinciden en" + tempElemento.tipo.ToString(), "Semantico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error1); error = true; } break; case 59: //Variable Numerica if (!VerificarID(ref id, 59)) { Error error1 = new Error(); error1.ErrorCustom("Los tipos de datos no coinciden en" + tempElemento.tipo.ToString(), "Semantico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error1); error = true; } break; case 60: //Variable cadena if (!VerificarID(ref id, 60)) { Error error1 = new Error(); error1.ErrorCustom("Los tipos de datos no coinciden en" + tempElemento.tipo.ToString(), "Semantico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error1); error = true; } break; } tempTokenData = tempTokenData.tokenDataRef; } if (!error) { if (tokenref.codigo != null) { //Se asigna el valor a la variable segun los parametros asignados ValoresGlobales.valores().tablaDeSimbolos.CambiarTipo(tokenref.codigo, id); tokenref.tokenInfo = ValoresGlobales.valores().tablaDeSimbolos.ObtenerToken(tokenref.codigo); id = 0; //Se restablece el id utilizado para la verificacion anteriror } else { Error error1 = new Error(); error1.ErrorCustom("Los tipos de datos no coinciden en" + tempElemento.tipo.ToString(), "Semantico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error1); id = 0; //Se restablece el id utilizado para la verificacion anteriror error = true; } } } }
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"); }
}//Fin SintaxisExpresion private TokenData SintaxisExpresionIf() { TokenData raizReturn = null; TokenData tempReturn = null; Stack <int> obligatorio = new Stack <int>(); List <int> opcional = new List <int>(); //Valores opcionales iniciales opcional.Add(23); opcional.Add(53); opcional.Add(55); opcional.Add(30); //Se obtiene el primer token if (!analizadorLexico.ObtenerToken() || analizadorLexico.returnToken == null) { Error error = new Error(); error.ErrorCustom("No se han obtendido la gramatica esperada 'EXP COMPARADOR EXP' en el elemento" + tempElemento.tipo.ToString(), "Sintactico", tempElemento); } else { do { switch (analizadorLexico.returnToken.tokenInfo.id) { case 23: // ( //Se colocan los valores opcionales a continuacion opcional.Clear(); opcional.Add(23); opcional.Add(53); opcional.Add(55); opcional.Add(30); AgregarTokenData(ref raizReturn, ref tempReturn); //Se colocan los datos obligatorios dentro del stack if (obligatorio.Count > 0) { if (obligatorio.Peek() == 55) { obligatorio.Pop(); } if (obligatorio.Peek() == 53) { obligatorio.Pop(); } } obligatorio.Push(24); break; case 24: // ) AgregarTokenData(ref raizReturn, ref tempReturn); if (obligatorio.Count > 0) { if (obligatorio.Peek() != 24) { ValoresGlobales.valores().tablaDeErrores.errores.Add(new Error(24, "Sintactico", tempElemento)); } else { obligatorio.Pop(); } } else { Error error = new Error(); error.ErrorCustom("No se espera caracter )", "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.errores.Add(error); } //Datos opcionales opcional.Clear(); opcional.Add(29); opcional.Add(30); opcional.Add(31); opcional.Add(32); break; case 29: // + case 30: // - case 31: // * case 32: // / AgregarTokenData(ref raizReturn, ref tempReturn); //Datos obligatorios obligatorio.Push(53); obligatorio.Push(55); //Datos opcionales opcional.Clear(); opcional.Add(23); opcional.Add(53); opcional.Add(55); break; case 53: //Variables case 55: //Numeros AgregarTokenData(ref raizReturn, ref tempReturn); opcional.Clear(); opcional.Add(29); opcional.Add(30); opcional.Add(31); opcional.Add(32); if (obligatorio.Count > 0) { if (obligatorio.Peek() == 55) { obligatorio.Pop(); } if (obligatorio.Peek() == 53) { obligatorio.Pop(); } } break; case 38: // == case 39: // <= case 40: // >= case 41: // < case 42: // > case 43: // != goto cont; //Se sale del analisis break; default: Error error2 = new Error(); error2.NoSeEsperaba(analizadorLexico.returnToken.tokenInfo.id, "Sintactico", tempElemento); ValoresGlobales.valores().tablaDeErrores.AgregarError(error2); break; } //Mientras existan tokens } while (analizadorLexico.ObtenerToken()); } cont: if (obligatorio.Count > 0) { Error error = new Error(); error.ErrorCustom("Expresion ingresada incorrecta dentro del elemento" + tempElemento.tipo.ToString(), "Sintactico", tempElemento); } return(raizReturn); }//Fin de SintaxisExpresionIf()