コード例 #1
0
        public ProductionRuleLeftRecursionType GetRecursionType()
        {
            if (this.Count == 0)
            {
                return(ProductionRuleLeftRecursionType.None);
            }
            var first = this[0];

            if (!first.Veins.IsRuleEntryPoint)
            {
                return(ProductionRuleLeftRecursionType.None);
            }

            /* *
             * Iterate through the sequence, if we encounter
             * one which points to the same rule node, we have
             * a left-recursive cycle.
             * *
             * ToDo: Add case to handle epsilon transitions which
             * cause left-recursion. AKA: Hidden Left Recursion.
             * */
            ProductionRuleLeftRecursionType result = ProductionRuleLeftRecursionType.None;

            for (int i = 1; i < this.Count; i++)
            {
                var currentNode = this[i];
                if (!currentNode.Veins.IsRuleEntryPoint && !(this.IsEpsilonDerived(i) && currentNode.RootLeaf == first))
                {
                    return(result);
                }
                if (currentNode == first || this.IsEpsilonDerived(i) && currentNode.RootLeaf == first)
                {
                    result |= (i == 1 ? ProductionRuleLeftRecursionType.Direct : ProductionRuleLeftRecursionType.Indirect);
                }
            }
            return(result);
        }
コード例 #2
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);
        }