/// <summary> /// Algoritm pentru inlocuirea inceputului comun. /// </summary> /// <param name="regula">Prima regula de forma A->aC.</param> /// <param name="regulaSecundara">A doua regula de forma A->aB</param> /// <returns></returns> private List <RegulaProductie> InlocuireInceputComun(RegulaProductie regula, RegulaProductie regulaSecundara, Tuple <int, int> info) { string prefixNeterminale = "2"; List <RegulaProductie> rezultat = new List <RegulaProductie>(); //Generam neterminalul A*. string neterminalNou = string.Format($"{regula.LeftSide}{prefixNeterminale}"); GramaticaAnalizata.Neterminale.Add(neterminalNou); //Preluam partea comuna. var aData = regula.RightSide.GetRange(0, info.Item2); aData.Add(neterminalNou); //Preluam partea ulterioara partii comune din prima regula. var bData = regula.RightSide.GetRange(info.Item2, regula.RightSide.Count - info.Item2); //Preluam partea ulterioara partii comune din a doua regula. var cData = regulaSecundara.RightSide.GetRange(info.Item2, regulaSecundara.RightSide.Count - info.Item2); //Adaugam regula A->aA*. rezultat.Add(new RegulaProductie { LeftSide = regula.LeftSide, RightSide = new List <string>(aData) }); //Adaugam regula A*->b. rezultat.Add(new RegulaProductie { LeftSide = neterminalNou, RightSide = bData }); //Adaugam regula A*->c. rezultat.Add(new RegulaProductie { LeftSide = neterminalNou, RightSide = cData }); return(rezultat); }
/// <summary> /// Algoritm pentru inlocuirea recursivitatii stanga. /// </summary> /// <param name="regula">Regula de forma A->Aa.</param> /// <param name="regulaSecundara">Regula de forma A->b.</param> /// <param name="neterminaleNoi">Pentru a putea adauga noul neterminal aparut.</param> /// <returns></returns> private List <RegulaProductie> InlocuireRecursivitateStanga(RegulaProductie regula, RegulaProductie regulaSecundara) { string prefixNeterminale = "1"; List <RegulaProductie> rezultat = new List <RegulaProductie>(); //Generam neterminalul A^ string neterminalNou = string.Format($"{regula.LeftSide}{prefixNeterminale}"); GramaticaAnalizata.Neterminale.Add(neterminalNou); //Adaugam regula A->bA^ rezultat.Add(new RegulaProductie { LeftSide = regula.LeftSide, RightSide = regulaSecundara.RightSide }); rezultat.Last().RightSide.Add(neterminalNou); //Adaugam regula A^->aA^ rezultat.Add(new RegulaProductie { LeftSide = neterminalNou, RightSide = regula.RightSide }); rezultat.Last().RightSide.RemoveAt(0); rezultat.Last().RightSide.Add(neterminalNou); //Adaugam regula A^->eps rezultat.Add(new RegulaProductie { LeftSide = neterminalNou, RightSide = new List <string>() }); return(rezultat); }
/// <summary> /// Generarea unei gramatici pe baza input-ului dat. /// </summary> /// <returns></returns> public static Gramatica GenereazaGramaticaFromUI(string simbolStart, string neterminale, string terminale, string reguliProductie) { #region Verificari initiale if (simbolStart == null || neterminale == null || terminale == null || reguliProductie == null) { throw new Exception("Nu s-au introdus datele necesare generarii unei gramatici!"); } #endregion #region Neterminale //Construim lista de neterminale. List <string> neterminaleList = new List <string>(); foreach (var neterminal in neterminale.Split(' ')) { //Daca vreun neterminal contine caractere interzise aruncam o eroare. if (neterminal.Contains("-") || neterminal.Contains("<") || neterminal.Contains(">") || neterminal.Contains(".") || neterminal.Contains("+")) { throw new Exception("Terminalele nu pot contine caractere interzise."); } neterminaleList.Add(neterminal); } //Daca simbolul de start nu apartine acestei liste aruncam o eroare. if (!neterminaleList.Contains(simbolStart)) { throw new Exception("Multimea terminalelor este incorecta sau simbolul de start nu apartine acesteia!"); } #endregion #region Terminale //Construim lista de terminale. List <string> terminaleList = new List <string>(); foreach (var terminal in terminale.Split(' ')) { terminaleList.Add(terminal); } #endregion #region Reguli de productie //Construim lista cu regulile de productie. List <RegulaProductie> reguliProductieList = new List <RegulaProductie>(); foreach (var regula in reguliProductie.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)) { RegulaProductie regulaProductie = new RegulaProductie(); regulaProductie.LeftSide = regula.Split(':')[0]; foreach (var rightSideTerminal in regula.Split(':')[1].Split(' ')) { if (rightSideTerminal != "") { regulaProductie.RightSide.Add(rightSideTerminal); } } reguliProductieList.Add(regulaProductie); } #endregion return(new Gramatica { SimbolStart = simbolStart, Neterminale = neterminaleList, Terminale = terminaleList, ReguliProductie = reguliProductieList }); }