Пример #1
0
        public NFAGraph ToDFA()
        {
            //first, we need to know the alphabet
            var alphabet = new SortedSet<char>();
            foreach (var state in _adjList.Keys)
            {
                foreach (var link in _adjList[state].Where(l => !l.IsEmpty))
                {
                    alphabet.UnionWith(link.CharClass.CharSet());
                }
            }

            var dfa = new NFAGraph();
            var stateSetMap = new Dictionary<HashSet<NFAState>, NFAState>(HashSet<NFAState>.CreateSetComparer());
            var startStateSet = eClosure(_startState);
            dfa._startState = dfa.NewState();
            stateSetMap[startStateSet] = dfa._startState;

            //Follow the links of the start state
            var markedDFAStates = new HashSet<HashSet<NFAState>>(HashSet<NFAState>.CreateSetComparer());
            //Start at the start and continue whilst there are no unmarked states
            var DFAStateQueue = new Queue<HashSet<NFAState>>();
            DFAStateQueue.Enqueue(startStateSet);
            while (DFAStateQueue.Count > 0)
            {
                var thisstate = DFAStateQueue.Dequeue();
                var origdfastate = stateSetMap[thisstate];
                markedDFAStates.Add(thisstate);
                foreach (var c in alphabet)
                {
                    var cclass = new CharacterClass();
                    cclass.Elements.Add(new CharacterClassElement(c));
                    cclass.IsNegated = false;

                    var targetStates = new HashSet<NFAState>();
                    foreach (var nfastate in thisstate)
                    {
                        foreach (var link in _adjList[nfastate])
                        {
                            if (CanFollowLink(link, c))
                            {
                                targetStates.Add(link.Target);
                            }
                        }
                    }
                    var targetStateClosure = eClosure(targetStates);
                    NFAState ndfastate;
                    if (!markedDFAStates.Contains(targetStateClosure))
                    {
                        DFAStateQueue.Enqueue(targetStateClosure);

                        ndfastate = dfa.NewState();
                        stateSetMap[targetStateClosure] = ndfastate;
                        if (targetStateClosure.Any(s => _finishState.Contains(s)))
                            dfa._finishState.Add(ndfastate);
                    }
                    else
                    {
                        ndfastate = stateSetMap[targetStateClosure];
                    }

                    dfa._adjList[origdfastate].Add(new NFALink()
                    {
                        IsEmpty = false,
                        CharClass = cclass,
                        Target = ndfastate
                    });

                }
                //now check for . transitions
            }

            return dfa;
        }
Пример #2
0
        private void InstantiateFromRegex(RegExpr re)
        {
            _startState = NewState();
            _finishState.Add(NewState());
            foreach (var alt in re.Alternatives)
            {
                var altnfa = new NFAGraph(alt);
                CopyInto(altnfa);

                var nsl = new NFALink();
                var nfl = new NFALink();
                nsl.IsEmpty = true;
                nfl.IsEmpty = true;
                nsl.Target = altnfa._startState;
                nfl.Target = _finishState.Single();
                _adjList[_startState].Add(nsl);
                _adjList[altnfa._finishState.Single()].Add(nfl);
            }
        }
Пример #3
0
 private void InstantiateFromMatchFactorOp(MatchFactorWithOp mop)
 {
     var mf = new NFAGraph(mop.Factor);
     CopyIntoWithTerminals(mf);
     switch (mop.Op.Type)
     {
         case UnaryOperatorType.None:
             break;
         case UnaryOperatorType.Optional:
             var elink1 = new NFALink();
             elink1.IsEmpty = true;
             elink1.Target = _finishState.Single();
             _adjList[_startState].Add(elink1);
             break;
         case UnaryOperatorType.OneMany:
             var elink2 = new NFALink();
             elink2.IsEmpty = true;
             elink2.Target = _startState;
             _adjList[_finishState.Single()].Add(elink2);
             break;
         case UnaryOperatorType.NoneMany:
             var newend = NewState();
             var blink = new NFALink();
             var flink = new NFALink();
             blink.IsEmpty = true;
             flink.IsEmpty = true;
             blink.Target = _startState;
             flink.Target = newend;
             _adjList[_finishState.Single()].Add(blink);
             _adjList[_startState].Add(flink);
             _finishState = new HashSet<NFAState>{newend};
             break;
     }
 }
Пример #4
0
        private void InstantiateFromAlternative(Alternative alt)
        {
            _startState = NewState();
            _finishState.Add(NewState());
            var curtail = _startState;
            foreach (var mf in alt.Factors)
            {
                var mfnfa = new NFAGraph(mf);
                CopyInto(mfnfa);

                var nl = new NFALink();
                nl.IsEmpty = true;
                nl.Target = mfnfa._startState;
                _adjList[curtail].Add(nl);
                curtail = mfnfa._finishState.Single();
            }
            var nel = new NFALink();
            nel.IsEmpty = true;
            nel.Target = _finishState.Single();
            _adjList[curtail].Add(nel);
        }
Пример #5
0
 private void CopyIntoWithTerminals(NFAGraph other)
 {
     CopyInto(other);
     this._startState = other._startState;
     this._finishState = other._finishState;
 }
Пример #6
0
 private void CopyInto(NFAGraph other)
 {
     foreach (var node in other._nodes)
         this._nodes.Add(node);
     foreach (var kvp in other._adjList)
         this._adjList[kvp.Key] = kvp.Value;
 }