/// <summary>
        /// LR(1)的Goto操作。
        /// 将圆点移到所有LR(1)项中的符号<paramref name="x"/>之后。
        /// </summary>
        /// <param name="list"></param>
        /// <param name="state"></param>
        /// <param name="x">一个文法符号,终结点或非终结点。</param>
        /// <param name="firstList"></param>
        /// <returns></returns>
        static LALR1State Goto(this RegulationList list, LALR1State state, TreeNodeType x, Dictionary <TreeNodeType, bool> nullableDict, FIRSTCollection firstList = null)
        {
            var toState = new LALR1State();

            foreach (var group in state.GetGroups())
            {
                TreeNodeType nextNode = group.Item1.GetNodeNext2Dot();
                if (nextNode == x)
                {
                    toState.TryInsert(
                        new LR0Item(group.Item1.Regulation, group.Item1.DotPosition + 1),
                        group.Item2);
                }
            }

            return(Closure(list, toState, nullableDict, firstList));
        }
        /// <summary>
        /// LR(1)的Closure操作。
        /// 补全一个状态。
        /// </summary>
        /// <param name="grammar"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        static LALR1State Closure(this RegulationList grammar, LALR1State state,
                                  Dictionary <TreeNodeType, bool> nullableDict = null, FIRSTCollection firstCollection = null)
        {
            if (nullableDict == null)
            {
                grammar.GetNullableDict(out nullableDict);
            }
            if (firstCollection == null)
            {
                grammar.GetFirstCollection(out firstCollection, nullableDict);
            }

            Queue <LR1Item> queue = new Queue <LR1Item>();

            foreach (var item in state)
            {
                queue.Enqueue(item);
            }
            while (queue.Count > 0)
            {
                LR1Item      item = queue.Dequeue();
                TreeNodeType node = item.GetNodeNext2Dot();
                if (node == null || node.IsLeave)
                {
                    continue;
                }

                List <TreeNodeType> betaZ     = item.GetBetaZ();
                FIRST             first       = grammar.GetFirst(firstCollection, nullableDict, betaZ);
                List <Regulation> regulations = grammar.GetRegulations(node);
                foreach (var regulation in regulations)
                {
                    foreach (var value in first.Values)
                    {
                        LR1Item newItem = new LR1Item(regulation, 0, value);
                        if (state.TryInsert(newItem))
                        {
                            queue.Enqueue(newItem);
                        }
                    }
                }
            }

            return(state);
        }