public SyntacticalDFAState(ControlledDictionary <IOilexerGrammarProductionRuleEntry, SyntacticalDFARootState> lookup, GrammarSymbolSet symbols)
 {
     if (lookup == null)
     {
         throw new ArgumentNullException("lookup");
     }
     this.lookup  = lookup;
     this.symbols = symbols;
 }
Esempio n. 2
0
        /// <summary>
        /// Constructs the initial look-ahead for the transitions.
        /// </summary>
        /// <remarks></remarks>
        public void ConstructInitialLookahead(GrammarSymbolSet grammarSymbols, Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries, Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleVocabulary)
        {
            /* *
             * Left-recursive rules will use the relevant rule
             * paths within their projections within a loop to avoid
             * stack overflow.
             * */

            bool includeRules = this.RootLeaf.Veins.LeftRecursionType != ProductionRuleLeftRecursionType.None;
            var  result       = new ControlledDictionary <GrammarVocabulary, PredictionTree>();

            this.LookAhead = result;
            if (includeRules)
            {
                /* *
                 * On left-recursive rules, the requirements change.
                 * *
                 * The rules must be considered at the start to
                 * ensure that  the left recursive branches
                 * can be switched 'off' to allow for reductions
                 * to function properly.
                 * */

                foreach (var key in this.Veins.Keys)
                {
                    var targets = this.Veins[key];
                    if (targets.Any(k => k.GetRecursionType() != ProductionRuleLeftRecursionType.None && this.RootLeaf == this))
                    {
                        var intersection = key.Intersect(this.Veins.DFAOriginState.OutTransitions.FullCheck);
                        var reducedRules = key.GetRuleVariant().GetSymbols().Select(k => (IGrammarRuleSymbol)k).Select(k => new { Node = fullSeries.GetRuleNodeFromFullSeries(k.Source), Symbol = k }).Where(k => k.Node.HasBeenReduced || k.Node == k.Node.RootLeaf && k.Node.Veins.LeftRecursionType != ProductionRuleLeftRecursionType.None).Select(k => k.Symbol);
                        var ruleVar      = new GrammarVocabulary(key.symbols, reducedRules.ToArray());
                        intersection |= (key.GetTokenVariant() | ruleVar);
                        if (!intersection.IsEmpty)
                        {
                            result._Add(intersection, targets);
                        }
                    }
                    else
                    {
                        DoReductionAware(fullSeries, result, key);
                    }
                }
            }
            else
            {
                foreach (var key in this.Veins.Keys.ToArray())
                {
                    DoReductionAware(fullSeries, result, key);
                }
            }

            /* *
             * Lexical ambiguity handling follows after the full transition table is known.
             * */
            SyntacticAnalysisCore.CreateLexicalAmbiguityTransitions(grammarSymbols, result, null, this, fullSeries, ruleVocabulary);
        }
Esempio n. 3
0
        internal bool CalculateTerminalAmbiguities(
            Dictionary <SyntacticalDFAState, PredictionTreeLeaf> allLeaves,
            ControlledDictionary <IOilexerGrammarProductionRuleEntry, SyntacticalDFARootState> ruleDFAStates,
            Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleLookup,
            GrammarSymbolSet grammarSymbols)
        {
            var ambiguities = ObtainTerminalAmbiguities(allLeaves, ruleDFAStates, ruleLookup, grammarSymbols);

            /* *
             * First step, reduce the ambiguity data provided to us.
             * *
             * This is done here versus in the ObtainTerminalAmbiguities
             * due to the 'research' nature of this process.
             * *
             * It might have to be rewritten or the information added
             * back in.
             * */
            var ambiguityRewrite = (from ambigKeysValue in ambiguities
                                    from reductionTuple in ambigKeysValue.Value
                                    from pathSet in reductionTuple.Item1
                                    select new
            {
                AmbiguousTransition = ambigKeysValue.Keys.Key1,
                TyingPaths = ambigKeysValue.Keys.Key2,
                FollowAmbiguity = new PredictionTreeFollow(pathSet.Item2, this)                        //ConstructInitialFollow(this, ambigKeysValue.Keys.Key1, reductionTuple, allLeaves, ruleDFAStates, ruleLookup),
            }).ToArray();

            foreach (var rewrite in ambiguityRewrite)
            {
                if (rewrite.FollowAmbiguity.InitialPaths.All(initialPath => initialPath.CurrentNode.Veins.DFAOriginState.IsEdge))
                {
                    continue;
                }
                List <PredictionTreeFollow> currentSet;
                if (!this.followAmbiguities.TryGetValue(rewrite.AmbiguousTransition, rewrite.TyingPaths, out currentSet))
                {
                    followAmbiguities.Add(rewrite.AmbiguousTransition, rewrite.TyingPaths, currentSet = new List <PredictionTreeFollow>());
                }
                currentSet.Add(rewrite.FollowAmbiguity);
            }
            return(followAmbiguities.Count > 0);
        }
