private Boolean _is_valid_prod; // Variable para guardar si es una producción válida. /// <summary> /// Constructor de la clase Produccion. /// </summary> /// <param name="str_prod">Cadena que represeta una producción.</param> public Produccion(string str_prod) { _prod_str = str_prod; _right_items = new List <string>(); _left_items = new List <string>(); _is_valid_prod = true; _error = PROD_ERROR.NO_ERROR; _analize_production(); }
/// <summary> /// Analiza la cadena que representa la producción. /// Separa la parte izquieda y derecha de la producción, y de ser válida /// determina su tipo. /// </summary> private void _analize_production() { Boolean is_arrow = false; Boolean has_epsilon = false; String[] str_aux; string item = ""; // Elimina espacios. str_aux = _prod_str.Split(' '); _prod_str = ""; foreach (string l in str_aux) { _prod_str += l; } // Elimina tabuladores. str_aux = _prod_str.Split('\t'); _prod_str = ""; foreach (string l in str_aux) { _prod_str += l; } // Si la cadena de producción está vacía... if (_prod_str == "") { _is_valid_prod = false; // Es una producción sin error, pero no válida. return; } else // Si no... { // Recorre todos los caracteres de la cadena de producción. for (int i = 0; i < _prod_str.Length; i++) { // Si encuentra un simbolo flecha '->'... if (_prod_str[i] == '-' && i < _prod_str.Length - 1 && _prod_str[i + 1] == '>') { // Si no tiene flecha... if (!is_arrow) { if (item != "") { _left_items.Add(item); } item = ""; is_arrow = true; // Levanta la bandera de flecha. has_epsilon = false; // Baja la bandera de epsilon. i++; // Avanza al siguiente caracter despues de '>'. } else // Si ya tiene flecha (encontró otra flecha) { _is_valid_prod = false; // La producción es inválida. _error = PROD_ERROR.INVALID_PRODUCTION; // Error de producción inválida. break; // Termina el ciclo. } } else // Si no es simbolo flecha '->'... { // Si el caracter es epsilon y no ha tenido empsilon.. if (_prod_str[i] == _epsilon && !has_epsilon) { has_epsilon = true; // Bandera tiene epsilon a true. // Si no tiene flecha... if (!is_arrow) { //_left_items.Clear(); // Limpia la lista de elementos izquierdos. _left_items.Add("" + _prod_str[i]); // Inserta epsilon en el lado izquierdo. _left_items_str = "" + _prod_str[i]; // Agrega el epsilon a la cadena } else // Si ya tiene flecha // _right_items.Clear(); // Limpia la lista de elementos derechos. { _right_items.Add("" + _prod_str[i]); // Inserta epsilon en el lado derecho. _right_items_str = "" + _prod_str[i]; // Agrega el epsilon a la cadena break; // Termina el ciclo. } } else // Si no.... Si el caracter es un un Terminal o un No Terminal... if (IsTerminal(_prod_str[i]) || IsNoTerminal(_prod_str[i])) { // Si no tiene flecha, guarda el caracter del lado izquierdo de la producción // y si tiene flecha lo guarda del lado derecho. if (!has_epsilon) { if (!is_arrow) { if (_prod_str[i] == '|') { if (item != "") { _left_items.Add(item); } item = ""; } else { item += "" + _prod_str[i]; } _left_items_str += _prod_str[i]; } else { if (_prod_str[i] == '|') { if (item != "") { _right_items.Add(item); } item = ""; } else { item += "" + _prod_str[i]; } _right_items_str += _prod_str[i]; } } } else // Si no, marca un error de caracter invalido. { _is_valid_prod = false; // La producción es inválida. _error = PROD_ERROR.INVALID_CHARACTER; // Error de caracter inválido. break; // Termina el ciclo. } } } } if (item != "") { _right_items.Add(item); } // Si no hay componentes izquierdos o derechos en la producción... error!. if (!is_arrow || _left_items.Count == 0 || _right_items.Count == 0) { _error = PROD_ERROR.INVALID_PRODUCTION; } }