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