public List <LlConfiguration <TSymbol> > OutgoingEpsiEdges(LlConfiguration <TSymbol> llconf) { if (llconf.Count() == 0) { // If intially the stack is empty we cannot figure out next edges, so return an empty list. return(new List <LlConfiguration <TSymbol> > ()); } var topState = llconf.stack[llconf.stack.Count - 1]; var transitions = topState.Transitions; var result = new List <LlConfiguration <TSymbol> >(); foreach (var kv in transitions) { var symbol = kv.Key; var targetState = kv.Value; var newllconf = llconf.Pop(); // a copy without top state if (!IsTerminal(symbol)) { newllconf = newllconf.Push(targetState); newllconf = newllconf.Push(Automatons[symbol].Start); result.Add(newllconf); } } if (topState.Accepting > 0) { // We also add a separate epsilon-edge for the situation in which // top state is accepting state for some nonterminal's automaton and // we don't move forward but just pop the top state from the stack. // then we consider two cases: when the stack is empty and when it's not. if (llconf.Count() == 1) { // prevSymbol is a nonterminal whose DFA contains topState (and topState is accepting) var prevSymbol = AccStateOwnerDictionary [topState]; var newllconf = llconf.Pop(); // a copy without top state // browse the list of target states for the prevSymbol and for each of them create // a separate configuration with the stack containing the given state. if (TargetStatesDictionary.ContainsKey(prevSymbol)) { foreach (var targetState in TargetStatesDictionary[prevSymbol]) { result.Add(newllconf.Push(targetState)); } } } else { result.Add(llconf.Pop()); } } return(result); }
// Indexed by beginnings of terminal ranges. public List <KeyValuePair <TSymbol, LlConfiguration <TSymbol> > > OutgoingTerminalEdges(LlConfiguration <TSymbol> llconf) { var topState = llconf.stack[llconf.stack.Count - 1]; var transitions = topState.Transitions; var resultDict = new SortedDictionary <TSymbol, LlConfiguration <TSymbol> > (); foreach (var kv in transitions) { var symbol = kv.Key; var targetState = kv.Value; // topState---symbol-->targetState (we pop topState and push targetState) if (IsTerminal(symbol)) { var newllconf = llconf.Pop(); // a copy without top state newllconf = newllconf.Push(targetState); resultDict.Add(symbol, newllconf); } } var result = new List <KeyValuePair <TSymbol, LlConfiguration <TSymbol> > >(); foreach (var kv in resultDict) { result.Add(kv); } return(result); }