forked from jasder/antlr
turn on local context cache.
This commit is contained in:
parent
14372f2515
commit
8279c3da11
|
@ -144,7 +144,6 @@ import java.util.Set;
|
|||
|
||||
*/
|
||||
public class ATNConfigSet implements Set<ATNConfig> {
|
||||
// TODO: convert to long like Sam? use list and map from config to ctx?
|
||||
/*
|
||||
The reason that we need this is because we don't want the hash map to use
|
||||
the standard hash code and equals. We need all configurations with the same
|
||||
|
@ -152,53 +151,28 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
|||
the number of objects associated with ATNConfigs. The other solution is to
|
||||
use a hash table that lets us specify the equals/hashcode operation.
|
||||
*/
|
||||
public static class Key {
|
||||
ATNState state;
|
||||
int alt;
|
||||
SemanticContext semanticContext;
|
||||
|
||||
public Key(ATNState state, int alt, SemanticContext semanticContext) {
|
||||
this.state = state;
|
||||
this.alt = alt;
|
||||
this.semanticContext = semanticContext;
|
||||
}
|
||||
|
||||
public Key(ATNConfig c) {
|
||||
this(c.state, c.alt, c.semanticContext);
|
||||
public static class ConfigHashSet extends Array2DHashSet<ATNConfig> {
|
||||
public ConfigHashSet() {
|
||||
super(16,2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ( obj==this ) return true;
|
||||
if ( this.hashCode() != obj.hashCode() ) return false;
|
||||
if ( !(obj instanceof Key) ) return false;
|
||||
Key key = (Key)obj;
|
||||
return this.state.stateNumber==key.state.stateNumber
|
||||
&& this.alt==key.alt
|
||||
&& this.semanticContext.equals(key.semanticContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
public int hashCode(ATNConfig o) {
|
||||
int hashCode = 7;
|
||||
hashCode = 5 * hashCode + state.stateNumber;
|
||||
hashCode = 5 * hashCode + alt;
|
||||
hashCode = 5 * hashCode + semanticContext.hashCode();
|
||||
hashCode = 31 * hashCode + o.state.stateNumber;
|
||||
hashCode = 31 * hashCode + o.alt;
|
||||
hashCode = 31 * hashCode + o.semanticContext.hashCode();
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConfigHashSet extends Array2DHashSet<ATNConfig> {
|
||||
public int hashCode(ATNConfig o) {
|
||||
return o.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(ATNConfig a, ATNConfig b) {
|
||||
if ( a==null && b==null ) return true;
|
||||
if ( a==null || b==null ) return false;
|
||||
if ( a==b ) return true;
|
||||
if ( a==null || b==null ) return false;
|
||||
if ( hashCode(a) != hashCode(b) ) return false;
|
||||
return a.equals(b);
|
||||
return a.state.stateNumber==b.state.stateNumber
|
||||
&& a.alt==b.alt
|
||||
&& b.semanticContext.equals(b.semanticContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,11 +238,9 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
|||
if ( config.semanticContext!=SemanticContext.NONE ) {
|
||||
hasSemanticContext = true;
|
||||
}
|
||||
Key key = new Key(config);
|
||||
ATNConfig existing = configLookup.get(config);
|
||||
if ( existing==null ) { // nothing there yet; easy, just add
|
||||
configLookup.add(config);
|
||||
configs.add(config); // track order here
|
||||
ATNConfig existing = configLookup.put(config);
|
||||
if ( existing==config ) { // we added this new one
|
||||
configs.add(config); // track order here
|
||||
return true;
|
||||
}
|
||||
// a previous (s,i,pi,_), merge with it and save result
|
||||
|
@ -346,8 +318,8 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
|||
public boolean equals(Object o) {
|
||||
// System.out.print("equals " + this + ", " + o+" = ");
|
||||
ATNConfigSet other = (ATNConfigSet)o;
|
||||
boolean same = configLookup!=null &&
|
||||
configLookup.equals(other.configLookup) &&
|
||||
boolean same = configs!=null &&
|
||||
configs.equals(other.configs) && // includes stack context
|
||||
this.fullCtx == other.fullCtx &&
|
||||
this.uniqueAlt == other.uniqueAlt &&
|
||||
this.conflictingAlts == other.conflictingAlts &&
|
||||
|
|
|
@ -206,7 +206,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
public int predictATN(@NotNull DFA dfa, @NotNull TokenStream input,
|
||||
@Nullable ParserRuleContext<?> outerContext)
|
||||
{
|
||||
contextCache = new PredictionContextCache("predict ctx cache");
|
||||
//contextCache = new PredictionContextCache("predict ctx cache");
|
||||
if ( outerContext==null ) outerContext = ParserRuleContext.EMPTY;
|
||||
if ( debug || debug_list_atn_decisions ) {
|
||||
System.out.println("predictATN decision "+dfa.decision+
|
||||
|
@ -268,7 +268,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
if ( dfa_debug ) System.out.println("ctx sensitive state "+outerContext+" in "+s);
|
||||
boolean loopsSimulateTailRecursion = true;
|
||||
boolean fullCtx = true;
|
||||
contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
||||
// contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
||||
ATNConfigSet s0_closure =
|
||||
computeStartState(dfa.atnStartState, outerContext,
|
||||
greedy, loopsSimulateTailRecursion,
|
||||
|
@ -312,7 +312,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
" at DFA state "+s.stateNumber);
|
||||
}
|
||||
|
||||
contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
||||
// contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
||||
alt = execATN(dfa, s, input, startIndex, outerContext);
|
||||
contextCache = null;
|
||||
// this adds edge even if next state is accept for
|
||||
|
|
|
@ -7,9 +7,9 @@ import java.util.Set;
|
|||
/** Set impl with closed hashing (open addressing). */
|
||||
public class Array2DHashSet<T> implements Set<T> {
|
||||
|
||||
public static final int INITAL_CAPACITY = 4;
|
||||
public static final int INITAL_BUCKET_CAPACITY = 2;
|
||||
public static final double LOAD_FACTOR = 0.8;
|
||||
public static final int INITAL_CAPACITY = 16; // must be power of 2
|
||||
public static final int INITAL_BUCKET_CAPACITY = 8;
|
||||
public static final double LOAD_FACTOR = 0.75;
|
||||
|
||||
protected T[][] buckets;
|
||||
|
||||
|
@ -19,9 +19,15 @@ public class Array2DHashSet<T> implements Set<T> {
|
|||
protected int threshold = (int)(INITAL_CAPACITY * LOAD_FACTOR); // when to expand
|
||||
|
||||
protected int currentPrime = 1; // jump by 4 primes each expand or whatever
|
||||
protected int initialBucketCapacity = INITAL_BUCKET_CAPACITY;
|
||||
|
||||
public Array2DHashSet() {
|
||||
buckets = (T[][])new Object[INITAL_CAPACITY][];
|
||||
this(INITAL_CAPACITY, INITAL_BUCKET_CAPACITY);
|
||||
}
|
||||
|
||||
public Array2DHashSet(int initialCapacity, int initialBucketCapacity) {
|
||||
buckets = (T[][])new Object[initialCapacity][];
|
||||
this.initialBucketCapacity = initialBucketCapacity;
|
||||
}
|
||||
|
||||
/** Add o to set if not there; return existing value if already there. */
|
||||
|
@ -33,12 +39,14 @@ public class Array2DHashSet<T> implements Set<T> {
|
|||
protected T put_(T o) {
|
||||
int b = getBucket(o);
|
||||
T[] bucket = buckets[b];
|
||||
// NEW BUCKET
|
||||
if ( bucket==null ) {
|
||||
buckets[b] = (T[])new Object[INITAL_BUCKET_CAPACITY];
|
||||
buckets[b] = (T[])new Object[initialBucketCapacity];
|
||||
buckets[b][0] = o;
|
||||
n++;
|
||||
return o;
|
||||
}
|
||||
// LOOK FOR IT IN BUCKET
|
||||
for (int i=0; i<bucket.length; i++) {
|
||||
T existing = bucket[i];
|
||||
if ( existing==null ) { // empty slot; not there, add.
|
||||
|
@ -46,14 +54,14 @@ public class Array2DHashSet<T> implements Set<T> {
|
|||
n++;
|
||||
return o;
|
||||
}
|
||||
if ( existing.equals(o) ) return existing;
|
||||
if ( equals(existing,o) ) return existing; // found existing, quit
|
||||
}
|
||||
// full bucket, expand and add to end
|
||||
// FULL BUCKET, expand and add to end
|
||||
T[] old = bucket;
|
||||
bucket = (T[])new Object[old.length * 2];
|
||||
buckets[b] = bucket;
|
||||
System.arraycopy(old, 0, bucket, 0, old.length);
|
||||
bucket[old.length] = o;
|
||||
bucket[old.length] = o; // add to end
|
||||
n++;
|
||||
return o;
|
||||
}
|
||||
|
@ -65,7 +73,7 @@ public class Array2DHashSet<T> implements Set<T> {
|
|||
if ( bucket==null ) return null; // no bucket
|
||||
for (T e : bucket) {
|
||||
if ( e==null ) return null; // empty slot; not there
|
||||
if ( e.equals(o) ) return e;
|
||||
if ( equals(e,o) ) return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -83,7 +91,7 @@ public class Array2DHashSet<T> implements Set<T> {
|
|||
if ( bucket==null ) continue;
|
||||
for (T o : bucket) {
|
||||
if ( o==null ) break;
|
||||
h += o.hashCode();
|
||||
h += hashCode(o);
|
||||
}
|
||||
}
|
||||
return h;
|
||||
|
@ -95,7 +103,8 @@ public class Array2DHashSet<T> implements Set<T> {
|
|||
if ( !(o instanceof Array2DHashSet) || o==null ) return false;
|
||||
Array2DHashSet<T> other = (Array2DHashSet<T>)o;
|
||||
if ( other.size() != size() ) return false;
|
||||
return containsAll(other);
|
||||
boolean same = this.containsAll(other) && other.containsAll(this);
|
||||
return same;
|
||||
}
|
||||
|
||||
protected void expand() {
|
||||
|
@ -209,7 +218,7 @@ public class Array2DHashSet<T> implements Set<T> {
|
|||
for (int i=0; i<bucket.length; i++) {
|
||||
T e = bucket[i];
|
||||
if ( e==null ) return false; // empty slot; not there
|
||||
if ( e.equals(o) ) { // found it
|
||||
if ( equals(e,(T)o) ) { // found it
|
||||
// shift all elements to the right down one
|
||||
// for (int j=i; j<bucket.length-1; j++) bucket[j] = bucket[j+1];
|
||||
System.arraycopy(bucket, i+1, bucket, i, bucket.length-i-1);
|
||||
|
|
Loading…
Reference in New Issue