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); }
public bool Subsumes(LlConfiguration <TSymbol> configuration) { if ((this.label.CompareTo(configuration.label) != 0) || this.stack.Count > configuration.Count()) { return(false); } var firstStack = this.stack; var secondStack = configuration.stack; for (int i = 0; i < firstStack.Count; i++) { if (firstStack [firstStack.Count - i - 1] != secondStack[secondStack.Count - i - 1]) { return(false); } } return(true); }
public bool Equals(LlConfiguration <TSymbol> other) { return(this.Subsumes(other) && other.Subsumes(this)); }
// 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); }