public virtual bool Add(ATNConfig e, PredictionContextCache contextCache) { EnsureWritable(); System.Diagnostics.Debug.Assert(!outermostConfigSet || !e.ReachesIntoOuterContext); System.Diagnostics.Debug.Assert(!e.IsHidden); if (contextCache == null) { contextCache = PredictionContextCache.Uncached; } bool addKey; long key = GetKey(e); ATNConfig mergedConfig; addKey = !mergedConfigs.TryGetValue(key, out mergedConfig); if (mergedConfig != null && CanMerge(e, key, mergedConfig)) { mergedConfig.OuterContextDepth = Math.Max(mergedConfig.OuterContextDepth, e.OuterContextDepth); PredictionContext joined = PredictionContext.Join(mergedConfig.Context, e.Context, contextCache); UpdatePropertiesForMergedConfig(e); if (mergedConfig.Context == joined) { return(false); } mergedConfig.Context = joined; return(true); } for (int i = 0; i < unmerged.Count; i++) { ATNConfig unmergedConfig = unmerged[i]; if (CanMerge(e, key, unmergedConfig)) { unmergedConfig.OuterContextDepth = Math.Max(unmergedConfig.OuterContextDepth, e.OuterContextDepth); PredictionContext joined = PredictionContext.Join(unmergedConfig.Context, e.Context, contextCache); UpdatePropertiesForMergedConfig(e); if (unmergedConfig.Context == joined) { return(false); } unmergedConfig.Context = joined; if (addKey) { mergedConfigs[key] = unmergedConfig; unmerged.RemoveAt(i); } return(true); } } configs.Add(e); if (addKey) { mergedConfigs[key] = e; } else { unmerged.Add(e); } UpdatePropertiesForAddedConfig(e); return(true); }
public virtual PredictionContext Join(PredictionContext x, PredictionContext y) { if (!enableCache) { return(PredictionContext.Join(x, y, this)); } PredictionContextCache.IdentityCommutativePredictionContextOperands operands = new PredictionContextCache.IdentityCommutativePredictionContextOperands(x, y); PredictionContext result; if (joinContexts.TryGetValue(operands, out result)) { return(result); } result = PredictionContext.Join(x, y, this); result = GetAsCached(result); joinContexts[operands] = result; return(result); }
private static PredictionContext AppendContext(PredictionContext context, PredictionContext suffix, PredictionContext.IdentityHashMap visited) { if (suffix.IsEmpty) { if (IsEmptyLocal(suffix)) { if (context.HasEmpty) { return(EmptyLocal); } throw new NotSupportedException("what to do here?"); } return(context); } if (suffix.Size != 1) { throw new NotSupportedException("Appending a tree suffix is not yet supported."); } PredictionContext result; if (!visited.TryGetValue(context, out result)) { if (context.IsEmpty) { result = suffix; } else { int parentCount = context.Size; if (context.HasEmpty) { parentCount--; } PredictionContext[] updatedParents = new PredictionContext[parentCount]; int[] updatedReturnStates = new int[parentCount]; for (int i = 0; i < parentCount; i++) { updatedReturnStates[i] = context.GetReturnState(i); } for (int i_1 = 0; i_1 < parentCount; i_1++) { updatedParents[i_1] = AppendContext(context.GetParent(i_1), suffix, visited); } if (updatedParents.Length == 1) { result = new SingletonPredictionContext(updatedParents[0], updatedReturnStates[0]); } else { System.Diagnostics.Debug.Assert(updatedParents.Length > 1); result = new Antlr4.Runtime.Atn.ArrayPredictionContext(updatedParents, updatedReturnStates); } if (context.HasEmpty) { result = PredictionContext.Join(result, suffix); } } visited[context] = result; } return(result); }