Beispiel #1
0
        public static void TestRegExp()
        {
            a = new Regex("a");
            b = new Regex("b");

            // expr1: "baa"
            expr1 = new Regex("baa");
            // expr2: "bb"
            expr2 = new Regex("bb");
            // expr3: "baa | baa"
            expr3 = expr1.or(expr2);

            // all: "(a|b)*"
            all = (a.or(b)).star();

            // expr4: "(baa | baa)+"
            expr4 = expr3.plus();
            // expr5: "(baa | baa)+ (a|b)*"
            expr5 = expr4.dot(all);
            // converting to NDFA
            int i = 0;
            NDFA <int, char> ndfa     = expr5.toNDFA(ref i);
            string           ndfaTest = "baab";

            tester(ndfaTest, ndfa.accept(ndfaTest.ToCharArray()));
            Console.WriteLine("-----NDFA Graph-----");
            GraphViz.PrintNDFA(ndfa, "ndfa");
        }
Beispiel #2
0
        public NDFA <T, U> reverse(U epsilon)
        {
            NDFA <T, U> result = new NDFA <T, U>(epsilon);

            // Add DFA's startstate as endstate
            result.addEndState(StartState);
            foreach (T endState in EndStates)
            {
                result.addStartState(endState);
            }

            forEachTransition((terminal, fromState, toState)
                              => result.addTransition(terminal, toState, fromState));
            return(result);
        }
Beispiel #3
0
        public static void PrintNDFA <T, U>(NDFA <T, U> ndfa, string filename)
        {
            var s = "digraph{ ";

            s += GetFinalStatesData(ndfa.EndStates);
            s += GetStartStatesData(ndfa.StartStates);

            s += "node [shape = circle];";
            ndfa.forEachTransition((terminal, fromState, toState) => s += TransitionToString(terminal, fromState, toState));
            s += " }";

            Console.WriteLine(s);

            GenerateGraphFile(s, filename, Enums.GraphReturnType.Svg);
        }
Beispiel #4
0
        public NDFA <int, char> toNDFA(ref int i)
        {
            NDFA <int, char> ndfaLeft  = left?.toNDFA(ref i);
            NDFA <int, char> ndfaRight = right?.toNDFA(ref i);
            var ndfa = new NDFA <int, char>('$', ndfaLeft, ndfaRight);

            switch (op)
            {
            case Operator.ONE:
                var currState = ++i;
                ndfa.addStartState(currState);
                foreach (var terminal in terminals)
                {
                    ndfa.addTransition(terminal, currState, currState = ++i);
                }
                ndfa.addEndState(currState);
                break;

            case Operator.OR:
                var orStartState = ++i;
                var orEndState   = ++i;
                ndfa.addStartState(orStartState);
                ndfa.addTransition(ndfa.Epsilon, orStartState, ndfaLeft.StartStates.First());
                ndfa.addTransition(ndfa.Epsilon, orStartState, ndfaRight.StartStates.First());
                ndfa.addTransition(ndfa.Epsilon, ndfaLeft.EndStates.Last(), orEndState);
                ndfa.addTransition(ndfa.Epsilon, ndfaRight.EndStates.Last(), orEndState);
                ndfa.addEndState(orEndState);
                break;

            case Operator.DOT:
                ndfa.addStartState(ndfaLeft.StartStates.First());
                ndfa.addEndState(ndfaRight.EndStates.Last());
                ndfa.addTransition(ndfa.Epsilon, ndfaLeft.EndStates.Last(), ndfaRight.StartStates.First());
                break;

            case Operator.PLUS:
                ndfa = plusAndStarOperatorHandlerCalledByToNDFA(ndfa, ndfaLeft, ref i);
                break;

            case Operator.STAR:
                ndfa = plusAndStarOperatorHandlerCalledByToNDFA(ndfa, ndfaLeft, ref i);
                break;

            default:
                break;
            }
            return(ndfa);
        }
Beispiel #5
0
        private NDFA <int, char> plusAndStarOperatorHandlerCalledByToNDFA(NDFA <int, char> ndfa, NDFA <int, char> left, ref int i)
        {
            var startState = ++i;
            var endState   = ++i;

            ndfa.addStartState(startState);
            ndfa.addEndState(endState);
            ndfa.addTransition(ndfa.Epsilon, startState, left.StartStates.First());
            ndfa.addTransition(ndfa.Epsilon, left.EndStates.Last(), left.StartStates.First());
            ndfa.addTransition(ndfa.Epsilon, left.EndStates.Last(), endState);
            if (op == Operator.STAR)
            {
                ndfa.addTransition(ndfa.Epsilon, startState, endState);
            }
            return(ndfa);
        }
Beispiel #6
0
 public NDFA(U epsilon, NDFA <T, U> ndfa1, NDFA <T, U> ndfa2)
 {
     Epsilon = epsilon;
     if (ndfa1 != null)
     {
         Alphabet.UnionWith(ndfa1.Alphabet);
     }
     if (ndfa2 != null)
     {
         Alphabet.UnionWith(ndfa2.Alphabet);
     }
     Transitions
         = ndfa1 != null && ndfa2 != null
         ? ndfa1.Transitions.Concat(ndfa2.Transitions).ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
         : ndfa1 != null
         ? ndfa1.Transitions
         : ndfa2 != null
         ? ndfa2.Transitions
         : Transitions;
 }