private void NTPListClone()
        {
            var ntplist = ProductionInfo.Production_ParserResult.ntplist;

            NewNTPList = new List <NonTerminalProductionInfo>();

            foreach (var pitem in ntplist)
            {
                var newinfo = new NonTerminalProductionInfo {
                    Name = pitem.Name, Item = new List <NonTerminalProductionItemInfo>()
                };

                foreach (var item in pitem.Item)
                {
                    newinfo.Item.Add(new NonTerminalProductionItemInfo {
                        Content = item.Content.ToList()
                    });
                }

                NewNTPList.Add(newinfo);
            }
        }
        /// <summary>
        /// 消除公因子
        /// </summary>
        private void EliminateCommonFactor()
        {
            var n                = NewNTPList.Count;
            var newntpid         = 0;
            var newntpnameprefix = Production_Parser.SysNamePrefix + "U_";

            for (var i = 0; i < n; i++)
            {
                var lastdiff = 0;
                var hasdiff  = false;
                var minn     = NewNTPList[i].Item[0].Content.Count;

                for (var j = 1; j < NewNTPList[i].Item.Count; j++)
                {
                    minn = Math.Min(minn, NewNTPList[i].Item[j].Content.Count);
                }

                while (!hasdiff && lastdiff < minn)
                {
                    var curitem = NewNTPList[i].Item[0].Content[lastdiff];

                    for (var j = 1; j < NewNTPList[i].Item.Count; j++)
                    {
                        if (curitem != NewNTPList[i].Item[j].Content[lastdiff])
                        {
                            hasdiff = true;
                            break;
                        }
                    }

                    if (!hasdiff)
                    {
                        lastdiff++;
                    }
                }

                if (lastdiff > 0)
                {
                    //存在公共部分,需要分离
                    var needepsilon = false;
                    //存在重复项,意味着分离出的非公共部分需要包含epsilon
                    if (lastdiff == minn)
                    {
                        needepsilon = true;
                    }

                    var newntp = new NonTerminalProductionInfo();
                    newntp.Name = newntpnameprefix + (newntpid++);
                    newntp.Item = new List <NonTerminalProductionItemInfo>();
                    var hadepsilon = false;

                    //加入非公共部分
                    foreach (var pitem in NewNTPList[i].Item)
                    {
                        if (pitem.Content.Count > lastdiff)
                        {
                            var isepsilon = true;

                            foreach (var item in pitem.Content)
                            {
                                if (item != "epsilon")
                                {
                                    isepsilon = false;
                                }
                            }

                            //判断是否为epsilon项,若是,则设定needepsilon标记留作后面处理
                            if (isepsilon)
                            {
                                if (!hadepsilon)
                                {
                                    hadepsilon  = true;
                                    needepsilon = true;
                                }
                            }
                            else
                            {
                                var newcontent = new NonTerminalProductionItemInfo();
                                newcontent.Content = new List <string>();

                                for (var j = lastdiff; j < pitem.Content.Count; j++)
                                {
                                    newcontent.Content.Add(pitem.Content[j]);
                                }

                                newntp.Item.Add(newcontent);
                            }
                        }
                    }

                    //加入epsilon项
                    if (needepsilon)
                    {
                        newntp.Item.Add(new NonTerminalProductionItemInfo {
                            Content = new string[] { "epsilon" }.ToList()
                        });
                    }

                    //清空原产生式所有项,仅保留公共项,并在最后追加到该新产生式的引用
                    var content = NewNTPList[i].Item[0];
                    NewNTPList[i].Item.Clear();
                    content.Content.RemoveRange(lastdiff, content.Content.Count - lastdiff);
                    content.Content.Add(newntp.Name);
                    NewNTPList[i].Item.Add(content);
                    NewNTPList.Add(newntp);
                }
            }
        }
        /// <summary>
        /// 消除左递归
        /// </summary>
        private bool EliminateLeftRecursion(out string ErrorText)
        {
            ErrorText = "";
            var ntplist = ProductionInfo.Production_ParserResult.ntplist;
            //首先建立矩阵方程X = XA + B,其中X是1 * n的,A是n * n的,B是1 * n的,n为非终结符的总数
            var n      = ntplist.Length;
            var ntpmap = new Dictionary <string, int>();//非终结符映射表
            var X      = new string[n];

            for (var i = 0; i < n; i++)
            {
                X[i]         = ntplist[i].Name;
                ntpmap[X[i]] = i;
            }

            var A = new List <List <string> > [n, n];
            var B = new List <string[]> [n];

            for (var i = 0; i < n; i++)
            {
                for (var j = 0; j < n; j++)
                {
                    A[i, j] = null;
                }
            }

            for (var i = 0; i < n; i++)
            {
                foreach (var item in ntplist[i].Item)
                {
                    var headerindex = 0;

                    while (headerindex < item.Content.Length && item.Content[headerindex] == "epsilon")
                    {
                        headerindex++;
                    }

                    if (headerindex >= item.Content.Length)
                    {
                        headerindex = item.Content.Length - 1;//全为epsilon,留出一项即可
                    }

                    if (ntpmap.ContainsKey(item.Content[headerindex]))
                    {
                        //开头为非终结符,表明该项应该属于A矩阵
                        var line = ntpmap[item.Content[headerindex]];

                        //第line行第i列表示第i个产生式的第line项
                        if (A[line, i] == null)
                        {
                            A[line, i] = new List <List <string> >();
                        }

                        //创建一个新列表,将头非终结符之后的所有的符号全部加入该列表并追加到A矩阵当前项中
                        var list = new List <string>();

                        for (var j = headerindex + 1; j < item.Content.Length; j++)
                        {
                            list.Add(item.Content[j]);
                        }

                        //防止程序崩溃的保护措施
                        if (list.Count == 0)
                        {
                            list.Add("epsilon");
                        }

                        A[line, i].Add(list);
                    }
                    else
                    {
                        //开头为终结符,表示该项应该属于B矩阵
                        if (B[i] == null)
                        {
                            B[i] = new List <string[]>();
                        }

                        B[i].Add(item.Content);
                    }
                }
            }

            //方程转化为X = BZ,Z = I + AZ
            //将方程转化为产生式序列
            var newntplist       = new List <NonTerminalProductionInfo>();
            var newntpitemprefex = Production_Parser.SysNamePrefix + "Z_";
            var nullZ            = new HashSet <string>();

            //生成Z产生式
            for (var i = 0; i < n; i++)
            {
                for (var j = 0; j < n; j++)
                {
                    var newntp = new NonTerminalProductionInfo();

                    newntp.Name = newntpitemprefex + (i + 1) + "_" + (j + 1);
                    newntp.Item = new List <NonTerminalProductionItemInfo>();

                    for (var k = 0; k < n; k++)
                    {
                        if (A[i, k] != null)
                        {
                            foreach (var pitem in A[i, k])
                            {
                                var newcontent = new NonTerminalProductionItemInfo();
                                newcontent.Content = pitem.ToList();
                                newcontent.Content.Add(newntpitemprefex + (k + 1) + "_" + (j + 1));
                                newntp.Item.Add(newcontent);
                            }
                        }
                    }

                    //+ I
                    if (i == j)
                    {
                        newntp.Item.Add(new NonTerminalProductionItemInfo {
                            Content = new string[] { "epsilon" }.ToList()
                        });
                    }

                    if (newntp.Item.Count == 0)
                    {
                        nullZ.Add(newntp.Name);
                    }
                    else
                    {
                        newntplist.Add(newntp);
                    }
                }
            }

            //移除所有无效的Z产生式
            var updated = true;

            while (updated)
            {
                updated = false;

                for (var i = newntplist.Count - 1; i >= 0; i--)
                {
                    for (var j = newntplist[i].Item.Count - 1; j >= 0; j--)
                    {
                        var hasunknownitem = false;

                        foreach (var item in newntplist[i].Item[j].Content)
                        {
                            if (nullZ.Contains(item))
                            {
                                hasunknownitem = true;
                                break;
                            }
                        }

                        if (hasunknownitem)
                        {
                            newntplist[i].Item.RemoveAt(j);
                            updated = true;
                        }
                    }

                    if (newntplist[i].Item.Count == 0)
                    {
                        nullZ.Add(newntplist[i].Name);
                        newntplist.RemoveAt(i);
                        updated = true;
                    }
                }
            }

            //产生式选择
            for (var i = 0; i < n; i++)
            {
                var newntp = new NonTerminalProductionInfo();

                newntp.Name = X[i];
                newntp.Item = new List <NonTerminalProductionItemInfo>();

                //遍历B矩阵的每一项,与Z矩阵进行相乘操作
                var hasnonnull = false;

                for (var j = 0; j < n; j++)
                {
                    if (B[j] != null && !nullZ.Contains(newntpitemprefex + (j + 1) + "_" + (i + 1)))
                    {
                        hasnonnull = true;

                        foreach (var pitem in B[j])
                        {
                            var newcontent = new NonTerminalProductionItemInfo();
                            newcontent.Content = pitem.ToList();
                            newcontent.Content.Add(newntpitemprefex + (j + 1) + "_" + (i + 1));
                            newntp.Item.Add(newcontent);
                        }
                    }
                }

                if (!hasnonnull)
                {
                    ErrorText = "[GrammarCompiler_LL_1]:该文法不是LL(1)文法!在进行左递归消除时,对于非终结符\"" + newntp.Name + "\"而言,B矩阵各项全为null,疑似存在循环引用!\n";
                    return(false);
                }

                newntplist.Add(newntp);
            }

            //删除多余产生式,采用从开始符号的引用分析方法
            var visited = new Dictionary <string, bool>();

            for (var i = 0; i < newntplist.Count; i++)
            {
                visited[newntplist[i].Name] = false;
                ntpmap[newntplist[i].Name]  = i;
            }

            var queue = new Queue <string>();

            queue.Enqueue(StartSymbol);
            visited[StartSymbol] = true;

            while (queue.Count > 0)
            {
                var curntp = queue.Dequeue();

                foreach (var pitem in newntplist[ntpmap[curntp]].Item)
                {
                    foreach (var item in pitem.Content)
                    {
                        if (visited.ContainsKey(item) && !visited[item])
                        {
                            visited[item] = true;
                            queue.Enqueue(item);
                        }
                    }
                }
            }

            for (var i = newntplist.Count - 1; i >= 0; i--)
            {
                if (!visited[newntplist[i].Name])
                {
                    newntplist.RemoveAt(i);
                }
            }

            NewNTPList = newntplist;
            return(true);
        }