private void Form1_Load(object sender, EventArgs e) { Console.WriteLine(Notation.infixToPostfix("abb+(abb)+")); NFA n = Compiler.Compile(Notation.infixToPostfix("(a|b)*")); Console.WriteLine("AHH"); // DEBUG CODE }
/// <summary> /// Creates an alternation between this NFA and the given NFA /// </summary> /// <param name="secondNFA">NFA being alternated with this NFA</param> public void Alternation(NFA secondNFA) { // alternating NFAs requires we make a new start state that has epsilon transitions to // both of the given NFAs // create new start state (not accepting) State newStart = new State(false); // add epsilon transitions from the new start to the start of the two original NFAs newStart.AddTransition(Transition.Epsilon, this.GetStart()); newStart.AddTransition(Transition.Epsilon, secondNFA.GetStart()); // make the start of this NFA the new start state this.SetStart(newStart); }
/// <summary> /// Concatenates the given NFA to the end of this NFA /// </summary> /// <param name="appendingNFA">NFA being appended to the end of this NFA</param> public void Concatenate(NFA appendingNFA) { // when concatenating two NFAs, accepting states of the first NFA // are given epsilon transitions to the start state of the seconds NFA // keep a list of visited states so we don't add states over and over List <State> visited = new List <State>(); // reference to the current state we're working with State curState; // queue of states to be checked Queue <State> stateQueue = new Queue <State>(); stateQueue.Enqueue(this.GetStart()); // while states exist in the queue, continue to loop while (stateQueue.Count > 0) { curState = stateQueue.Dequeue(); if (visited.Contains(curState)) { continue; } // add this state to the list of visited states visited.Add(curState); // queue up all states that can be transitioned to foreach (Transition t in curState.GetTransitions()) { stateQueue.Enqueue(t.GetState()); } // if this state is accepting, add an epsilon transition to the start of // the appendingNFA if (curState.IsAccepting()) { curState.AddTransition(Transition.Epsilon, appendingNFA.GetStart()); // this state is no longer accepting curState.SetAccepting(false); } } }
//TODO make this work f****r public static NFA Compile(string postfix) { // stack that stores NFA pieces Stack <NFA> nfaStack = new Stack <NFA>(); // go through postfix notation foreach (char c in postfix.ToCharArray()) { switch (c) { // concatenate case Notation.CONCAT_OP: // pop previous two items on stack NFA nCat1 = nfaStack.Pop(); NFA nCat2 = nfaStack.Pop(); // make them one item nCat2.Concatenate(nCat1); //TODO make sure this is the right order // push it onto the stack nfaStack.Push(nCat2); break; // kleene star case '*': NFA nStar = nfaStack.Pop(); nStar.KleeneStar(); nfaStack.Push(nStar); break; // alternation case '|': NFA nAlt1 = nfaStack.Pop(); NFA nAlt2 = nfaStack.Pop(); nAlt2.Alternation(nAlt1); nfaStack.Push(nAlt2); break; // kleene plus case '+': //TODO future implementation break; // standard character default: // make new NFA piece containing 'c' and push it to the NFA stack // we make an NFA in the format: // -> O -a-> O // where the second state is accepting State start = new State(false); State transState = new State(true); start.AddTransition(c, transState); nfaStack.Push(new NFA(start)); break; } } return(nfaStack.Pop()); }