Esempio n. 4
0
        private void ObtainTerminalAmbiguitiesOnPath(
            PredictionTreeBranch sourceMasterPath,
            Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries,
            ControlledDictionary <IOilexerGrammarProductionRuleEntry, SyntacticalDFARootState> ruleDFAs,
            Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleLookup,
            FiniteAutomataMultiTargetTransitionTable <GrammarVocabulary, Tuple <int, PredictionTreeBranch> > transitionTableResult,
            GrammarSymbolSet grammarSymbols)
        {
            var ambiguousSymbols = grammarSymbols.AmbiguousSymbols.ToList();
            Stack <Tuple <int, PredictionTreeBranch> > toProcess = new Stack <Tuple <int, PredictionTreeBranch> >();
            var fullCheck = this.Veins.Keys.Aggregate(GrammarVocabulary.UnionAggregateDelegate);

            /* * * * * * * * * * * * * * * * * * * * * * * * * *  * *\
             * Kick things off with the master path, this is derived *
             * from the incoming states from the parent rule.        *
             * * * * * * * * * * * * * * * * * * * * * * * * * *  * */
            toProcess.Push(Tuple.Create(0, sourceMasterPath));
            //foreach (var transition in this.Value.Keys)
            //    foreach (var target in this.Value[transition])
            //        toProcess.Push(new PredictionTreeBranch(sourceMasterPath.Take(sourceMasterPath.Depth).Concat(target).ToList(), sourceMasterPath.Depth, true, false, sourceMasterPath.GetDeviationsUpTo(sourceMasterPath.Depth)));
            HashSet <PredictionTreeBranch> seen = new HashSet <PredictionTreeBranch>();

            while (toProcess.Count > 0)
            {
                var currentPathTuple = toProcess.Pop();
                var currentPath      = currentPathTuple.Item2;
                if (currentPath.Depth == 0)
                {
                    continue;
                }
                if (currentPath.CurrentNode.Veins.Keys.Aggregate(GrammarVocabulary.UnionAggregateDelegate).Intersect(fullCheck).IsEmpty)
                {
                    continue;
                }

                /* *
                 * Walk up the tree one level into the state that
                 * follows the current rule in whatever the current
                 * calling rule might be.
                 * */
                var incomingTransitions = currentPath.FollowTransition(fullSeries, ruleLookup[currentPath.CurrentNode.Veins.Rule], ruleLookup, true, false, true, true);

                /* *
                 * Aggregate the transitions from our previously
                 * calculated LL(1) look-ahead information.
                 * */
                /* *
                 * On the state following this rule, gather up the
                 * targets which do overlap one or more of our
                 * transitions.
                 * */
                var fullAmbiguityContext = incomingTransitions.FullCheck | fullCheck;

                var intersectionPoints = (from t in incomingTransitions.Keys
                                          let intersection = t.Intersect(fullCheck)
                                                             where !intersection.IsEmpty
                                                             from path in incomingTransitions[t]
                                                             select new { Intersection = intersection, Path = path }).ToArray();
                var overlap = GrammarVocabulary.NullInst;
                if ((fullAmbiguityContext != null && !fullAmbiguityContext.IsEmpty) && grammarSymbols.IsGrammarPotentiallyAmbiguous(fullAmbiguityContext))
                {
                    foreach (var ambiguity in ambiguousSymbols)
                    {
                        var localIntersect    = fullCheck & ambiguity.AmbiguityKey;
                        var incomingIntersect = incomingTransitions.FullCheck & ambiguity.AmbiguityKey;
                        if (localIntersect.IsEmpty || incomingIntersect.IsEmpty)
                        {
                            /* If the intersection isn't present on one or the other sides; then, for the purposes of
                             * this follow check, the union would not be relevant, it would likely be identified within the
                             * prediction upon the state itself. */
                            continue;
                        }
                        var aggregateIntersect = fullAmbiguityContext & ambiguity.AmbiguityKey;
                        var overlapIntersect   = overlap & ambiguity.AmbiguityKey;
                        if (aggregateIntersect.Equals(ambiguity.AmbiguityKey) && !overlapIntersect.Equals(ambiguity.AmbiguityKey))
                        {
                            /*  */
                            var ambiguityIntersection =
                                (from t in incomingTransitions.Keys
                                 let intersection = t.Intersect(incomingIntersect)
                                                    where !intersection.IsEmpty
                                                    from path in incomingTransitions[t]
                                                    select new { Intersection = intersection, Path = path }).ToArray();
                            var ambiguityVocabulary = new GrammarVocabulary(grammarSymbols, ambiguity);
                            foreach (var intersectingPoint in ambiguityIntersection)
                            {
                                var path         = intersectingPoint.Path;
                                var intersection = localIntersect;
                                if (path.Equals(currentPath))
                                {
                                    continue;
                                }

                                /* Notify the nodes of the ambiguities so their state-machines can be patched up.
                                 * This is done explicitly to avoid the ambiguity cropping up and allowing it everywhere,
                                 * which is incorrect. If it shows up where it's not supposed to, we have a logic error
                                 * somwehere. */
                                foreach (var node in (from ambigPath in PushIntersection(sourceMasterPath, transitionTableResult, toProcess, seen, currentPathTuple, currentPath, path, intersection, ambiguityVocabulary)
                                                      select ambigPath.CurrentNode).Distinct().ToArray())
                                {
                                    node.DenoteLexicalAmbiguity(ambiguity);
                                }
                            }
                            ambiguity.Occurrences++;
                            overlap |= aggregateIntersect;
                        }
                    }
                }
                foreach (var intersectingPoint in intersectionPoints)
                {
                    var path         = intersectingPoint.Path;
                    var intersection = intersectingPoint.Intersection;
                    if (path.Equals(currentPath))
                    {
                        continue;
                    }
                    PushIntersection(sourceMasterPath, transitionTableResult, toProcess, seen, currentPathTuple, currentPath, path, intersection).ToArray();
                }
            }
        }
