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)); } }
internal PredictionTreeBranch GetTransitionPath(PredictionTreeBranch targetPath, PredictionTreeLeaf[] previousNodes, PredictionTreeBranch currentSubPath, Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleLookup, bool usePrevious, bool isEpsilonTransition = false, bool incrementDeviations = true) { var currentNode = currentSubPath[0]; if (previousNodes.Length > 0) { Debug.Assert(previousNodes[previousNodes.Length - 1].Veins.DFAOriginState.OutTransitions.Keys.Any(k => !k.Intersect(ruleLookup[currentNode.Rule]).IsEmpty)); } short[] deviations = incrementDeviations ? targetPath.IncrementDeviations(previousNodes.Length, isEpsilonTransition) : targetPath.GetDeviationsUpTo(previousNodes.Length); var result = new PredictionTreeBranch(previousNodes.Concat(currentSubPath).ToArray(), targetPath.Depth + currentSubPath.Depth, passAlong: false, deviations: deviations); result.MinDepth = targetPath.MinDepth; return(result); }