private IEnumerable <SituationEdge <T> > DevelopRuleInputEdges(string RuleName) { ProcessingQueue <string, SituationEdge <T> > queue; queue = new ProcessingQueue <string, SituationEdge <T> >(); queue.Add(RuleName); queue.Process((q, ruleName) => { foreach (IRule <T> rule in GetRootNodes(ruleName).Select(item => item.Rule)) { foreach (SituationEdge <T> edge in GetRuleInputEdges(rule)) { q.AddResult(edge); if (!(edge.Predicate is INonTerminalPredicate <T> nonTerminal)) { continue; } q.Add(nonTerminal.Name); } } }); return(queue.Results); }
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); }
public void ShouldProcess() { ProcessingQueue <string, string> queue; string[] results; queue = new ProcessingQueue <string, string>(); for (int t = 0; t < 10; t++) { queue.Add(t.ToString()); } queue.Process((q, item) => { q.Add(item); q.AddResult(item); }); results = queue.Results.ToArray(); Assert.AreEqual(10, results.Length); for (int t = 0; t < 10; t++) { Assert.AreEqual(t.ToString(), results[t]); } }
public void Add(ITerminalRangeInput <T> Range) { ProcessingQueue <ITerminalRangeInput <T>, bool> queue; ITerminalRangeInput <T> existingRange; queue = new ProcessingQueue <ITerminalRangeInput <T>, bool>(); queue.Add(Range); queue.Process((q, range) => { for (int t = 0; t < items.Count; t++) { existingRange = items[t]; if ((range.LastValue.CompareTo(existingRange.FirstValue) < 0) || (range.FirstValue.CompareTo(existingRange.LastValue) > 0)) { continue; } // englobed if ((range.FirstValue.CompareTo(existingRange.FirstValue) >= 0) && (range.LastValue.CompareTo(existingRange.LastValue) <= 0)) { items.RemoveAt(t); if (range.FirstValue.CompareTo(existingRange.FirstValue) > 0) { items.Insert(t, provider.CreateTerminalRangeInput(existingRange.FirstValue, provider.GetPreviousValue(range.FirstValue))); t++; } items.Insert(t, range); t++; if (range.LastValue.CompareTo(existingRange.LastValue) < 0) { items.Insert(t, provider.CreateTerminalRangeInput(provider.GetNextValue(range.LastValue), existingRange.LastValue)); t++; } return; } // englobing if ((range.FirstValue.CompareTo(existingRange.FirstValue) <= 0) && (range.LastValue.CompareTo(existingRange.LastValue) >= 0)) { if (range.FirstValue.CompareTo(existingRange.FirstValue) < 0) { items.Insert(t, provider.CreateTerminalRangeInput(range.FirstValue, provider.GetPreviousValue(existingRange.FirstValue))); } t++; if (range.LastValue.CompareTo(existingRange.LastValue) > 0) { q.Add(provider.CreateTerminalRangeInput(provider.GetNextValue(existingRange.LastValue), range.LastValue)); } return; } // left if (range.FirstValue.CompareTo(existingRange.FirstValue) < 0) { items.RemoveAt(t); items.Insert(t, provider.CreateTerminalRangeInput(range.FirstValue, provider.GetPreviousValue(existingRange.FirstValue))); t++; items.Insert(t, provider.CreateTerminalRangeInput(existingRange.FirstValue, range.LastValue)); t++; items.Insert(t, provider.CreateTerminalRangeInput(provider.GetNextValue(range.LastValue), existingRange.LastValue)); t++; return; } // right if (range.FirstValue.CompareTo(existingRange.FirstValue) > 0) { items.RemoveAt(t); items.Insert(t, provider.CreateTerminalRangeInput(existingRange.FirstValue, provider.GetPreviousValue(range.FirstValue))); t++; items.Insert(t, provider.CreateTerminalRangeInput(range.FirstValue, existingRange.LastValue)); t++; q.Add(provider.CreateTerminalRangeInput(provider.GetNextValue(existingRange.LastValue), range.LastValue)); t++; return; } } items.Add(range); }); }