예제 #1
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);
        }
예제 #2
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));
            }
        }
예제 #3
0
        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);
        }