public void TestAdvanceToEndSimpleRegex() { SimpleTestPathRegex regex = new SimpleTestPathRegex("A1B"); IBeforeItemGraphkenState <string, int, Func <string, bool>, Func <int, bool> > initState = regex.CreateState(); Func <Func <string, bool>, string, bool> itemMatch = (f, i) => f(i); Func <Func <int, bool>, int, bool> dependencyMatch = (f, d) => f(d); bool atEnd, atCount; IBeforeDependencyGraphkenState <string, int, Func <string, bool>, Func <int, bool> > stateAfterA = initState.Advance("A", itemMatch, out atEnd, out atCount); Assert.IsTrue(stateAfterA.CanContinue); Assert.IsFalse(atEnd); IBeforeItemGraphkenState <string, int, Func <string, bool>, Func <int, bool> > stateAfter1 = stateAfterA.Advance(1, dependencyMatch, out atCount); Assert.IsTrue(stateAfter1.CanContinue); IBeforeDependencyGraphkenState <string, int, Func <string, bool>, Func <int, bool> > stateAfterB = stateAfter1.Advance("B", itemMatch, out atEnd, out atCount); Assert.IsTrue(stateAfterB.CanContinue); Assert.IsTrue(atEnd); }
private TUpInfo Traverse([NotNull] TItem tail, [NotNull] Dictionary <TItem, TDependency[]> incidentDependencies, IBeforeDependencyGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeDependencyState, TDownInfo rawDown, HashSet <TPathState> statesOnPath) { if (!beforeDependencyState.CanContinue) { throw new ArgumentException("Traverse must be called with continueable state", nameof(beforeDependencyState)); } _checkAbort(); TUpInfo upSum; bool visitSuccessors = ShouldVisitSuccessors(tail, _currentPath, out upSum); if (visitSuccessors) { // We are at this item for the first time - check whether we find a path to some defined end TDependency[] dependencies; if (!incidentDependencies.TryGetValue(tail, out dependencies)) { dependencies = NO_DEPENDENCIES; } foreach (var nextDep in dependencies) { bool dependencyIsCounted; IBeforeItemGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeItemState = beforeDependencyState.Advance(nextDep, (m, d) => m.IsMatch(d), out dependencyIsCounted); if (beforeItemState.CanContinue) { TItem nextTail = nextDep.UsedItem; bool atEnd; bool itemIsCounted; IBeforeDependencyGraphkenState <TItem, TDependency, ItemMatch, DependencyMatch> beforeNextDependencyState = beforeItemState.Advance(nextTail, (m, i) => ItemMatch.IsMatch(m, i), out atEnd, out itemIsCounted); _currentPath.Push(nextDep); CountedEnum counted = dependencyIsCounted ? CountedEnum.DependencyCounted : itemIsCounted ? CountedEnum.UsedItemCounted : CountedEnum.NotCounted; var stateElement = CreateStateElement(beforeNextDependencyState, nextDep); bool newOnPath = statesOnPath.Add(stateElement); DownAndHere downAndHere = AfterPushDependency(_currentPath, atEnd, !newOnPath, counted, rawDown); TUpInfo childUp; if (_currentPath.Count < _maxRecursionDepth && beforeNextDependencyState.CanContinue && newOnPath) { childUp = Traverse(nextTail, incidentDependencies, beforeNextDependencyState, downAndHere.Down, statesOnPath); statesOnPath.Remove(stateElement); } else { childUp = default(TUpInfo); // ??? as above ____ } upSum = BeforePopDependency(_currentPath, atEnd, !newOnPath, counted, rawDown, downAndHere.Save, upSum, childUp); _currentPath.Pop(); } } } upSum = AfterVisitingSuccessors(visitSuccessors, tail, _currentPath, upSum); return(upSum); }