private IEnumerable <IReduceInput <T> > GetTerminalInputsAfterPredicate(INonTerminalPredicate <T> NonTerminal) { ISituationEdge <T> edge; ProcessingQueue <ISituationEdge <T>, IReduceInput <T> > queue; //IInput<T> input; queue = new ProcessingQueue <ISituationEdge <T>, IReduceInput <T> >(); // add edges next to current non terminal edge = GetEdge(NonTerminal); queue.AddRange(edge.TargetNode.Edges); // search for left recursive rules referenced by non terminal foreach (SituationEdge <T> developpedEdge in DevelopRuleInputEdges(NonTerminal.Name)) { // left recursive rule case if ((developpedEdge.Predicate is INonTerminalPredicate <T> recursiveNonTerminal) && (recursiveNonTerminal.Name == NonTerminal.Name)) { queue.AddRange(developpedEdge.TargetNode.Edges); } } // search for loops foreach (SituationEdge <T> developpedEdge in DevelopRuleInputEdges(NonTerminal.Name)) { queue.AddRange(GetLoopedEdges(developpedEdge.TargetNode)); } queue.Process((q, item) => { foreach (IInput <T> input in item.Predicate.GetInputs()) { if (input is IReduceInput <T> terminalInput) { q.AddResult(terminalInput); } //else if (item.Predicate is IReducePredicate<T>) q.AddResult(new EOSInput<T>()); else if (input is INonTerminalInput <T> nonTerminalInput) { q.AddRange(DevelopRuleInputEdges(nonTerminalInput.Name)); } } }); return(queue.Results); }
public ISituationCollection <T> Develop(IEnumerable <ISituation <T> > Situations) { SituationCollection <T> developpedSituations; Situation <T> newSituation; IReduceInput <T>[] inputs; ProcessingQueue <ISituation <T>, ISituation <T> > processingQueue; //bool isReductionSituationAfterPredicate; processingQueue = new ProcessingQueue <ISituation <T>, ISituation <T> >(); processingQueue.AddRange(Situations); processingQueue.Process((q, situation) => { q.AddResult(situation); if (!(situation.Predicate is INonTerminalPredicate <T> nonTerminal)) { return; } //isReductionSituationAfterPredicate = IsReductionStuationAfterPredicate(nonTerminal); inputs = GetTerminalInputsAfterPredicate(nonTerminal).ToArray(); foreach (SituationEdge <T> developpedEdge in DevelopRuleInputEdges(nonTerminal.Name)) { // basic case foreach (IReduceInput <T> input in inputs) { newSituation = new Situation <T>(developpedEdge.Rule, developpedEdge.Predicate, input); q.AddResult(newSituation); } } }); developpedSituations = new SituationCollection <T>(); developpedSituations.AddRange(processingQueue.Results); return(developpedSituations); }