public void TableConstructor(String fileName, String path, Automata.Automata afd) { try { // Determine whether the directory exists. if (!Directory.Exists(path + "\\" + "Transitions Table")) { // Try to create the directory. DirectoryInfo di = Directory.CreateDirectory(path + "\\" + "Transitions Table"); } String pngPath = path + "\\" + "Transitions Table"; System.IO.File.WriteAllText(path + "\\" + "TableTransition.dot", GetCodeGraphviz(afd, fileName)); var command = "dot -Tpng \"" + path + "\\" + "TableTransition.dot\" -o \"" + pngPath + "\\" + fileName + "Table.png\" "; var procStarInfo = new ProcessStartInfo("cmd", "/C" + command); var proc = new System.Diagnostics.Process(); proc.StartInfo = procStarInfo; proc.Start(); proc.WaitForExit(); } catch (Exception) { MessageBox.Show("Error al escribir el archivo aux_grafico.dot", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public void generarDOT(String nombreArchivo, String pngname, Automata.Automata automataFinito) { String texto = "digraph automata_finito {\n"; texto += "\trankdir=LR;" + "\n"; texto += "\tgraph [label=\"" + nombreArchivo + "\", labelloc=t, fontsize=20]; \n"; texto += "\tnode [shape=doublecircle, style = filled];"; //listar estados de aceptación for (int i = 0; i < automataFinito.Aceptacion.Count; i++) { texto += " " + automataFinito.Aceptacion[i]; } // texto += ";" + "\n"; texto += "\tnode [shape=circle];" + "\n"; texto += "\n" + " edge [color=black];"+ "\n"; texto += "\tsecret_node [style=invis];\n" + " secret_node -> "+ automataFinito.Inicio + " [label=\"inicio\"];" + "\n"; //transiciones for (int i = 0; i < automataFinito.Estados.Count; i++) { ArrayList t = (automataFinito.Estados[i]).Transiciones; for (int j = 0; j < t.Count; j++) { texto += "\t" + ((Transicion)t[j]).DOT_String() + "\n"; } } texto += "}"; System.IO.File.WriteAllText(nombreArchivo + ".dot", texto); //Application.StartupPath String path = Application.StartupPath; try { // Determine whether the directory exists. if (!Directory.Exists(path + "\\" + nombreArchivo)) { // Try to create the directory. DirectoryInfo di = Directory.CreateDirectory(path + "\\" + nombreArchivo); } String pngPath = path + "\\" + nombreArchivo; var command = "dot -Tpng \"" + path + "\\" + nombreArchivo + ".dot\" -o \"" + pngPath + "\\" + nombreArchivo + " " + pngname + ".png\" "; //Console.WriteLine(command); var procStarInfo = new ProcessStartInfo("cmd", "/C" + command); var proc = new System.Diagnostics.Process(); proc.StartInfo = procStarInfo; proc.Start(); proc.WaitForExit(); } catch (Exception e) { } }
public String GetCodeGraphviz(Automata.Automata afd, String nombre) { Automata.Automata temp = afd; String texto = ""; List <String> lista = new List <String>(); List <int> estados = new List <int>(); foreach (var item in temp.Estados) { foreach (Transicion o in item.Transiciones) { //Token t = new Token(0, o.Simbolo, o.Simbolo, 0,0); if (!lista.Contains(o.Simbolo)) { lista.Add(o.Simbolo); } int start = o.Inicio.IdEstado; int end = o.Fin.IdEstado; if (!estados.Contains(start)) { estados.Add(start); } if (!estados.Contains(end)) { estados.Add(end); } } } string[,] matriz = new string[estados.Count() + 1, lista.Count() + 1]; for (int i = 0; i < lista.Count(); i++) { matriz[0, i + 1] = lista[i]; } estados.Sort(); for (int i = 0; i < estados.Count(); i++) { matriz[i + 1, 0] = estados[i].ToString(); } int indexState = 0; int indexTerminal = 0; foreach (var item in afd.Estados) { foreach (Transicion transicion in item.Transiciones) { int a = transicion.Inicio.IdEstado; string b = transicion.Simbolo; indexState = estados.FindIndex(e => e == a); indexTerminal = lista.FindIndex(e => e == b); String end = transicion.Fin.IdEstado.ToString(); /**/ foreach (var i in temp.Aceptacion) { if (i.IdEstado == transicion.Fin.IdEstado) { end = end + "#"; } } matriz[indexState + 1, indexTerminal + 1] = end; } } for (int i = 0; i < matriz.GetLength(0); i++) { texto = texto + "\n<TR>\n"; for (int j = 0; j < matriz.GetLength(1); j++) { if (matriz[i, j] == null) { texto = texto + "\t<TD width=\"75\">-</TD>\n"; } else { texto = texto + "\t<TD width=\"75\">" + matriz[i, j].Replace('"', ' ') + "</TD>\n"; } } texto = texto + "</TR>\n"; } return("digraph G {\n" + "\n\tgraph [rankdir=LR, label=\"Transition Table " + nombre + "\", labelloc=t, fontsize=30, pad=0.5, nodesep=0.5, ranksep=2];\n" + "\n\tnode[shape=none];\n" + "\n\ttable[label =<\n <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\"> " + texto + "\n</TABLE>>];\n}"); }
public Boolean EvaluateExpression(String regex, Automata.Automata automata, ArrayList ar, bool isString) { Estado inicial = automata.Inicio; List <Estado> estados = automata.Estados; List <Estado> aceptacion = new List <Estado>(automata.Aceptacion); HashSet <Estado> conjunto = eClosure(inicial); if (isString) { foreach (String ch in ar) { //Move in sets es un metodo para moverme entre conjuntos simbolo = ch; conjunto = moveInSet(conjunto, ch); if (conjunto.Count == 0) { simbolo = ch.ToString(); EvaluatorController.Instance.getError(ch, 0); break; } HashSet <Estado> temp = new HashSet <Estado>(); IEnumerator <Estado> iter = conjunto.GetEnumerator(); //Estado aux = iter.Current; while (iter.MoveNext()) { Estado siguiente = iter.Current; //aux = iter.MoveNext(); /** * En esta parte es muy importante el metodo addAll * porque se tiene que agregar el eClosure de todo el conjunto * resultante del move y se utiliza un hashSet temporal porque * no se permite la mutacion mientras se itera */ temp.UnionWith(eClosure(siguiente)); } conjunto = temp; } } else { for (int i = 0; i < regex.Length; i++) { //Move in sets es un metodo para moverme entre conjuntos Char ch = regex[i]; conjunto = moveInSet(conjunto, ch.ToString()); if (conjunto.Count == 0) { simbolo = ch.ToString(); EvaluatorController.Instance.getError(ch.ToString(), i); break; } HashSet <Estado> temp = new HashSet <Estado>(); IEnumerator <Estado> iter = conjunto.GetEnumerator(); //Estado aux = iter.Current; while (iter.MoveNext()) { Estado siguiente = iter.Current; //aux = iter.MoveNext(); /** * En esta parte es muy importante el metodo addAll * porque se tiene que agregar el eClosure de todo el conjunto * resultante del move y se utiliza un hashSet temporal porque * no se permite la mutacion mientras se itera */ temp.UnionWith(eClosure(siguiente)); } conjunto = temp; } } bool response = false; foreach (Estado aceptation_State in aceptacion) { if (conjunto.Contains(aceptation_State)) { response = true; } } if (response) { return(true); } else { error = "No Existe transicion con " + simbolo + " o el ultimo simbolo no llego a un estado aceptador"; simbolo = ""; return(false); } }
/// <summary> /// Metodos de evaluacion /// </summary> /// <param name="expressionName"></param> /// <param name="strToEvaluate"></param> /// <returns></returns> //Evaluacion de caracteres, verifica que todos los caracretes coincidan public bool SimulateExpression(string expressionName, string strToEvaluate) { clearTokens(); if (strToEvaluate.Contains("\\n")) { strToEvaluate.Replace("\\n", ('\n').ToString()); } if (strToEvaluate.Contains("\\r")) { strToEvaluate.Replace("\\r", ('\n').ToString()); } if (strToEvaluate.Contains("\\t")) { strToEvaluate.Replace("\\t", ('\t').ToString()); } //Se crea un array que tendra el alfabeto modificado ArrayList new_alphabet = new ArrayList(); bool validate = false; //Itera en los automatas guardados foreach (Evaluator item in arrayAutomatas) { //Busca el automata cuyo nombre coincida con el recivido por el metodo if (item.ExpressionName.Equals(expressionName)) { Automata.Automata afd_temp = item.Afd; //Varibale para definir que tipo de alfabeto tiene el automata //es decir: si tiene solo simbolos, conjuntos, cadenas, o mezcla entre ellas int swcase = 0; //Se itera en el afabeto; foreach (var alphabet in afd_temp.Alfabeto) { //Quita las comillas y los espacios; String alphabetChar = alphabet.Trim('"'); //Intenta convertir el alfabeto a char Char value; bool result; result = Char.TryParse(alphabetChar, out value); if (result && (SetController.Instance.GetElemntsOfSet(alphabetChar) == null)) { if (result || alphabetChar.Equals("\\n") || alphabetChar.Equals("\\t") || alphabetChar.Equals("\\r") || alphabetChar.Equals("\"") || alphabetChar.Equals("\'")) { if (alphabetChar.Equals("\\n")) { new_alphabet.Add(('\n').ToString());; } else if (alphabetChar.Equals("\\t")) { new_alphabet.Add(('\t').ToString());; } else if (alphabetChar.Equals("\\r")) { new_alphabet.Add(('\r').ToString());; } else { new_alphabet.Add(alphabetChar); } //Si logra converit a char o si es un caracter especial, significa que solo es un simbolo //y lo agrega al nuevo alfabeto } } else { //Si no logra convertir, significa que lo que vino fue una cadena o un conjunto //Se busca los elementos del conjunto ArrayList listChar = SetController.Instance.GetElemntsOfSet(alphabetChar); //Verifica que la lista no venga vacia if (listChar != null) { //se itera sobre los elementos del conjuntos foreach (var letter in listChar) { String letter_temp = letter.ToString().Trim('"'); //Se agregan los elemenentos al alfabeto if (!new_alphabet.Contains(letter_temp)) { new_alphabet.Add(letter_temp.ToString()); } } } //Si la lista vienen vacia es por que vino una cadena else if (listChar == null) { //la cadena se agrega directamente new_alphabet.Add(alphabetChar); swcase = 1; } else { //Si no coincide con ninguno, el elemento no se encuentra dentro del alfabeto y marca error error = "El conjunto '" + alphabetChar + "' no ha sido declarado. No se puede evaluar: " + strToEvaluate + ".\n"; return(false); } } } //Casos de desicion //Caso 0: el alfabeto solo tiene simbolos, solo conjuntos o mezcla entre los dos. //Caso 1; el alfabeto tiene solo cadenas o mezcla entre los demas //Se itera sobre la cadena de entrada //Quita las comillas y los espacios; String str_temp = strToEvaluate.Trim('"'); //Variable 'booleana' sirve para determinar si continuar evaluando o no; int countAux = 1; Char ch = ' '; for (int i = 0; i < str_temp.Length; i++) { //Verifica que todos los elementos esten dentro del alfabeto ch = str_temp[i]; if (!new_alphabet.Contains(ch.ToString())) { //sirve para ver si las cadenas contienen el elemnto int contadorInterno = 0; foreach (string str in new_alphabet) { if (str.Length > 1) { if (str.Contains(ch.ToString())) { contadorInterno = 1; break; } } } if (contadorInterno != 1) { countAux = 0; //Si algun elemento no se encuentra del alfabeto lo guarda en un array de errores Token t = new Token(0, str_temp[i].ToString(), "Carcter_" + str_temp[i].ToString(), i, 0); arrayErroresEvaluados.Add(t); break; } } } //Uno o mas caracteres no se encuentran dentro del alfabeto del automata if (countAux == 0) { error = "X Error en " + strToEvaluate + ". El caracter " + ch + ", no se encuentra dentro del alfabeto\n"; return(false); } switch (swcase) { //Cuando solo vienen simbolos o conjuntos case 0: //Se envia a evaluar la expresion validate = ThompsonControlador.Instance.EvaluateExpression(str_temp, afd_temp, null, false); break; //Cuando vienen cadenas; case 1: //Array que va a guardar unicamente las cadenas ArrayList cadenas = new ArrayList(); ArrayList cadenas2 = new ArrayList(); ArrayList cabezas = new ArrayList(); //Esta variable va a ser un contador de letras String iteradorCadena = ""; int cont = 0; foreach (String i in new_alphabet) { if (i.Length > 1) { if (i.Contains("\\n")) { cadenas.Add(i.Replace("\\n", ('\n').ToString())); } if (i.Contains("\\r")) { cadenas.Add(i.Replace("\\r", ('\n').ToString())); } if (i.Contains("\\t")) { cadenas.Add(i.Replace("\\t", ('\t').ToString())); } else { cadenas.Add(i); } cabezas.Add(i[0].ToString()); } } for (int i = 0; i < str_temp.Length; i++) { char a = str_temp[i]; if (cabezas.Contains(a.ToString())) { int contInterno = 0; for (int j = i; j < str_temp.Length; j++) { iteradorCadena = iteradorCadena + str_temp[j]; if (cadenas.Contains(iteradorCadena)) { i = j; contInterno = 1; break; } } if (contInterno != 0) { cadenas2.Add(iteradorCadena); iteradorCadena = ""; } else { cadenas2.Add(str_temp[i].ToString()); } } else { cadenas2.Add(str_temp[i].ToString()); } iteradorCadena = ""; } validate = ThompsonControlador.Instance.EvaluateExpression(str_temp, afd_temp, cadenas2, true); break; default: break; } //si la validacion fue exitosa significa que la cadena fue valida if (validate) { //Se agregan los tokens evaluados a la lista que se va a imprimir for (int i = 0; i < str_temp.Length; i++) { Token t = new Token(0, str_temp[i].ToString(), "Carcter_" + str_temp[i].ToString(), i, 0); arrayTokensEvaluados.Add(t); } } else { error = "X " + ThompsonControlador.Instance.getError() + "\n"; for (int i = 0; i < str_temp.Length; i++) { Token t = new Token(0, str_temp[i].ToString(), "Carcter_" + str_temp[i].ToString(), i, 0); arrayErroresEvaluados.Add(t); } } break; } } return(validate); }
//Insert public void Insert(string name, Automata.Automata afd) { Evaluator e = new Evaluator(name, afd); arrayAutomatas.Add(e); }
public void Insert(String name, ArrayList ar, String path) { ArrayList vuelta = new ArrayList(); // array que va a almacenar los elementos en orden inverso for (int i = ar.Count - 1; i >= 0; i--) { vuelta.Add(ar[i]); NodeController.getInstancia().InsertStack(ar[i].ToString()); } String ast = ""; foreach (var item in vuelta) { ast = ast + " " + item; } Console.WriteLine(ast); RegularExpression re = new RegularExpression(name, vuelta); arrayListER.Add(re); NodeController.getInstancia().Print(name, path); //Convierte la expresion regular de prefija a pos ArrayList regularExpresion = NodeController.getInstancia().ConvertExpression(NodeController.getInstancia().getRoot()); ArrayList regex = new ArrayList(); try { regex = RegexController.Instance.infixToPostfix(regularExpresion); } catch (Exception a) { Console.WriteLine("Expresión mal ingresada"); } string st = ""; foreach (var item in regularExpresion) { st = st + item; } Console.WriteLine(name + "->" + st); //CONSTRUYE EL AUTOMATA ANF AFN aFN = new AFN(); aFN.construirAutomata(regex); Automata.Automata afn_result = aFN.Afn; ThompsonControlador.Instance.generarDOT("AFN", name, afn_result); InsertAutomataAFNName("AFN " + name); //CONSTRUYE EL AUTOMATA AFD AFD AFD = new AFD(); AFD.conversionAFN(afn_result); Automata.Automata afd_result = AFD.Afd; //CONSTRUYE EL AUTOMATA SIN ESTADO STRAMPA Automata.Automata afd_trampa = AFD.RemoveCheatStates(afd_result); ThompsonControlador.Instance.generarDOT("AFD", name, afd_trampa); InsertAutomataAFDName("AFD " + name); //CONSTRUYE LA TABLA ThompsonControlador.Instance.TableConstructor(name, path, afd_trampa); InsertTablaName(name + "Table"); //ENVIA EL AUTOMATA A SER GUARDADO PARA POSTERIOR EVALUACION EvaluatorController.Instance.Insert(name, afd_trampa); NodeController.getInstancia().clearList(); }
public Evaluator(string n, Automata.Automata a) { this.expressionName = n; this.afd = a; }