Esempio n. 5
0
        internal MultikeyedDictionary <GrammarVocabulary, int, List <Tuple <Tuple <int[], PredictionTree>[], int[]> > > ObtainTerminalAmbiguities(
            Dictionary <SyntacticalDFAState, PredictionTreeLeaf> fullSeries,
            ControlledDictionary <IOilexerGrammarProductionRuleEntry, SyntacticalDFARootState> ruleDFAs,
            Dictionary <IOilexerGrammarProductionRuleEntry, GrammarVocabulary> ruleLookup,
            GrammarSymbolSet grammarSymbols)
        {
            if (!this.Veins.DFAOriginState.IsEdge)
            {
                return(new MultikeyedDictionary <GrammarVocabulary, int, List <Tuple <Tuple <int[], PredictionTree>[], int[]> > >());
            }
            var tempDictionary  = new MultikeyedDictionary <PredictionTreeBranch, GrammarVocabulary, Tuple <int[], PredictionTree> >();
            var rootNode        = fullSeries[ruleDFAs[this.Rule]];
            var currentIncoming = new List <PredictionTreeBranch>(rootNode.incoming);
            var reductions      = rootNode.PointsOfReduction.ToArray();

            if (reductions.Length > 0)
            {
            }
            var totalIncoming = new HashSet <PredictionTreeBranch>();
            Dictionary <PredictionTree, PredictionTree> uniqueSet = new Dictionary <PredictionTree, PredictionTree>();

            foreach (var path in currentIncoming)
            {
                var transitionTableResult = new FiniteAutomataMultiTargetTransitionTable <GrammarVocabulary, Tuple <int, PredictionTreeBranch> >();
                var masterPathChop        = new PredictionTreeBranch(path.Take(path.Depth).Concat(new[] { this }).ToArray(), path.Depth, false, false);

                masterPathChop.SetDeviations(path.GetDeviationsUpTo(path.Depth));
                ObtainTerminalAmbiguitiesOnPath(masterPathChop, fullSeries, ruleDFAs, ruleLookup, transitionTableResult, grammarSymbols);

                /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * \
                 * Construct the sequence of Path->Grammar->PathSets based           *
                 * off of the table provided by the ObtainTerminalAmbiguitiesOnPath. *
                 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **/
                foreach (var transition in transitionTableResult.Keys)
                {
                    var epDepthLookup =
                        (from entry in transitionTableResult[transition]
                         group entry.Item1 by entry.Item2).ToDictionary(k => k.Key, v => v.ToArray());
                    //int minDepth;
                    //var uniqueCurrent = GetUniqueDPathSet(uniqueSet, transitionTableResult, transition, epDepthLookup);
                    //var subPath = new PredictionTreeBranch(path.Skip(minDepth).ToList(), path.Depth - minDepth, minDepth: path.MinDepth);
                    tempDictionary.TryAdd(path, transition, Tuple.Create((from epDepth in transitionTableResult[transition]
                                                                          select epDepth.Item1).ToArray(), GetFollowDPathSet(transitionTableResult, transition, epDepthLookup)));
                }
            }



            var regrouping = (from ksvp in tempDictionary
                              group new { Path = ksvp.Keys.Key1, Set = ksvp.Value } by ksvp.Keys.Key2).ToDictionary(k => k.Key, v => v.ToArray());

            /*
             * foreach (var pathSet in from key in regrouping.Keys
             *                      let value = regrouping[key]
             *                      from r in value
             *                      select r.Set)
             *  pathSet.Item2.FixAllPaths();//*/

            var comparisons = (from key in regrouping.Keys
                               let value = regrouping[key]
                                           let kRewrite = from r in value
                                                          select r.Set
                                                          let commonalities = PredictionTree.GetCompoundRightSideSimilarities(kRewrite)
                                                                              select new { Commonalities = commonalities, Transition = key }).ToDictionary(k => k.Transition, v => v.Commonalities);
            var resultDictionary = new MultikeyedDictionary <GrammarVocabulary, int, List <Tuple <Tuple <int[], PredictionTree>[], int[]> > >();

            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * \
             * Once we're done, we need to rebuild the paths with the MinDepth set to  *
             * their current Depth.  This is to ensure that it the PathSets don't try  *
             * to reduce more than necessary.                                          *
             * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
             * Then we take that set and perform a right-hand-side comparison between  *
             * the elements.                                                           *
             * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
             * This will be used later to reduce the walking necessary to isolate the  *
             * proper machine to use to disambiguate the look-ahead.                   *
             \ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **/
            foreach (var comparison in comparisons.Keys)
            {
                var comparisonElements = comparisons[comparison];
                foreach (var memberCount in comparisonElements.Keys)
                {
                    var comparisonElement = comparisonElements[memberCount];
                    resultDictionary.Add(comparison, memberCount, comparisonElement);
                }
            }
            return(resultDictionary);
        }
 public SyntacticalDFARootState(IOilexerGrammarProductionRuleEntry entry, ControlledDictionary <IOilexerGrammarProductionRuleEntry, SyntacticalDFARootState> lookup, GrammarSymbolSet symbols)
     : base(lookup, symbols)
 {
     this.entry = entry;
 }
Esempio n. 7
0
 public GrammarSymbolComparer(GrammarSymbolSet grammarSymbols)
 {
     this._grammarSymbols = grammarSymbols;
 }
Esempio n. 8
0
 public SyntacticalNFAState(ControlledDictionary <IOilexerGrammarProductionRuleEntry, SyntacticalDFARootState> lookup, GrammarSymbolSet symbols)
 {
     this.lookup  = lookup;
     this.symbols = symbols;
 }