private void InitRegProd(string[] reguliProd)
        {
            ReguliDeProductie x = new ReguliDeProductie();

            x.SetLeft(reguliProd[0]);
            x.InitializeRightPartOfExistingRules(reguliProd);
            _reguliProductie.Add(x);

            Console.WriteLine();
        }
        private void CheckLeftRecv(List <ReguliDeProductie> rList, int index, List <ReguliDeProductie> cReguliProductie, bool[] checkArr)
        {
            for (int i = 0; i < rList.Count; i++)
            {
                int    contor = rList[i].GetRight().Length;
                string first  = rList[i].GetRight().FirstOrDefault();
                if (rList[i].GetLeft() == first)
                {
                    if (rList.Count < 2)
                    {
                        Console.WriteLine("Imposibil de eliminar recursivitatea stanga!");
                        break;
                    }

                    int l_contor = rList[i].GetRight().Length;

                    // Introducem 2 reguli de productie noi
                    ReguliDeProductie newRule1 = new ReguliDeProductie();
                    ReguliDeProductie newRule2 = new ReguliDeProductie();

                    // Ambele reguli de productie vor fi pentru acelasi neterminal
                    newRule1.SetLeft(rList[i].GetLeft().ToString() + 'x');
                    newRule2.SetLeft(rList[i].GetLeft().ToString() + 'x');


                    // Se adauga noul neterminal in lista
                    _neterminale.Add(newRule1.GetLeft());

                    // Initializare prima regula de productie introdusa
                    string[] right_1 = rList[i].GetRight().Reverse().Take(l_contor - 1).Reverse().ToArray();
                    newRule1.SetRight(Helper.Concatenate(right_1, newRule1.GetLeft()));


                    // Initializare a doua regula de productie introdusa
                    string[] right_2 = new string[] { };
                    newRule2.SetRight(right_2);



                    // Introducem noile reguli de productie in lista
                    cReguliProductie.Add(newRule1);
                    cReguliProductie.Add(newRule2);

                    ReguliDeProductie newRule0 = new ReguliDeProductie();
                    newRule0.SetLeft(rList[i].GetLeft());

                    // Aplicam prima parte a regulii de eliminare a recursivitatii
                    if (i == rList.Count - 1)
                    {
                        string[] right = rList[i - 1].GetRight().Take(1).Select(ind => ind.ToString()).ToArray();
                        string[] str   = Helper.Concatenate(right, newRule1.GetLeft());
                        newRule0.SetRight(str);

                        //_reguliProductie.RemoveAt(index + i - 1);
                        if (checkArr[index + i - 1] == false)
                        {
                            checkArr[index + i - 1] = true;
                        }
                    }
                    else
                    if (i < rList.Count - 1)
                    {
                        string[] right = rList[i + 1].GetRight().Take(1).Select(ind => ind.ToString()).ToArray();
                        string[] str   = Helper.Concatenate(right, newRule1.GetLeft());
                        newRule0.SetRight(str);

                        if (checkArr[index + i + 1] == false)
                        {
                            checkArr[index + i + 1] = true;
                        }
                        //_reguliProductie.RemoveAt(index + i + 1);
                    }
                    cReguliProductie.Add(newRule0);
                    checkArr[index + i] = true;
                }
            }

            for (int i = 0; i < rList.Count; i++)
            {
                if (checkArr[index + i] == false)
                {
                    cReguliProductie.Add(rList[i]);
                    checkArr[index + i] = true;
                }
            }
        }
        private void CheckElements(List <ReguliDeProductie> rList, int index, List <ReguliDeProductie> cReguliProductie, bool[] checkArr)
        {
            // Contor utiliat in denumirea noilor neterminale
            int contor = 0;

            // Fiecare regula de productie specifica aceluiasi neterminal
            for (int i = 0; i < rList.Count; i++)
            {
                for (int j = i + 1; j < rList.Count; j++)
                {
                    // Se compara inceputul partii drepte a regulii de productie cu cel al urmatoarelor neterminale
                    int NumberOfCommonElements = Helper.Compare(rList[i].GetRight(), rList[j].GetRight());

                    // Daca se gaseste cel putin un element comun
                    if (NumberOfCommonElements != 0)
                    {
                        contor++;

                        // Doua reguli pentru A1
                        ReguliDeProductie newElement1 = new ReguliDeProductie();
                        ReguliDeProductie newElement2 = new ReguliDeProductie();


                        // Se seteaza partea stanga a celor doua reguli corespunzatoare neterminalului A1
                        newElement1.SetLeft(rList[i].GetLeft() + contor.ToString());
                        newElement2.SetLeft(rList[i].GetLeft() + contor.ToString());

                        // Se adauga A1 in lista de neterminale
                        _neterminale.Add(newElement1.GetLeft());

                        // Se seteaza partea dreapta a primei reguli corespunzatoare lui A1
                        string[] right_1 = rList[i].GetRight().Reverse().Take(rList[i].GetRightPartNumberOfElements() - NumberOfCommonElements).Reverse().ToArray();
                        newElement1.SetRight(right_1);

                        // Se seteaza partea dreapta pentru a doua regula corespunzatoare lui A1
                        string[] right_2 = rList[j].GetRight().Reverse().Take(rList[j].GetRightPartNumberOfElements() - NumberOfCommonElements).Reverse().ToArray();
                        newElement2.SetRight(right_2);

                        //// Adauugam cele doua reugli de productie la lista
                        cReguliProductie.Add(newElement1);
                        cReguliProductie.Add(newElement2);

                        // Se ia partea comuna a celor coua reguli (a)
                        string[] right = rList[i].GetRight().Take(NumberOfCommonElements).ToArray();

                        // Se concateneaza cu neterminalul introdus (A1)
                        ReguliDeProductie newElement0 = new ReguliDeProductie();
                        newElement0.SetLeft(rList[i].GetLeft());
                        newElement0.SetRight(Helper.Concatenate(right, newElement1.GetLeft()));

                        // Se adauga noua regula de productie in lista
                        cReguliProductie.Add(newElement0);

                        // se bifeaza regula de productie folosita din sirul original
                        checkArr[index + i] = true;

                        // Se elimina A -> ac
                        if (checkArr[index + j] == false)
                        {
                            //_reguliProductie.RemoveAt(index + j);
                            checkArr[index + j] = true;
                        }
                    }
                }
                if (checkArr[index + i] == false)
                {
                    cReguliProductie.Add(rList[i]);
                    checkArr[index + i] = true;
                }
            }
        }