1 /* 2 * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 * Use of this file is governed by the BSD 3-clause license that 4 * can be found in the LICENSE.txt file in the project root. 5 */ 6 7 package org.antlr.v4.runtime.atn; 8 9 import java.util.Arrays; 10 11 public class ArrayPredictionContext extends PredictionContext { 12 /** Parent can be null only if full ctx mode and we make an array 13 * from {@link #EMPTY} and non-empty. We merge {@link #EMPTY} by using null parent and 14 * returnState == {@link #EMPTY_RETURN_STATE}. 15 */ 16 public final PredictionContext[] parents; 17 18 /** Sorted for merge, no duplicates; if present, 19 * {@link #EMPTY_RETURN_STATE} is always last. 20 */ 21 public final int[] returnStates; 22 ArrayPredictionContext(SingletonPredictionContext a)23 public ArrayPredictionContext(SingletonPredictionContext a) { 24 this(new PredictionContext[] {a.parent}, new int[] {a.returnState}); 25 } 26 ArrayPredictionContext(PredictionContext[] parents, int[] returnStates)27 public ArrayPredictionContext(PredictionContext[] parents, int[] returnStates) { 28 super(calculateHashCode(parents, returnStates)); 29 assert parents!=null && parents.length>0; 30 assert returnStates!=null && returnStates.length>0; 31 // System.err.println("CREATE ARRAY: "+Arrays.toString(parents)+", "+Arrays.toString(returnStates)); 32 this.parents = parents; 33 this.returnStates = returnStates; 34 } 35 36 @Override isEmpty()37 public boolean isEmpty() { 38 // since EMPTY_RETURN_STATE can only appear in the last position, we 39 // don't need to verify that size==1 40 return returnStates[0]==EMPTY_RETURN_STATE; 41 } 42 43 @Override size()44 public int size() { 45 return returnStates.length; 46 } 47 48 @Override getParent(int index)49 public PredictionContext getParent(int index) { 50 return parents[index]; 51 } 52 53 @Override getReturnState(int index)54 public int getReturnState(int index) { 55 return returnStates[index]; 56 } 57 58 // @Override 59 // public int findReturnState(int returnState) { 60 // return Arrays.binarySearch(returnStates, returnState); 61 // } 62 63 @Override equals(Object o)64 public boolean equals(Object o) { 65 if (this == o) { 66 return true; 67 } 68 else if ( !(o instanceof ArrayPredictionContext) ) { 69 return false; 70 } 71 72 if ( this.hashCode() != o.hashCode() ) { 73 return false; // can't be same if hash is different 74 } 75 76 ArrayPredictionContext a = (ArrayPredictionContext)o; 77 return Arrays.equals(returnStates, a.returnStates) && 78 Arrays.equals(parents, a.parents); 79 } 80 81 @Override toString()82 public String toString() { 83 if ( isEmpty() ) return "[]"; 84 StringBuilder buf = new StringBuilder(); 85 buf.append("["); 86 for (int i=0; i<returnStates.length; i++) { 87 if ( i>0 ) buf.append(", "); 88 if ( returnStates[i]==EMPTY_RETURN_STATE ) { 89 buf.append("$"); 90 continue; 91 } 92 buf.append(returnStates[i]); 93 if ( parents[i]!=null ) { 94 buf.append(' '); 95 buf.append(parents[i].toString()); 96 } 97 else { 98 buf.append("null"); 99 } 100 } 101 buf.append("]"); 102 return buf.toString(); 103 } 104 } 105