Exemplo n.º 1
0
        public IPredictionTreeDestination SetDecisionFor(GrammarVocabulary rootTransitionKey, PredictionTreeLeaf targetStateNode)
        {
            Debug.Assert(rootTransitionKey != null, "Error, the root transition key to make a decision was invalid!");
            IPredictionTreeDestination result;

            if (targetStateNode != null)
            {
                if (!this.decisionTree.TryGetValue(rootTransitionKey, targetStateNode, out result))
                {
                    this.decisionTree.Add(rootTransitionKey, targetStateNode, result = new PredictionTreeDestination()
                    {
                        DecidingFactor = rootTransitionKey, Target = targetStateNode
                    });
                }
            }
            else
            {
                if (!this.followFailures.TryGetValue(rootTransitionKey, out result))
                {
                    this.followFailures.Add(rootTransitionKey, result = new PredictionTreeFollowCaller(this)
                    {
                        DecidingFactor = rootTransitionKey
                    });
                }
            }
            return(result);
        }
Exemplo n.º 2
0
        FollowTransition(
            Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries,
            GrammarVocabulary transitionKey,
            Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleLookup,
            bool usePrevious,
            bool injectIncomingPaths,
            bool includeRootEdges    = false,
            bool isEpsilonTransition = false,
            bool silentlyFail        = false,
            bool isReduction         = false)
        {
            var resultData = from u in FollowTransitionInternal(fullSeries, transitionKey, ruleLookup, usePrevious, isEpsilonTransition, silentlyFail, isReduction)
                             group u.Item2 by u.Item1;
            FiniteAutomataMultiTargetTransitionTable <GrammarVocabulary, PredictionTreeBranch> result = new FiniteAutomataMultiTargetTransitionTable <GrammarVocabulary, PredictionTreeBranch>();

            foreach (var element in resultData)
            {
                if (element.Key.IsEmpty)
                {
                    result.SetAutoSegment(false);
                }
                result.Add(element.Key, element.ToList());
                if (element.Key.IsEmpty)
                {
                    result.SetAutoSegment(true);
                }
            }
            return(result);
        }
Exemplo n.º 3
0
 public TransitionRequest(GrammarVocabulary transition, PredictionTreeBranch path, bool usePrevious, bool isReduction)
 {
     this.path = path;
     this.transitionRequirement = transition;
     this.usePrevious           = usePrevious;
     this.isReduction           = isReduction;
 }
