Ejemplo n.º 1
0
        /// <summary>
        /// 填充 DFA 的数据。
        /// </summary>
        /// <param name="grammar">词法分析器使用的语法。</param>
        /// <param name="useTrailing">是否用到了向前看。</param>
        private void FillDfa(Grammar <T> grammar, out bool useTrailing)
        {
            // 构造 DFA。
            Nfa nfa     = BuildNfa(grammar, out useTrailing);
            int headCnt = this.contextCount * 2;
            Dfa dfa     = nfa.BuildDfa(headCnt);

            dfa.Minimize(headCnt);
            // 获取 DFA 的数据。
            this.charClass      = dfa.CharClass.GetCharClassMap();
            this.stateCount     = dfa.Count;
            this.states         = new StateData[stateCount];
            this.charClassCount = dfa.CharClass.Count;
            for (int i = 0; i < this.stateCount; i++)
            {
                DfaState state       = dfa[i];
                int[]    transitions = new int[charClassCount];
                for (int j = 0; j < charClassCount; j++)
                {
                    DfaState target = state[j];
                    if (target == null)
                    {
                        transitions[j] = Constants.DeadState;
                    }
                    else
                    {
                        transitions[j] = target.Index;
                    }
                }
                states[i] = new StateData(transitions, state.SymbolIndex);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// 初始化 <see cref="DfaState"/> 类的新实例。
 /// </summary>
 /// <param name="dfa">状态所在的 DFA。</param>
 /// <param name="index">状态的索引。</param>
 public DfaState(Dfa dfa, int index)
 {
     this.Dfa         = dfa;
     this.Index       = index;
     this.transitions = new DfaState[dfa.CharClass.Count];
 }
Ejemplo n.º 3
0
        /// <summary>
        /// 根据当前的 NFA 构造 DFA,采用子集构造法。
        /// </summary>
        /// <param name="headCnt">头节点的个数。</param>
        internal Dfa BuildDfa(int headCnt)
        {
            Dfa dfa = new Dfa(charClass);
            // DFA 和 NFA 的状态映射表,DFA 的一个状态对应 NFA 的一个状态集合。
            Dictionary <DfaState, HashSet <NfaState> > stateMap =
                new Dictionary <DfaState, HashSet <NfaState> >();
            // 由 NFA 状态集合到对应的 DFA 状态的映射表(与上表互逆)。
            Dictionary <HashSet <NfaState>, DfaState> dfaStateMap =
                new Dictionary <HashSet <NfaState>, DfaState>(SetEqualityComparer <NfaState> .Default);
            Stack <DfaState> stack = new Stack <DfaState>();

            // 添加头节点。
            for (int i = 0; i < headCnt; i++)
            {
                DfaState head = dfa.NewState();
                head.SymbolIndex = new int[0];
                HashSet <NfaState> headStates = EpsilonClosure(Enumerable.Repeat(this[i], 1));
                stateMap.Add(head, headStates);
                dfaStateMap.Add(headStates, head);
                stack.Push(head);
            }
            int charClassCnt = charClass.Count;

            while (stack.Count > 0)
            {
                DfaState           state    = stack.Pop();
                HashSet <NfaState> stateSet = stateMap[state];
                // 遍历字符类。
                for (int i = 0; i < charClassCnt; i++)
                {
                    // 对于 NFA 中的每个转移,寻找 Move 集合。
                    HashSet <NfaState> set = Move(stateSet, i);
                    if (set.Count > 0)
                    {
                        set = EpsilonClosure(set);
                        DfaState newState;
                        if (!dfaStateMap.TryGetValue(set, out newState))
                        {
                            // 添加新状态.
                            newState = dfa.NewState();
                            stateMap.Add(newState, set);
                            dfaStateMap.Add(set, newState);
                            stack.Push(newState);
                            // 合并符号索引。
                            newState.SymbolIndex = set.Where(s => s.SymbolIndex != Constants.None)
                                                   .Select(s =>
                            {
                                if (s.StateType == NfaStateType.TrailingHead)
                                {
                                    return(int.MaxValue - s.SymbolIndex);
                                }
                                else
                                {
                                    return(s.SymbolIndex);
                                }
                            }).OrderBy(idx => idx).ToArray();
                        }
                        // 添加 DFA 的转移。
                        state[i] = newState;
                    }
                }
            }
            return(dfa);
        }