public override bool Equals(object o) { if (o == this) { return(true); } else { if (!(o is Antlr4.Runtime.Atn.SingletonPredictionContext)) { return(false); } } if (this.GetHashCode() != o.GetHashCode()) { return(false); } Antlr4.Runtime.Atn.SingletonPredictionContext other = (Antlr4.Runtime.Atn.SingletonPredictionContext)o; return(returnState == other.returnState && parent.Equals(other.parent)); }
internal static PredictionContext Merge(PredictionContext a, PredictionContext b, bool rootIsWildcard, MergeCache mergeCache) { if (a == b || a.Equals(b)) { return(a); } if (a is SingletonPredictionContext && b is SingletonPredictionContext) { return(MergeSingletons((SingletonPredictionContext)a, (SingletonPredictionContext)b, rootIsWildcard, mergeCache)); } // At least one of a or b is array // If one is $ and rootIsWildcard, return $ as * wildcard if (rootIsWildcard) { if (a is EmptyPredictionContext) { return(a); } if (b is EmptyPredictionContext) { return(b); } } // convert singleton so both are arrays to normalize if (a is SingletonPredictionContext) { a = new ArrayPredictionContext((SingletonPredictionContext)a); } if (b is SingletonPredictionContext) { b = new ArrayPredictionContext((SingletonPredictionContext)b); } return(MergeArrays((ArrayPredictionContext)a, (ArrayPredictionContext)b, rootIsWildcard, mergeCache)); }
public static PredictionContext MergeArrays( ArrayPredictionContext a, ArrayPredictionContext b, bool rootIsWildcard, MergeCache mergeCache) { if (mergeCache != null) { PredictionContext previous = mergeCache.Get(a, b); if (previous != null) { return(previous); } previous = mergeCache.Get(b, a); if (previous != null) { return(previous); } } // merge sorted payloads a + b => M int i = 0; // walks a int j = 0; // walks b int k = 0; // walks target M array int[] mergedReturnStates = new int[a.returnStates.Length + b.returnStates.Length]; PredictionContext[] mergedParents = new PredictionContext[a.returnStates.Length + b.returnStates.Length]; // walk and merge to yield mergedParents, mergedReturnStates while (i < a.returnStates.Length && j < b.returnStates.Length) { PredictionContext a_parent = a.parents[i]; PredictionContext b_parent = b.parents[j]; if (a.returnStates[i] == b.returnStates[j]) { // same payload (stack tops are equal), must yield merged singleton int payload = a.returnStates[i]; // $+$ = $ bool both_dollar = payload == EMPTY_RETURN_STATE && a_parent == null && b_parent == null; bool ax_ax = (a_parent != null && b_parent != null) && a_parent.Equals(b_parent); // ax+ax -> ax if (both_dollar || ax_ax) { mergedParents[k] = a_parent; // choose left mergedReturnStates[k] = payload; } else // ax+ay -> a'[x,y] { PredictionContext mergedParent = Merge(a_parent, b_parent, rootIsWildcard, mergeCache); mergedParents[k] = mergedParent; mergedReturnStates[k] = payload; } i++; // hop over left one as usual j++; // but also skip one in right side since we merge } else if (a.returnStates[i] < b.returnStates[j]) { // copy a[i] to M mergedParents[k] = a_parent; mergedReturnStates[k] = a.returnStates[i]; i++; } else // b > a, copy b[j] to M { mergedParents[k] = b_parent; mergedReturnStates[k] = b.returnStates[j]; j++; } k++; } // copy over any payloads remaining in either array if (i < a.returnStates.Length) { for (int p = i; p < a.returnStates.Length; p++) { mergedParents[k] = a.parents[p]; mergedReturnStates[k] = a.returnStates[p]; k++; } } else { for (int p = j; p < b.returnStates.Length; p++) { mergedParents[k] = b.parents[p]; mergedReturnStates[k] = b.returnStates[p]; k++; } } // trim merged if we combined a few that had same stack tops if (k < mergedParents.Length) { // write index < last position; trim if (k == 1) { // for just one merged element, return singleton top PredictionContext a_ = SingletonPredictionContext.Create(mergedParents[0], mergedReturnStates[0]); if (mergeCache != null) { mergeCache.Put(a, b, a_); } return(a_); } mergedParents = Arrays.CopyOf(mergedParents, k); mergedReturnStates = Arrays.CopyOf(mergedReturnStates, k); } PredictionContext M = new ArrayPredictionContext(mergedParents, mergedReturnStates); // if we created same array as a or b, return that instead // TODO: track whether this is possible above during merge sort for speed if (M.Equals(a)) { if (mergeCache != null) { mergeCache.Put(a, b, a); } return(a); } if (M.Equals(b)) { if (mergeCache != null) { mergeCache.Put(a, b, b); } return(b); } CombineCommonParents(mergedParents); if (mergeCache != null) { mergeCache.Put(a, b, M); } return(M); }