Exemplo n.º 4
0
        /// <summary>
        /// Constructs the initial look-ahead for the transitions.
        /// </summary>
        /// <remarks></remarks>
        public void ConstructInitialLookahead(GrammarSymbolSet grammarSymbols, Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries, Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleVocabulary)
        {
            /* *
             * Left-recursive rules will use the relevant rule
             * paths within their projections within a loop to avoid
             * stack overflow.
             * */

            bool includeRules = this.RootLeaf.Veins.LeftRecursionType != ProductionRuleLeftRecursionType.None;
            var  result       = new ControlledDictionary <GrammarVocabulary, PredictionTree>();

            this.LookAhead = result;
            if (includeRules)
            {
                /* *
                 * On left-recursive rules, the requirements change.
                 * *
                 * The rules must be considered at the start to
                 * ensure that  the left recursive branches
                 * can be switched 'off' to allow for reductions
                 * to function properly.
                 * */

                foreach (var key in this.Veins.Keys)
                {
                    var targets = this.Veins[key];
                    if (targets.Any(k => k.GetRecursionType() != ProductionRuleLeftRecursionType.None && this.RootLeaf == this))
                    {
                        var intersection = key.Intersect(this.Veins.DFAOriginState.OutTransitions.FullCheck);
                        var reducedRules = key.GetRuleVariant().GetSymbols().Select(k => (IGrammarRuleSymbol)k).Select(k => new { Node = fullSeries.GetRuleNodeFromFullSeries(k.Source), Symbol = k }).Where(k => k.Node.HasBeenReduced || k.Node == k.Node.RootLeaf && k.Node.Veins.LeftRecursionType != ProductionRuleLeftRecursionType.None).Select(k => k.Symbol);
                        var ruleVar      = new GrammarVocabulary(key.symbols, reducedRules.ToArray());
                        intersection |= (key.GetTokenVariant() | ruleVar);
                        if (!intersection.IsEmpty)
                        {
                            result._Add(intersection, targets);
                        }
                    }
                    else
                    {
                        DoReductionAware(fullSeries, result, key);
                    }
                }
            }
            else
            {
                foreach (var key in this.Veins.Keys.ToArray())
                {
                    DoReductionAware(fullSeries, result, key);
                }
            }

            /* *
             * Lexical ambiguity handling follows after the full transition table is known.
             * */
            SyntacticAnalysisCore.CreateLexicalAmbiguityTransitions(grammarSymbols, result, null, this, fullSeries, ruleVocabulary);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Returns whether the <see cref="CurrentNode"/>'s States Transition Table
 /// collides with the <paramref name="collider"/> provided.
 /// </summary>
 /// <param name="collider">The <see cref="GrammarVocabulary"/>
 /// to check for collisions with.</param>
 /// <returns>true, if the <paramref name="collider"/> collides with the
 /// transition table.</returns>
 public bool CollidesWith(GrammarVocabulary collider)
 {
     if (this.CurrentNode == null ||
         collider == null ||
         collider.IsEmpty)
     {
         return(false);
     }
     return(!this.CurrentNode.Veins.DFAOriginState.OutTransitions.FullCheck.Intersect(collider).IsEmpty);
 }
Exemplo n.º 6
0
        private static TransitionRequest GetTransitionRequest(GrammarVocabulary transition, PredictionTreeBranch path, bool usePrevious, bool isReduction)
        {
            List <TransitionRequest> result;
            var fKey = Tuple.Create(usePrevious, isReduction);

            lock (transitionRequests)
                if (transitionRequests.TryGetValue(fKey, transition, path, out result))
                {
                    lock (result)
                        return(result.FirstOrDefault(p => p.DeviationDetail.SequenceEqual(path.deviations)));
                }
            return(null);
        }
Exemplo n.º 7
0
        private static IEnumerable <PredictionTreeBranch> PushIntersection(
            PredictionTreeBranch sourceMasterPath,
            FiniteAutomataMultiTargetTransitionTable <GrammarVocabulary, Tuple <int, PredictionTreeBranch> > transitionTableResult,
            Stack <Tuple <int, PredictionTreeBranch> > toProcess,
            HashSet <PredictionTreeBranch> seen,
            Tuple <int, PredictionTreeBranch> currentPathTuple,
            PredictionTreeBranch currentPath,
            PredictionTreeBranch path,
            GrammarVocabulary intersection,
            GrammarVocabulary transitionKey = null)
        {
            /* * * * * * * * * * * * * * * * * * * * * * * * * *\
             * Construct the transition table with the matching *
             * paths.                                           *
             * * * * * * * * * * * * * * * * * * * * * * * * * */
            var intersectingCurrent = from key in currentPath.CurrentNode.Veins.Keys
                                      let intersect = key.Intersect(intersection)
                                                      where !intersect.IsEmpty
                                                      let subPathSet = currentPath.CurrentNode.Veins[key]
                                                                       from subPath in subPathSet.UnalteredOriginals
                                                                       let rPath = new PredictionTreeBranch(sourceMasterPath.Take(currentPath.Depth).Concat(subPath).ToList(), currentPath.Depth + subPath.Depth, true, false, currentPath.GetDeviationsUpTo(currentPath.Depth), minDepth: currentPath.Depth)
                                                                                   where rPath.Valid
                                                                                   select rPath;
            var set = new List <Tuple <int, PredictionTreeBranch> >(from ip in intersectingCurrent
                                                                    select Tuple.Create(currentPathTuple.Item1, ip))
            {
                Tuple.Create(currentPathTuple.Item1 + 1, new PredictionTreeBranch(path.baseList, path.Depth, false, false, minDepth: path.Depth))
            };
            var distinctNodeArray = (from element in set
                                     select element.Item2).Distinct().ToArray();

            foreach (var element in distinctNodeArray)
            {
                yield return(element);
            }
            transitionTableResult.Add(transitionKey ?? intersection, set);

            /* * * * * * * * * * * * * * * * * * * * * * * * * * * *\
             * If the current point is an edge, walk further        *
             * up the parse tree to see what else lies in store.    *
             * * * * * * * * * * * * * * * * * * * * * * * * * * * **
             * Further ambiguities might result in additional look- *
             * ahead being necessary.                               *
             * * * * * * * * * * * * * * * * * * * * * * * * * * * */
            if (seen.Add(path) && path.CurrentNode.Veins.DFAOriginState.IsEdge)
            {
                toProcess.Push(Tuple.Create(currentPathTuple.Item1 + 1, path));
            }
        }
Exemplo n.º 8
0
        public ProductionRuleProjectionReduction SetReductionOn(GrammarVocabulary reducedRule, int deviationLevel, Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries)
        {
            Debug.Assert(reducedRule != null, "Error, the root transition key to make a reduction was invalid!");
            var vocabSymbol     = reducedRule.GetSymbols()[0];
            var ruleVocabSymbol = vocabSymbol as IGrammarRuleSymbol;

            if (ruleVocabSymbol != null)
            {
                var rootNode = fullSeries.GetRuleNodeFromFullSeries(ruleVocabSymbol.Source);
                if (!rootNode.HasBeenReduced)
                {
                    rootNode.HasBeenReduced = true;
                }
            }
            return(new ProductionRuleProjectionReduction()
            {
                ReducedRule = reducedRule, LookAheadDepth = deviationLevel, Rule = this.RootLeaf.Rule
            });
        }
Exemplo n.º 9
0
        private void DoReductionAware(Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries, ControlledDictionary <GrammarVocabulary, PredictionTree> result, GrammarVocabulary key)
        {
            var tokenVar     = key.GetTokenVariant();
            var reducedRules =
                key
                .GetRuleVariant()
                .GetSymbols()
                .Select(k => (IGrammarRuleSymbol)k)
                .Select(k => new { Node = fullSeries.GetRuleNodeFromFullSeries(k.Source), Symbol = k })
                .Where(k => k.Node.HasBeenReduced).Select(k => k.Symbol);// || k.Node == k.Node.RootLeaf && k.Node.Value.LeftRecursionType != ProductionRuleLeftRecursionType.None && this == this.RootLeaf
            var ruleVar = new GrammarVocabulary(key.symbols, reducedRules.ToArray());

            if (!tokenVar.IsEmpty)
            {
                result._Add(tokenVar, this.Veins[key]);
            }
            if (!ruleVar.IsEmpty)
            {
                result._Add(ruleVar, this.Veins[key]);
            }
        }
Exemplo n.º 10
0
        private static TransitionRequest PushTransitionRequest(GrammarVocabulary transition, PredictionTreeBranch path, bool usePrevious, bool isReduction)
        {
            var fKey = Tuple.Create(usePrevious, isReduction);

            lock (transitionRequests)
            {
                List <TransitionRequest> resultSet;
                if (!transitionRequests.TryGetValue(fKey, transition, path, out resultSet))
                {
                    transitionRequests.Add(fKey, transition, path, resultSet = new List <TransitionRequest>());
                }
                lock (resultSet)
                {
                    TransitionRequest result = resultSet.FirstOrDefault(p => p.DeviationDetail.SequenceEqual(path.deviations));
                    if (result == null)
                    {
                        resultSet.Add(result = new TransitionRequest(transition, path, usePrevious, isReduction));
                    }
                    return(result);
                }
            }
        }
Exemplo n.º 11
0
        private void ObtainTerminalAmbiguitiesOnPath(
            PredictionTreeBranch sourceMasterPath,
            Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries,
            ControlledDictionary <IOilexerGrammarProductionRuleEntry, SyntacticalDFARootState> ruleDFAs,
            Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleLookup,
            FiniteAutomataMultiTargetTransitionTable <GrammarVocabulary, Tuple <int, PredictionTreeBranch> > transitionTableResult,
            GrammarSymbolSet grammarSymbols)
        {
            var ambiguousSymbols = grammarSymbols.AmbiguousSymbols.ToList();
            Stack <Tuple <int, PredictionTreeBranch> > toProcess = new Stack <Tuple <int, PredictionTreeBranch> >();
            var fullCheck = this.Veins.Keys.Aggregate(GrammarVocabulary.UnionAggregateDelegate);

            /* * * * * * * * * * * * * * * * * * * * * * * * * *  * *\
             * Kick things off with the master path, this is derived *
             * from the incoming states from the parent rule.        *
             * * * * * * * * * * * * * * * * * * * * * * * * * *  * */
            toProcess.Push(Tuple.Create(0, sourceMasterPath));
            //foreach (var transition in this.Value.Keys)
            //    foreach (var target in this.Value[transition])
            //        toProcess.Push(new PredictionTreeBranch(sourceMasterPath.Take(sourceMasterPath.Depth).Concat(target).ToList(), sourceMasterPath.Depth, true, false, sourceMasterPath.GetDeviationsUpTo(sourceMasterPath.Depth)));
            HashSet <PredictionTreeBranch> seen = new HashSet <PredictionTreeBranch>();

            while (toProcess.Count > 0)
            {
                var currentPathTuple = toProcess.Pop();
                var currentPath      = currentPathTuple.Item2;
                if (currentPath.Depth == 0)
                {
                    continue;
                }
                if (currentPath.CurrentNode.Veins.Keys.Aggregate(GrammarVocabulary.UnionAggregateDelegate).Intersect(fullCheck).IsEmpty)
                {
                    continue;
                }

                /* *
                 * Walk up the tree one level into the state that
                 * follows the current rule in whatever the current
                 * calling rule might be.
                 * */
                var incomingTransitions = currentPath.FollowTransition(fullSeries, ruleLookup[currentPath.CurrentNode.Veins.Rule], ruleLookup, true, false, true, true);

                /* *
                 * Aggregate the transitions from our previously
                 * calculated LL(1) look-ahead information.
                 * */
                /* *
                 * On the state following this rule, gather up the
                 * targets which do overlap one or more of our
                 * transitions.
                 * */
                var fullAmbiguityContext = incomingTransitions.FullCheck | fullCheck;

                var intersectionPoints = (from t in incomingTransitions.Keys
                                          let intersection = t.Intersect(fullCheck)
                                                             where !intersection.IsEmpty
                                                             from path in incomingTransitions[t]
                                                             select new { Intersection = intersection, Path = path }).ToArray();
                var overlap = GrammarVocabulary.NullInst;
                if ((fullAmbiguityContext != null && !fullAmbiguityContext.IsEmpty) && grammarSymbols.IsGrammarPotentiallyAmbiguous(fullAmbiguityContext))
                {
                    foreach (var ambiguity in ambiguousSymbols)
                    {
                        var localIntersect    = fullCheck & ambiguity.AmbiguityKey;
                        var incomingIntersect = incomingTransitions.FullCheck & ambiguity.AmbiguityKey;
                        if (localIntersect.IsEmpty || incomingIntersect.IsEmpty)
                        {
                            /* If the intersection isn't present on one or the other sides; then, for the purposes of
                             * this follow check, the union would not be relevant, it would likely be identified within the
                             * prediction upon the state itself. */
                            continue;
                        }
                        var aggregateIntersect = fullAmbiguityContext & ambiguity.AmbiguityKey;
                        var overlapIntersect   = overlap & ambiguity.AmbiguityKey;
                        if (aggregateIntersect.Equals(ambiguity.AmbiguityKey) && !overlapIntersect.Equals(ambiguity.AmbiguityKey))
                        {
                            /*  */
                            var ambiguityIntersection =
                                (from t in incomingTransitions.Keys
                                 let intersection = t.Intersect(incomingIntersect)
                                                    where !intersection.IsEmpty
                                                    from path in incomingTransitions[t]
                                                    select new { Intersection = intersection, Path = path }).ToArray();
                            var ambiguityVocabulary = new GrammarVocabulary(grammarSymbols, ambiguity);
                            foreach (var intersectingPoint in ambiguityIntersection)
                            {
                                var path         = intersectingPoint.Path;
                                var intersection = localIntersect;
                                if (path.Equals(currentPath))
                                {
                                    continue;
                                }

                                /* Notify the nodes of the ambiguities so their state-machines can be patched up.
                                 * This is done explicitly to avoid the ambiguity cropping up and allowing it everywhere,
                                 * which is incorrect. If it shows up where it's not supposed to, we have a logic error
                                 * somwehere. */
                                foreach (var node in (from ambigPath in PushIntersection(sourceMasterPath, transitionTableResult, toProcess, seen, currentPathTuple, currentPath, path, intersection, ambiguityVocabulary)
                                                      select ambigPath.CurrentNode).Distinct().ToArray())
                                {
                                    node.DenoteLexicalAmbiguity(ambiguity);
                                }
                            }
                            ambiguity.Occurrences++;
                            overlap |= aggregateIntersect;
                        }
                    }
                }
                foreach (var intersectingPoint in intersectionPoints)
                {
                    var path         = intersectingPoint.Path;
                    var intersection = intersectingPoint.Intersection;
                    if (path.Equals(currentPath))
                    {
                        continue;
                    }
                    PushIntersection(sourceMasterPath, transitionTableResult, toProcess, seen, currentPathTuple, currentPath, path, intersection).ToArray();
                }
            }
        }
Exemplo n.º 12
0
        private PredictionTree GetFollowDPathSet(FiniteAutomataMultiTargetTransitionTable <GrammarVocabulary, Tuple <int, PredictionTreeBranch> > transitionTableResult, GrammarVocabulary transition, Dictionary <PredictionTreeBranch, int[]> epDepthLookup)
        {
            //var minMinDepth = (from deviationPath in transitionTableResult[transition]
            //                   select deviationPath.Item2.MinDepth).Min();
            //minDepth = minMinDepth;
            //epDepthLookup = epDepthLookup.ToDictionary(dps => new PredictionTreeBranch(dps.Key.Skip(minMinDepth).ToList(), dps.Key.Depth - minMinDepth, minDepth: dps.Key.MinDepth - minMinDepth), dps => dps.Value);
            var result = PredictionTree.GetPathSet(transition, epDepthLookup.Keys.ToList(), this, ProductionRuleProjectionType.FollowAmbiguity, PredictionDerivedFrom.LookAhead_FollowPrediction);

            result.SetFollowEpsilonData(provider => epDepthLookup[provider]);
            return(result);
        }
Exemplo n.º 13
0
        FollowTransitionInternal(
            Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries,
            GrammarVocabulary transitionKey,
            Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleLookup,
            bool usePrevious,
            bool isEpsilonTransition = false,
            bool silentlyFail        = false,
            bool isReduction         = false)
        {
            if (transitionKey.IsEmpty)
            {
                return(new Tuple <GrammarVocabulary, PredictionTreeBranch> [0]);
            }


            List <Tuple <GrammarVocabulary, PredictionTreeBranch> > result = new List <Tuple <GrammarVocabulary, PredictionTreeBranch> >();

            /* *
             * The transition was broken up earlier to yield
             * subsets that overlapped on a portion of the
             * transition.
             * */
            var ambiguityVocabulary = transitionKey.DisambiguateVocabulary();

            short[] deviationsToPass = this.deviations;
            if (isReduction)
            {
                deviationsToPass = this.IncrementDeviations(this.Depth, false);
            }
            var targetPath = usePrevious ? this.Depth == this.MinDepth && this.Depth > 0 ? new PredictionTreeBranch(this.baseList, this.Depth - 1, false, false, deviationsToPass, this.epsilonDerivations, this.MinDepth - 1) : this.DecreaseDepth(false) : this;

            if (isReduction)
            {
                targetPath = new PredictionTreeBranch(targetPath.baseList, targetPath.Depth, false, false, deviationsToPass, this.epsilonDerivations, targetPath.MinDepth);
            }
            var fullTransitionKey = targetPath.CurrentNode.Veins.DFAOriginState.OutTransitions.Keys.FirstOrDefault(v => !v.Intersect(transitionKey.DisambiguateVocabulary()).IsEmpty);
            var cachedRequest     = GetTransitionRequest(transitionKey, targetPath, usePrevious, isReduction);

            if (cachedRequest != null)
            {
                return(cachedRequest.Detail);
            }
            if (fullTransitionKey == null && !silentlyFail)
            {
                Debug.Assert(fullTransitionKey != null);
            }
            else if (fullTransitionKey == null && silentlyFail)
            {
                return(result);
            }
            var targetOfTransition = targetPath.CurrentNode.Veins.DFAOriginState.OutTransitions[fullTransitionKey];

            var targetNodeOfTransition = fullSeries[targetOfTransition];

            PredictionTreeLeaf[] previousNodes = null;
            if (targetPath.Depth > 0)
            {
                previousNodes = targetPath.Take(targetPath.Depth).ToArray();
            }
            else
            {
                previousNodes = new PredictionTreeLeaf[0];
            }
            if (targetNodeOfTransition.Veins.Keys.Count > 0)
            {
                foreach (var key in targetNodeOfTransition.Veins.Keys)
                {
                    var tokenVar     = key.GetTokenVariant();
                    var originalSet  = key.GetRuleVariant().GetSymbols().Select(k => (IGrammarRuleSymbol)k).Select(k => new { Node = fullSeries.GetRuleNodeFromFullSeries(k.Source), Symbol = k }).Where(k => k.Node.HasBeenReduced).ToArray();
                    var reducedRules = originalSet.Where(k => NodeIsRelevantToThis(k.Node, targetNodeOfTransition)).Select(k => k.Symbol).ToArray();
                    var ruleVar      = new GrammarVocabulary(key.symbols, reducedRules);
                    foreach (var path in targetNodeOfTransition.Veins[key].UnalteredOriginals)
                    {
                        var currentSubPath = path;

                        /* *
                         * The transition is derived from the parent node's transitions because the current node is omittable.
                         * */
                        while (!currentSubPath.CurrentNode.Veins.Keys.Any(k => !k.Intersect(key).IsEmpty) && currentSubPath.Depth > 0)
                        {
                            currentSubPath = currentSubPath.DecreaseDepth(false);
                        }
                        if (!tokenVar.IsEmpty)
                        {
                            result.Add(Tuple.Create(tokenVar, GetTransitionPath(targetPath, previousNodes, currentSubPath, ruleLookup, usePrevious, isEpsilonTransition)));
                        }
                        if (!ruleVar.IsEmpty)
                        {
                            result.Add(Tuple.Create(ruleVar, GetTransitionPath(targetPath, previousNodes, currentSubPath, ruleLookup, usePrevious, isEpsilonTransition)));
                        }
                    }
                }
                if (targetOfTransition.IsEdge)
                {
                    HandleLeftRecursiveInjection(fullSeries, ruleLookup, usePrevious, isEpsilonTransition, silentlyFail, result, targetPath, targetNodeOfTransition, previousNodes);
                    var result2 = result.ToArray().ToList();
                    if (previousNodes.Length > 0)
                    {
                        result.AddRange(GetTransitionPath(targetPath, previousNodes, targetNodeOfTransition, ruleLookup, usePrevious, isEpsilonTransition, false).FollowTransitionInternal(fullSeries, ruleLookup[targetNodeOfTransition.Veins.Rule], ruleLookup, true, isEpsilonTransition: isEpsilonTransition));
                    }
                    else
                    {
                        result.Add(Tuple.Create(GrammarVocabulary.NullInst, new PredictionTreeBranch(new[] { targetNodeOfTransition }, passAlong: false)));
                    }
                }
            }
            else if (targetOfTransition.IsEdge && previousNodes.Length > 0)
            {
                HandleLeftRecursiveInjection(fullSeries, ruleLookup, usePrevious, isEpsilonTransition, silentlyFail, result, targetPath, targetNodeOfTransition, previousNodes);
                result.AddRange(targetPath.FollowTransitionInternal(fullSeries, ruleLookup[targetNodeOfTransition.Veins.Rule], ruleLookup, true, isEpsilonTransition: isEpsilonTransition));
            }
            else if (targetOfTransition.IsEdge && previousNodes.Length == 0 /* && includeRootEdges*/)
            {
                result.Add(Tuple.Create(GrammarVocabulary.NullInst, new PredictionTreeBranch(new[] { targetNodeOfTransition }, passAlong: false)));
            }
            var transitionDetail = PushTransitionRequest(transitionKey, targetPath, usePrevious, isReduction);

            if (transitionDetail.Detail == null)
            {
                transitionDetail.Detail = result;
            }
            return(result);
        }