/// <summary> /// Determina si la gramatica es de tipo 3 (Regular). /// </summary> /// <param name="prod">Produccion a checar</param> /// <returns>True si la producción es gramática regular, de lo contrario false</returns> private Boolean _is_type_3(Produccion prod) { if (prod.LeftItems.Count == 1 && Produccion.IsNoTerminal(prod.LeftItems[0][0])) { if (Produccion.IsTerminal(prod.RightItems[0][0])) { if (prod.RightItems.Count == 2) { if (Produccion.IsNoTerminal(prod.RightItems[1][0])) { return(true); } else { return(false); } } if (prod.RightItems.Count >= 2) { return(false); } else { return(true); } } } return(false); }
private List <string> genera_tokens(string input) { List <string> nueva = new List <string>(); string tok = ""; for (int i = 0; i < input.Length; i++) { if (Produccion.IsNoTerminal(input[i])) { tok += input[i]; if (i < input.Length - 1 && input[i + 1] == '\'') { tok += "'"; i++; } nueva.Insert(0, tok); tok = ""; } else if (Produccion.IsTerminal(input[i])) { nueva.Insert(0, "" + input[i]); } } return(nueva); }
private string get_prod_tabla(Produccion p, string c) { string prod = ""; for (int i = 0; i < p.RightItems.Count; i++) { // si el primero es un terminal, devulve la producción que genera ese terminal if (Produccion.IsTerminal(p.RightItems[i][0])) { if (p.RightItems[i][0] == c[0]) { prod = p.RightItems[i]; break; } } else { string nt = "" + p.RightItems[i][0]; int index = 1; if (p.RightItems[i].Length > 1) { while (index < p.RightItems[i].Length && p.RightItems[i][index++] == '\'') { nt += "'"; } } prod = get_prod_tabla(get_produccion(nt), c); if (prod != "") { prod = p.RightItems[i]; } } } return(prod); }
public Produccion calcula_primero_produccion(Produccion prod) { string prod_str = ""; prod_str = prod.LeftItems[0] + " -> "; foreach (string item in prod.RightItems) { string first = dame_primero_de_item(item); // si el primer elemento del item derecho es terminal, se agrega a la producción if (Produccion.IsTerminal(first[0])) { prod_str += "" + item[0] + "|"; } else // si no busca el primero del no terminal en la lista de primeros. { // recorre la lista de los primeros foreach (Produccion p in _primero) { // Si existe el primero obtenido en la lista, asigna sus elementos a el // primero de este. if (p.LeftItems[0] == first) { foreach (string it in p.RightItems) { prod_str += it + "|"; } break; } } } } return(new Produccion(prod_str)); }
public Produccion calcula_siguiente_produccion(Produccion prod) { string prod_str = ""; string left_str = prod.LeftItems[0] + " -> "; // Obtiene todas las producciones que contienen al no terminal izquierdo // de la produccion a calcular foreach (Produccion p_aux in dame_producciones_no_terminal(prod)) { // Recorre todos los elementos derechos de las producciones // para aplicar las reglas foreach (String it in p_aux.RightItems) { // si la produccion contiene al no terminal a evaluar... string item = it.Replace(prod.LeftItems[0] + "'", ""); if (item.Contains(prod.LeftItems[0])) { if (!item.Contains(prod.LeftItems[0] + "'")) { item = it; // checa la regla que se le aplica para obtener el sigueinte switch (checa_regla_siguiente(item, prod.LeftItems[0])) { case 1: int index = item.IndexOf(prod.LeftItems[0]); if (index < item.Length - 1) { index++; } while (index < item.Length && item[index] == '\'') { index++; } char sig = item[index]; // Si beta es un terminal lo agrega if (Produccion.IsTerminal(sig)) { if (!prod_str.Contains(sig)) { prod_str += "" + sig + "|"; } } else { // si beta es un no terminal obtiene el no terminal string nt = "" + item[index++]; while (index < item.Length && item[index++] == '\'') { nt += "'"; } // agrega los primeros del terminal obtenido a los // siguientes de la produccion actual foreach (String s in get_primeros(nt)) { // si el elemento no está en la lista y es difete de epsilon... if (s != "\u03B5" && !prod_str.Contains(s)) { prod_str += "" + s + "|"; } } if (get_primeros(nt).Contains("\u03B5")) { if (p_aux.LeftItems[0] != prod.LeftItems[0]) { foreach (String s in get_siguientes(p_aux.LeftItems[0])) { if (!prod_str.Contains(s)) { prod_str += "" + s + "|"; } } } } } break; case 2: if (p_aux.LeftItems[0] != prod.LeftItems[0]) { foreach (String s in get_siguientes(p_aux.LeftItems[0])) { if (!prod_str.Contains(s)) { prod_str += "" + s + "|"; } } } break; case 3: break; default: break; } } } } } if (is_inicial) { is_inicial = false; prod_str += "$"; } return(new Produccion(left_str + prod_str)); }
private int evalua_cadena(Gramatica g, string entrada) { Stack <string> pila = new Stack <string>(); int line_number = 0; entrada += "$"; pila.Push("$"); pila.Push(g.Producciones[0].LeftItems[0]); tb_pila_in.Text = "" + line_number + ": " + entrada + "\r\n"; tb_pila_ev.Text = "" + line_number + ": " + "$" + g.Producciones[0].LeftItems[0] + "\r\n"; line_number++; while (entrada.Length != 0 && pila.Count != 0) { string tope = pila.Pop(); // si el elemento de la pila es terminal if (Produccion.IsTerminal(tope[0])) { // Si el elemento del tope es igual al de la entrada, continua // con el siguiente. if (tope == "$" && tope == "" + entrada[0]) { return(1); } if (tope[0] == entrada[0]) { entrada = entrada.Remove(0, 1); } else if (tope != "\u03B5") { return(0); } } else // si el tope es un no terminal { string element = busca_tabla_analisis(tope, "" + entrada[0]); if (element != "") { List <string> invertidos = genera_tokens(element); foreach (string s in invertidos) { pila.Push(s); } } else { return(0); } } // Guarda los datos de la iteración para mostrar la pila de evaluación string aux = ""; foreach (string s in pila) { aux = aux + s; } tb_pila_ev.Text += "" + line_number + ": " + aux + "\r\n"; tb_pila_in.Text += "" + line_number + ": " + entrada + "\r\n"; line_number++; } return(0); }