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); }
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); }