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); }
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)); } }
public bool ConstructEpsilonLookAheadProjection(Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries, Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleVocabulary, int cycleDepth) { if (cycleDepth > 1) { this.cyclePaths[cycleDepth - 2].Clear(); } var currentCycle = this.cyclePaths[cycleDepth - 1]; bool result = false; FiniteAutomataMultiTargetTransitionTable <GrammarVocabulary, PredictionTreeBranch> resultTable = new FiniteAutomataMultiTargetTransitionTable <GrammarVocabulary, PredictionTreeBranch>(); var previousLeftRecursive = leftRecursionType; if (leftRecursionType == ProductionRuleLeftRecursionType.None) { var temp = (from p in currentCycle where p.Depth == 0 select p.GetRecursionType()).Aggregate(PredictionTreeBranch.LeftRecursionAggregateDelegate); if (leftRecursionType != (leftRecursionType | temp)) { leftRecursionType = temp; } } if (previousLeftRecursive != leftRecursionType) { result = true; } var transitionalPaths = (from p in currentCycle from ePath in p.ObtainEpsilonTransitions(fullSeries) select ePath).ToArray(); foreach (var transitionalPath in transitionalPaths) { if (!currentCycle.Contains(transitionalPath)) { currentCycle.Add(transitionalPath); var leftRecursionChange = (from path in currentCycle select path.GetRecursionType()).Aggregate(PredictionTreeBranch.LeftRecursionAggregateDelegate); } } var leftRecursivePaths = (from p in currentCycle where p.Depth == 0 let recurType = p.GetRecursionType() where recurType != ProductionRuleLeftRecursionType.None select p.GetFirstRecursion()).ToArray(); foreach (var path in currentCycle) { /* * * Use a transition table to sort out ambiguities. * */ foreach (var transition in path.CurrentNode.Veins.DFAOriginState.OutTransitions.Keys) { if (leftRecursionType == ProductionRuleLeftRecursionType.None) { //var tokVariant = transition.GetTokenVariant(); var tokenVar = transition.GetTokenVariant(); var reducedRules = transition.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); var ruleVar = new GrammarVocabulary(transition.symbols, reducedRules.ToArray()); if (!tokenVar.IsEmpty) { resultTable.Add(tokenVar, new List <PredictionTreeBranch>() { path }); } if (!ruleVar.IsEmpty) { resultTable.Add(ruleVar, new List <PredictionTreeBranch>() { path }); } } else { var currentSet = new List <PredictionTreeBranch>() { path }; //if (this.Rule.Name == "RelationalExp") //{ // if (transition.ToString() == "Identifier") // { foreach (var lrPath in leftRecursivePaths) { currentSet.Add(lrPath.GetTransitionPath(lrPath, lrPath.Take(lrPath.Depth).ToArray(), path, ruleVocabulary, false, false, false)); } // } //} resultTable.Add(transition, currentSet); } } } int currentCount = this.Count; if (currentCount != resultTable.Count) { result = true; if (this.Count > 0) { this._Clear(); } foreach (var transition in resultTable.Keys) { var pathSet = PredictionTree.GetPathSet(transition, resultTable[transition], this.Leaf, ProductionRuleProjectionType.LookAhead, PredictionDerivedFrom.Lookahead_Epsilon); this._Add(transition, pathSet); pathSet.CheckReductionState(fullSeries, ruleVocabulary); //pathSet.ProcessCommonSymbol(fullSeries, ruleVocabulary); } } return(result); }