// 扩充计算当前产生式组的闭包
        public EnclosedState calcEnclosed(EnclosedState es)
        {
            List <KeyValuePair <string, List <char> > > queue = new List <KeyValuePair <string, List <char> > >();

            foreach (var item in es.items) // 所有产生式入队
            {
                queue.Add(item);
            }
            for (int i = 0; i < queue.Count; i++)
            {
                var item = queue[i];
                int pos  = item.Key.IndexOf('●') + 1;
                if (pos < item.Key.Length)
                {
                    if (!isTerminator(item.Key[pos])) // 非终结符item.Key[pos]扩充产生式
                    {
                        foreach (string text in page.lstProduce.Items)
                        {
                            if (text[text.IndexOf(':') + 1] == item.Key[pos]) // 要扩充的一项产生式
                            {
                                string      extend = text.Substring(text.IndexOf(':') + 1).Replace(" → ", " → ●").Replace("ε", "");
                                List <char> suffix = new List <char>();
                                bool        append = false;
                                if (pos + 1 == item.Key.Length) // 该非终结符在结尾,则对于'ba'要添加'a'
                                {
                                    append = true;
                                }
                                for (int j = pos + 1; j < item.Key.Length; j++)
                                {
                                    if (isTerminator(item.Key[j]) && !suffix.Contains(item.Key[j])) // 如果是终结符则直接确定附加项
                                    {
                                        suffix.Add(item.Key[j]);
                                        break;
                                    }
                                    else // 如果是非终结符则添加FIRST集到附加项(包含ε则继续)
                                    {
                                        bool blank = false;
                                        foreach (char c in first[item.Key[j]])
                                        {
                                            if (c == 'ε')
                                            {
                                                blank = true;
                                            }
                                            else if (!suffix.Contains(c))
                                            {
                                                suffix.Add(c);
                                            }
                                        }
                                        if (!blank)
                                        {
                                            break;
                                        }
                                        if (j + 1 == item.Key.Length) // 最后一个可行非终结符还有ε
                                        {
                                            append = true;
                                        }
                                    }
                                }
                                if (append) // 原有附加项并到扩展项
                                {
                                    foreach (char c in item.Value)
                                    {
                                        if (!suffix.Contains(c))
                                        {
                                            suffix.Add(c);
                                        }
                                    }
                                }
                                int k;
                                for (k = 0; k < queue.Count; k++) // 寻找完全重复项
                                {
                                    if (queue[k].Key.Equals(extend) && queue[k].Value.Count == suffix.Count)
                                    {
                                        int l;
                                        suffix.Sort();
                                        for (l = 0; l < suffix.Count; l++)
                                        {
                                            if (suffix[l] != queue[k].Value[l])
                                            {
                                                break;
                                            }
                                        }
                                        if (l >= suffix.Count) // 完全相等
                                        {
                                            break;
                                        }
                                    }
                                }
                                if (k >= queue.Count) // 没有找到完全相等项,确定扩展一项(队列顺序限制,包括对“半重复”产生式也要进队)
                                {
                                    queue.Add(new KeyValuePair <string, List <char> >(extend, suffix));
                                }
                            }
                        }
                    }
                }
            }
            EnclosedState esbuild = new EnclosedState();

            for (int i = 0; i < queue.Count; i++)
            {
                if (esbuild.items.ContainsKey(queue[i].Key)) // 压缩队中产生式,若含有相同递推式则合并附加项,否则新建【产生式|向前搜索符】元组
                {
                    foreach (char c in queue[i].Value)
                    {
                        if (!esbuild.items[queue[i].Key].Contains(c))
                        {
                            esbuild.items[queue[i].Key].Add(c);
                        }
                    }
                }
                else
                {
                    esbuild.items.Add(queue[i].Key, queue[i].Value);
                }
            }
            return(esbuild);
        }
        // 构造LR(1)文法的DFA
        private void calcDefiniteFA()
        {
            int           count   = 0;
            List <string> extList = new List <string>();

            extList.Add(count++.ToString() + ":" + "Φ → " + page.cbBegin.SelectedItem);
            foreach (string line in page.lstProduce.Items)
            {
                extList.Add(count++.ToString() + ":" + line[0] + " → " + line.Substring(4));
            }
            page.lstProduce.Items.Clear();

            foreach (string line in extList)
            {
                page.lstProduce.Items.Add(line);
            }

            page.nterminator.Text += 'Φ';

            var init_state = new EnclosedState();

            init_state.items.Add("Φ → ●" + page.cbBegin.SelectedItem, new List <char>()
            {
                '#'
            });
            init_state = calcEnclosed(init_state);

            allStates.Add(init_state);

            List <List <KeyValuePair <int, char> > > release = new List <List <KeyValuePair <int, char> > >();

            // release[i][j]记录第i个状态可以通过字符release[i][j].Value推出第release[i][j].Key个状态

            for (int i = 0; i < allStates.Count; i++)
            {
                var front     = allStates[i].items;
                var graphAdj  = new List <KeyValuePair <int, char> >();
                var enableChr = new List <char>(); // 对推新状态的途径字符判重
                foreach (var pair in front)        // 找出所有不重复可推状态
                {
                    int pos = pair.Key.IndexOf('●') + 1;
                    if (pos < pair.Key.Length && !enableChr.Contains(pair.Key[pos]))
                    {
                        char c = pair.Key[pos];
                        enableChr.Add(c); // 对推新状态的途径字符判重
                        // 对经过c字符转向新状态
                        EnclosedState esbuild = new EnclosedState();
                        foreach (var trans in front) // 查询当前状态所有产生式中,●后是c的条目
                        {
                            int np = trans.Key.IndexOf('●') + 1;
                            if (np < trans.Key.Length && trans.Key[np] == c) // 找到一条符合项
                            {
                                string next = trans.Key.Remove(np - 1, 1).Insert(np, "●");
                                esbuild.items.Add(next, trans.Value);
                            }
                        }
                        esbuild = calcEnclosed(esbuild);
                        int j;
                        for (j = 0; j < allStates.Count; j++)                            // 新状态已存在
                        {
                            if (EnclosedState.Equals(esbuild.items, allStates[j].items)) // 判断是否完全匹配
                            {
                                graphAdj.Add(new KeyValuePair <int, char>(j, c));
                                break;
                            }
                        }
                        if (j >= allStates.Count) // 不存在新状态则创建
                        {
                            graphAdj.Add(new KeyValuePair <int, char>(j, c));
                            allStates.Add(esbuild);
                        }
                    }
                }
                release.Add(graphAdj);
            }

            graphMatrixCount = allStates.Count;
            graphMatrix      = new char[graphMatrixCount, graphMatrixCount];
            for (int i = 0; i < graphMatrixCount; i++)
            {
                foreach (var j in release[i])
                {
                    graphMatrix[i, j.Key] = j.Value;
                }
            }

            int tot = allStates[0].items.Count;

            for (int i = 1; i < allStates.Count; i++)
            {
                tot = Math.Max(tot, allStates[i].items.Count);
            }

            // 显示DFA状态转换矩阵
            var           dfaMatrix = new List <KeyValuePair <string, List <string> > >();
            List <string> stateList = new List <string>();

            for (int i = 0; i < graphMatrixCount; i++)
            {
                stateList.Add("状态" + i);
            }
            dfaMatrix.Add(new KeyValuePair <string, List <string> >("DFA", stateList));
            for (int i = 0; i < graphMatrixCount; i++)
            {
                stateList = new List <string>();
                for (int j = 0; j < graphMatrixCount; j++)
                {
                    if (graphMatrix[j, i] > 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.Append("从状态" + j + ":\n");
                        foreach (var item in allStates[j].items)
                        {
                            sb.Append(item.Key);
                            sb.Append(" , ");
                            sb.Append(item.Value[0]);
                            for (int k = 1; k < item.Value.Count; k++)
                            {
                                sb.Append('/');
                                sb.Append(item.Value[k]);
                            }
                            sb.Append('\n');
                        }
                        for (int l = allStates[j].items.Count; l < tot; l++)
                        {
                            sb.Append('\n');
                        }
                        sb.Append("经过字符 " + graphMatrix[j, i] + " 转变为状态" + i + ":\n");
                        foreach (var item in allStates[i].items)
                        {
                            sb.Append(item.Key);
                            sb.Append(" , ");
                            sb.Append(item.Value[0]);
                            for (int k = 1; k < item.Value.Count; k++)
                            {
                                sb.Append('/');
                                sb.Append(item.Value[k]);
                            }
                            sb.Append('\n');
                        }
                        for (int l = allStates[i].items.Count; l < tot; l++)
                        {
                            sb.Append('\n');
                        }
                        stateList.Add(sb.ToString());
                    }
                    else
                    {
                        StringBuilder sb = new StringBuilder();
                        for (int l = 0; l <= tot; l++)
                        {
                            sb.Append("\n\n");
                        }
                        stateList.Add(sb.ToString());
                    }
                }
                dfaMatrix.Add(new KeyValuePair <string, List <string> >("状态" + i, stateList));
            }
            page.tbDfa.ItemsSource = DataSourceCreator.ToDataSource(dfaMatrix);
        }