public void Validacion_ER(string id) { Parea(Token.Tipo.S_DOS_PUNTOS); string lexema = tokenActual.GetValor(); lexema = lexema.Remove(0, 1); lexema = lexema.Remove(lexema.Length - 1, 1); int filaInicio = tokenActual.GetFila(); int columnaInicio = tokenActual.GetColumna() + 1; Parea(Token.Tipo.CADENA); Parea(Token.Tipo.S_PUNTO_Y_COMA); //Aqui continua la validacion del lexema. consola += "**Evaluando Expresion Regular: " + id + "**\n"; try { Simbolo simbolo = tablaSimbolos[id]; //Posible Exception. if (!simbolo.GetTipo().Equals("Estado")) { throw new KeyNotFoundException(); //Como no es compatible el tipo entonces no se puede trabajar con él. Se manda Exception. } Cerradura estado = (Cerradura)simbolo.GetValor(); int contador = 0; if (estado.Validar(lexema, ref contador, ref filaInicio, ref columnaInicio, ref ListaTokensAnalizados)) { consola += "El lexema: \"" + lexema + "\", es válido para la Expresion Regular: " + id + "\n"; } else { consola += "El lexema: \"" + lexema + "\", no es válido para la Expresion Regular: " + id + "\n"; } } catch (KeyNotFoundException) { consola += "No se pudo validar el lexema: " + lexema + ", no se encontró su expresión regular\n**Fin evaluacion**\n"; } }
/** * Declaracion_CONJ espera una declaracion para un conjunto nuevo. * Por ello se recupera el valor del token ID y el valor de los elementos en una lista para luego incluirlos en la tabla de simbolos como una nueva variable. */ public void Declaracion_CONJ() { Parea(Token.Tipo.PR_CONJ); Parea(Token.Tipo.S_DOS_PUNTOS); string id = tokenActual.GetValor(); Parea(Token.Tipo.ID); Parea(Token.Tipo.S_FLECHA); LinkedList <string> elementos = new LinkedList <string>(); try { Token primero = tokenActual; elementos.AddLast(Elemento()); //Se envia parametro de la lista elementos por referencia al metodo Rango(). Rango(primero, ref elementos); } catch (ArgumentNullException) { //Error sintactico. Se maneja dentro de Elemento() y Rango(elementos) } Parea(Token.Tipo.S_PUNTO_Y_COMA); //Se crea un nuevo objeto conjunto Conjunto conjunto = new Conjunto(id, elementos); //Se vincula el objeto conjunto a un objeto simbolo que se agrega a la tablaSimbolos Simbolo simbolo = new Simbolo(id, "Conjunto", conjunto); //Es agregado el nuevo simbolo con su 'key' que es utilizado para evitar variables con el mismo nombre try { tablaSimbolos.Add(id, simbolo); } catch (ArgumentException) { Console.WriteLine("Ya existe un objeto con ID = " + id); } }
/* Estructura_P: * */ public Estructura Estructura_P(ref LinkedList <Terminal> terminals) { if (Comparador(Token.Tipo.S_LLAVE_IZQ)) { Parea(Token.Tipo.S_LLAVE_IZQ); Terminal id = new Terminal(Terminal.Tipo.ID, tokenActual.GetValor()); bool existe = this.ComprobarExistenciaEnLista(terminals, id); if (!existe) { try { //Revisa en la tabla de simbolos si existe un conjunto con el id solicitado y añade los elementos del conjunto a su lista de valores. Simbolo simbolo = tablaSimbolos[tokenActual.GetValor()]; Conjunto conjunto = (Conjunto)simbolo.GetValor(); id.ListaValores = new LinkedList <string>(conjunto.GetElementos()); terminals.AddLast(id); consola += "*Elementos para conjunto " + id.GetRepresentacion() + ":"; foreach (string elemento in id.ListaValores) { consola += "-" + elemento; } consola += "-*\n"; } catch (KeyNotFoundException) { //No se pudo obtener el conjunto de la tabla de simbolos, asi que no se guarda el Terminal en la lista de Terminales para la validacion. } } Parea(Token.Tipo.ID); Parea(Token.Tipo.S_LLAVE_DER); return(id); } else if (Comparador(Token.Tipo.CADENA)) { Terminal cadena = new Terminal(Terminal.Tipo.CADENA, tokenActual.GetValor()); bool existe = this.ComprobarExistenciaEnLista(terminals, cadena); if (!existe) { terminals.AddLast(cadena); } Parea(Token.Tipo.CADENA); return(cadena); } else if (Comparador(Token.Tipo.CARACTER_ESPECIAL)) { Terminal c_especial = new Terminal(Terminal.Tipo.CARACTER_ESPECIAL, tokenActual.GetValor()); bool existe = this.ComprobarExistenciaEnLista(terminals, c_especial); if (!existe) { terminals.AddLast(c_especial); } Parea(Token.Tipo.CARACTER_ESPECIAL); return(c_especial); } else if (Comparador(Token.Tipo.C_TODO)) { Terminal c_todo = new Terminal(Terminal.Tipo.C_TODO, tokenActual.GetValor()); bool existe = this.ComprobarExistenciaEnLista(terminals, c_todo); if (!existe) { terminals.AddLast(c_todo); } Parea(Token.Tipo.C_TODO); return(c_todo); } else if (Comparador(Token.Tipo.S_PUNTO) || Comparador(Token.Tipo.S_PLECA) || Comparador(Token.Tipo.S_INTERROGACION) || Comparador(Token.Tipo.S_ASTERISCO) || Comparador(Token.Tipo.S_SUMA)) { return(Estructura(ref terminals)); } else { Console.WriteLine("Error Sintactico\nEn ID_Token: " + controlToken + "\nSe esperaba [S_LLAVE_IZQ|CADENA|CARACTER_ESPECIAL|C_TODO|S_PUNTO|S_PLECA|S_INTERROGACION|S_ASTERISCO|S_SUMA] en lugar de [" + tokenActual.GetTipo() + ", " + tokenActual.GetValor() + "]"); consola += "*Error Sintactico*\nEn ID_Token: " + controlToken + "\nSe esperaba [S_LLAVE_IZQ|CADENA|CARACTER_ESPECIAL|C_TODO|S_PUNTO|S_PLECA|S_INTERROGACION|S_ASTERISCO|S_SUMA] en lugar de [" + tokenActual.GetTipo() + ", " + tokenActual.GetValor() + "]\n"; errorSintactico = true; existenciaErrorSintactico = true; return(null); } }
/* Declaracion_ER: Guarda en la tabla de simbolos un objeto de tipo Estructura. */ public void Declaracion_ER(string id) { Parea(Token.Tipo.S_FLECHA); try { //Se crea una ListaTerminales que se va llenando conforme se encuentra un terminal en Estructura_P. //Se crea una ListaTerminales que contiene las transiciones con el valor real para que se pueda alcanzar cierto estado. LinkedList <Terminal> ListaTerminales = new LinkedList <Terminal>(); //Se crea un ListaNodos que se va llenando conforme se realiza el AFN. LinkedList <Nodo> ListaNodos = new LinkedList <Nodo>(); //Se crea un nuevo objeto estructura. Estructura estructura = Estructura(ref ListaTerminales); Parea(Token.Tipo.S_PUNTO_Y_COMA); /***************************************************** AFN *****************************************************/ int n = 0; //Creacion de nodos y sus transiciones. estructura.Numerar(ref ListaNodos, ref n); //Creacion de grafica. String CadenaGraphviz = "digraph AFN{\n" + "\trankdir=LR;\n" + "\tGraph[label = \"AFN: " + id + "\"];\n" + "\tnode [shape = circle, fontsize = 10; style = filled fillcolor=gray, color = black, fontcolor = black];\n" + "\tI [fontsize = 1; style = filled fillcolor=white, fontcolor = white, color = white];\n" + "\tI->n" + estructura.GetFirst().Numero + "[label = Io];\n"; //Graficar nodos. Nodo First = estructura.GetFirst(); First.Graficar(ref CadenaGraphviz); CadenaGraphviz += "\tn" + estructura.GetLast().Numero + "[shape = doublecircle];\n" + "}"; Graficador graficadorAFN = new Graficador("AFN_" + id); //Creacion de archivos. RutasImagenes.AddLast(graficadorAFN.graficar(CadenaGraphviz)); /***************************************************** AFD *****************************************************/ int contadorCerraduras = 0; //A LinkedList <Nodo> c0 = new LinkedList <Nodo>(First.ObtenerCerraduras().OrderBy(nodo => nodo.Numero)); Cerradura Cerradura0 = new Cerradura(c0); Cerradura0.Estado = "n" + contadorCerraduras++; LinkedList <Cerradura> Cerraduras = new LinkedList <Cerradura>(); Cerraduras.AddLast(Cerradura0); bool nuevaEntrada; //Creacion de Estados y sus transiciones. do { nuevaEntrada = false; //Dictionary<string, Cerradura> auxiliar = new Dictionary<string, Cerradura>(Cerraduras); LinkedList <Cerradura> auxiliar = new LinkedList <Cerradura>(Cerraduras); foreach (Cerradura cerradura in Cerraduras) { if (!cerradura.Evaluado) { //a (terminal con el que se trabaja Mover). foreach (Terminal terminal in ListaTerminales) { //M(A,a) (mover). LinkedList <Nodo> Mover = new LinkedList <Nodo>(); foreach (Nodo elementoCerradura in cerradura.Elementos) { elementoCerradura.ObtenerMover(ref Mover, terminal.GetRepresentacion()); } if (Mover.Count != 0) { //C(M(A,a)) (cerradura del mover) LinkedList <Nodo> cm = new LinkedList <Nodo>(); foreach (Nodo elementoMover in Mover) { cm = new LinkedList <Nodo>(cm.Union(elementoMover.ObtenerCerraduras())); } cm = new LinkedList <Nodo>(cm.OrderBy(nodo => nodo.Numero)); bool existe = false; //Recorre el diccionario revisando si ya existe un estado igual para agregar la nueva transición. int tamano = cm.Count; foreach (Cerradura estado in auxiliar) { bool iguales = false; if (estado.Elementos.Count == cm.Count) { iguales = true; for (int i = 0; i < tamano; i++) { if (estado.Elementos.ElementAt(i).Numero != cm.ElementAt(i).Numero) { existe = false; iguales = false; break; } } if (iguales) { TransicionC transicion = new TransicionC(terminal, estado); cerradura.ListaTransiciones.AddLast(transicion); existe = true; break; } } } //Si no existe ese estado, se crea y se agrega a la lista de cerraduras auxiliar. if (!existe) { Cerradura CerraduraMover = new Cerradura(cm); CerraduraMover.Estado = "n" + contadorCerraduras++; auxiliar.AddLast(CerraduraMover); TransicionC transicion = new TransicionC(terminal, CerraduraMover); cerradura.ListaTransiciones.AddLast(transicion); nuevaEntrada = true; } } } cerradura.Evaluado = true; } } Cerraduras = auxiliar; } while (nuevaEntrada); CadenaGraphviz = "digraph AFD{\n" + "\trankdir=LR;\n" + "\tGraph[label = \"AFD: " + id + "\" fontcolor = dodgerblue4];\n" + "\tnode [shape = circle, fontsize = 10; colorscheme = pubu9, style = filled, fillcolor = 5, color = 6, fontcolor = 1];\n" + "\tI [fontsize = 1; style = filled fillcolor=white, fontcolor = white, color = white];\n" + "\tI->n0[label = Io, colorscheme = pubu9, color = 9, fontcolor = 9];\n"; //Tablas String ruta = Path.GetDirectoryName(Application.ExecutablePath); string carpeta = ruta + "\\Tablas"; if (!Directory.Exists(carpeta)) { Directory.CreateDirectory(carpeta); } ruta = carpeta; ruta += "\\Transiciones_" + id + ".pdf"; Document document = new Document(PageSize.LETTER, 10, 10, 10, 10); PdfWriter pw = PdfWriter.GetInstance(document, new FileStream(ruta, FileMode.Create)); document.Open(); Paragraph encabezado = new Paragraph("Tabla de transiciones de \"" + id + "\""); encabezado.Alignment = Element.ALIGN_CENTER; document.Add(encabezado); PdfPTable tabla = new PdfPTable(ListaTerminales.Count + 1); tabla.AddCell(""); foreach (Terminal terminal in ListaTerminales) { tabla.AddCell(terminal.GetRepresentacion()); } foreach (Cerradura estado in Cerraduras) { string nombreCelda = estado.Estado; if (estado.Elementos.Contains(estructura.GetLast())) { estado.Aceptacion = true; nombreCelda += "*"; } estado.Graficar(ref CadenaGraphviz); tabla.AddCell(nombreCelda); estado.Tablear(ref tabla, ListaTerminales); } CadenaGraphviz += "}"; document.Add(tabla); document.Close(); MessageBox.Show("Se ha creado un archivo mostrando la tabla de transiciones de " + id + " en:\n" + ruta + "\n"); Graficador graficadorAFD = new Graficador("AFD_" + id); //Creacion de archivos. RutasImagenes.AddLast(graficadorAFD.graficar(CadenaGraphviz)); //Se vincula el objeto Cerradura a un objeto simbolo que se agrega a la tablaSimbolos. Simbolo simbolo = new Simbolo(id, "Estado", Cerraduras.ElementAt(0)); //Es agregado el nuevo simbolo con su 'key' que es utilizado para evitar variables con el mismo nombre. try { tablaSimbolos.Add(id, simbolo); } catch (ArgumentException) { Console.WriteLine("Ya existe un objeto con ID = " + id); } } catch (NullReferenceException) { //Error sintactico. Manejado en Estructura. } }