Ejemplo n.º 1
0
        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);
        }