示例#1
0
        private void LeoReductionOperation(int iLoc, CachedStateFrameTransition fromLim)
        {
            var fromAH    = fromLim.Frame;
            var transSym  = fromLim.Symbol;
            var originLoc = fromLim.Origin;

            var toAH = Goto(fromAH, transSym);

            if (toAH == null)
            {
                return;
            }

            AddEimPair(iLoc, toAH, originLoc);
        }
示例#2
0
        private void MemoizeTransitions(int iLoc)
        {
            var frameSet = Chart.FrameSets[iLoc];
            // leo eligibility needs to be cached before creating the cached transition
            // if the size of the list is != 1, do not enter the cached frame transition
            var cachedTransitionsPool = SharedPools.Default <Dictionary <ISymbol, CachedStateFrameTransition> >();
            var cachedTransitions     = cachedTransitionsPool.AllocateAndClear();
            var cachedCountPool       = SharedPools.Default <Dictionary <ISymbol, int> >();
            var cachedCount           = cachedCountPool.AllocateAndClear();

            for (var i = 0; i < frameSet.Frames.Count; i++)
            {
                var stateFrame = frameSet.Frames[i];
                for (var j = 0; j < stateFrame.Frame.Data.Count; j++)
                {
                    var preComputedState = stateFrame.Frame.Data[j];
                    if (IsCompleted(preComputedState))
                    {
                        continue;
                    }

                    var postDotSymbol = GetPostDotSymbol(preComputedState);
                    if (postDotSymbol.SymbolType != SymbolType.NonTerminal)
                    {
                        continue;
                    }

                    // leo eligibile items are right recursive directly or indirectly
                    if (!_preComputedGrammar.IsRightRecursive(
                            preComputedState.Production.LeftHandSide))
                    {
                        continue;
                    }

                    // to determine if the item is leo unique, cache it here
                    var count = 0;
                    if (!cachedCount.TryGetValue(postDotSymbol, out count))
                    {
                        cachedCount[postDotSymbol] = 1;

                        var origin = stateFrame.Origin;
                        CachedStateFrameTransition topCacheItem = null;
                        while (true)
                        {
                            var originFrameSet = Chart.FrameSets[stateFrame.Origin];
                            var nextCachedItem = originFrameSet.FindCachedStateFrameTransition(postDotSymbol);
                            if (nextCachedItem == null)
                            {
                                break;
                            }
                            topCacheItem = nextCachedItem;
                            if (origin == nextCachedItem.Origin)
                            {
                                break;
                            }
                            origin = topCacheItem.Origin;
                        }

                        cachedTransitions[postDotSymbol] = new CachedStateFrameTransition(
                            postDotSymbol,
                            stateFrame.Frame,
                            topCacheItem == null ? stateFrame.Origin : origin);
                    }
                    else
                    {
                        cachedCount[postDotSymbol] = count + 1;
                    }
                }
            }

            // add all memoized leo items to the frameSet
            foreach (var symbol in cachedCount.Keys)
            {
                var count = cachedCount[symbol];
                if (count != 1)
                {
                    continue;
                }
                frameSet.AddCachedTransition(cachedTransitions[symbol]);
            }

            cachedTransitionsPool.ClearAndFree(cachedTransitions);
            cachedCountPool.ClearAndFree(cachedCount);
        }