rm transient context cache for closure computations; slight speed improvement maybe. less complex.
This commit is contained in:
parent
eda95f7478
commit
680df17280
|
@ -31,7 +31,6 @@ package org.antlr.v4.runtime.atn;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.misc.Array2DHashSet;
|
import org.antlr.v4.runtime.misc.Array2DHashSet;
|
||||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||||
import org.antlr.v4.runtime.misc.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -300,25 +299,20 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
||||||
|
|
||||||
public ATNConfigSet(ATNConfigSet old, PredictionContextCache contextCache) {
|
public ATNConfigSet(ATNConfigSet old, PredictionContextCache contextCache) {
|
||||||
this(old.fullCtx);
|
this(old.fullCtx);
|
||||||
addAll(old, contextCache);
|
addAll(old);
|
||||||
this.uniqueAlt = old.uniqueAlt;
|
this.uniqueAlt = old.uniqueAlt;
|
||||||
this.conflictingAlts = old.conflictingAlts;
|
this.conflictingAlts = old.conflictingAlts;
|
||||||
this.hasSemanticContext = old.hasSemanticContext;
|
this.hasSemanticContext = old.hasSemanticContext;
|
||||||
this.dipsIntoOuterContext = old.dipsIntoOuterContext;
|
this.dipsIntoOuterContext = old.dipsIntoOuterContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean add(ATNConfig e) {
|
|
||||||
return add(e, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adding a new config means merging contexts with existing configs for
|
/** Adding a new config means merging contexts with existing configs for
|
||||||
* (s, i, pi, _)
|
* (s, i, pi, _)
|
||||||
* We use (s,i,pi) as key
|
* We use (s,i,pi) as key
|
||||||
*/
|
*/
|
||||||
public boolean add(ATNConfig config, @Nullable PredictionContextCache contextCache) {
|
@Override
|
||||||
|
public boolean add(ATNConfig config) {
|
||||||
if ( readonly ) throw new IllegalStateException("This set is readonly");
|
if ( readonly ) throw new IllegalStateException("This set is readonly");
|
||||||
contextCache = null; // TODO: costs time to cache and saves essentially no RAM
|
|
||||||
if ( config.semanticContext!=SemanticContext.NONE ) {
|
if ( config.semanticContext!=SemanticContext.NONE ) {
|
||||||
hasSemanticContext = true;
|
hasSemanticContext = true;
|
||||||
}
|
}
|
||||||
|
@ -330,11 +324,10 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
||||||
// a previous (s,i,pi,_), merge with it and save result
|
// a previous (s,i,pi,_), merge with it and save result
|
||||||
boolean rootIsWildcard = !fullCtx;
|
boolean rootIsWildcard = !fullCtx;
|
||||||
PredictionContext merged =
|
PredictionContext merged =
|
||||||
PredictionContext.merge(existing.context, config.context, contextCache, rootIsWildcard);
|
PredictionContext.merge(existing.context, config.context, rootIsWildcard);
|
||||||
// no need to check for existing.context, config.context in cache
|
// no need to check for existing.context, config.context in cache
|
||||||
// since only way to create new graphs is "call rule" and here. We
|
// since only way to create new graphs is "call rule" and here. We
|
||||||
// cache at both places.
|
// cache at both places.
|
||||||
if ( contextCache!=null ) merged = contextCache.add(merged);
|
|
||||||
existing.reachesIntoOuterContext =
|
existing.reachesIntoOuterContext =
|
||||||
Math.max(existing.reachesIntoOuterContext, config.reachesIntoOuterContext);
|
Math.max(existing.reachesIntoOuterContext, config.reachesIntoOuterContext);
|
||||||
existing.context = merged; // replace context; no need to alt mapping
|
existing.context = merged; // replace context; no need to alt mapping
|
||||||
|
@ -384,17 +377,8 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean addAll(Collection<? extends ATNConfig> coll) {
|
||||||
public boolean addAll(Collection<? extends ATNConfig> c) {
|
for (ATNConfig c : coll) add(c);
|
||||||
return addAll(c, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean addAll(Collection<? extends ATNConfig> coll,
|
|
||||||
PredictionContextCache contextCache)
|
|
||||||
{
|
|
||||||
for (ATNConfig c : coll) {
|
|
||||||
add(c, contextCache);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,28 +50,23 @@ public abstract class ATNSimulator {
|
||||||
* to use only cached nodes/graphs in addDFAState(). We don't want to
|
* to use only cached nodes/graphs in addDFAState(). We don't want to
|
||||||
* fill this during closure() since there are lots of contexts that
|
* fill this during closure() since there are lots of contexts that
|
||||||
* pop up but are not used ever again. It also greatly slows down closure().
|
* pop up but are not used ever again. It also greatly slows down closure().
|
||||||
|
*
|
||||||
|
* This cache makes a huge difference in memory and a little bit in speed.
|
||||||
|
* For the Java grammar on java.*, it dropped the memory requirements
|
||||||
|
* at the end from 25M to 16M. We don't store any of the full context
|
||||||
|
* graphs in the DFA because they are limited to local context only,
|
||||||
|
* but apparently there's a lot of repetition there as well. We optimize
|
||||||
|
* the config contexts before storing the config set in the DFA states
|
||||||
|
* by literally rebuilding them with cached subgraphs only.
|
||||||
|
*
|
||||||
|
* I tried a cache for use during closure operations, that was
|
||||||
|
* whacked after each adaptivePredict(). It cost a little bit
|
||||||
|
* more time I think and doesn't save on the overall footprint
|
||||||
|
* so it's not worth the complexity.
|
||||||
*/
|
*/
|
||||||
protected final PredictionContextCache sharedContextCache =
|
protected final PredictionContextCache sharedContextCache =
|
||||||
new PredictionContextCache("shared DFA state context cache");
|
new PredictionContextCache("shared DFA state context cache");
|
||||||
|
|
||||||
/** This context cache tracks all context graphs used during a single
|
|
||||||
* ATN-based prediction operation. There will be significant context graph
|
|
||||||
* sharing among ATNConfigSets because all sets are derived from the
|
|
||||||
* same starting context.
|
|
||||||
*
|
|
||||||
* This cache is blown away after each adaptivePredict()
|
|
||||||
* because we cache everything within ATNConfigSets that become DFA
|
|
||||||
* states in sharedContextCache. (Sam thinks of this as an analogy to
|
|
||||||
* the nursery in a generational GC; then, sharedContextCache would be
|
|
||||||
* the mature generation.)
|
|
||||||
*
|
|
||||||
* In Sam's version, this is a parameter passed down through all of
|
|
||||||
* the methods, but it gets pretty unwieldy as there are already
|
|
||||||
* a crapload of parameters. Consequently, I'm using a field as a
|
|
||||||
* "parameter" despite it being generally poor coding style.
|
|
||||||
*/
|
|
||||||
protected PredictionContextCache contextCache;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ERROR = new DFAState(new ATNConfigSet());
|
ERROR = new DFAState(new ATNConfigSet());
|
||||||
ERROR.stateNumber = Integer.MAX_VALUE;
|
ERROR.stateNumber = Integer.MAX_VALUE;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package org.antlr.v4.runtime.atn;
|
package org.antlr.v4.runtime.atn;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.misc.NotNull;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
@ -126,7 +124,6 @@ public class ArrayPredictionContext extends PredictionContext {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public PredictionContext popAll(int invokingState,
|
public PredictionContext popAll(int invokingState,
|
||||||
@NotNull PredictionContextCache contextCache,
|
|
||||||
boolean fullCtx)
|
boolean fullCtx)
|
||||||
{
|
{
|
||||||
int index = Arrays.binarySearch(this.invokingStates, invokingState);
|
int index = Arrays.binarySearch(this.invokingStates, invokingState);
|
||||||
|
@ -135,7 +132,7 @@ public class ArrayPredictionContext extends PredictionContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
PredictionContext newCtx =
|
PredictionContext newCtx =
|
||||||
this.parents[index].popAll(invokingState, contextCache, fullCtx);
|
this.parents[index].popAll(invokingState, fullCtx);
|
||||||
for (int i = 0; i < this.invokingStates.length; i++) {
|
for (int i = 0; i < this.invokingStates.length; i++) {
|
||||||
if (i == index) continue;
|
if (i == index) continue;
|
||||||
PredictionContext next;
|
PredictionContext next;
|
||||||
|
@ -145,10 +142,9 @@ public class ArrayPredictionContext extends PredictionContext {
|
||||||
else {
|
else {
|
||||||
next = new SingletonPredictionContext(this.parents[i],
|
next = new SingletonPredictionContext(this.parents[i],
|
||||||
this.invokingStates[i]);
|
this.invokingStates[i]);
|
||||||
if ( contextCache!=null ) next = contextCache.add(next);
|
|
||||||
}
|
}
|
||||||
boolean rootIsWildcard = fullCtx;
|
boolean rootIsWildcard = fullCtx;
|
||||||
newCtx = merge(newCtx, next, contextCache, rootIsWildcard);
|
newCtx = merge(newCtx, next, rootIsWildcard);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newCtx;
|
return newCtx;
|
||||||
|
|
|
@ -235,7 +235,6 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
throw nvae;
|
throw nvae;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
contextCache = null; // wack the cache
|
|
||||||
input.seek(index);
|
input.seek(index);
|
||||||
input.release(m);
|
input.release(m);
|
||||||
}
|
}
|
||||||
|
@ -268,7 +267,6 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
if ( dfa_debug ) System.out.println("ctx sensitive state "+outerContext+" in "+s);
|
if ( dfa_debug ) System.out.println("ctx sensitive state "+outerContext+" in "+s);
|
||||||
boolean loopsSimulateTailRecursion = true;
|
boolean loopsSimulateTailRecursion = true;
|
||||||
boolean fullCtx = true;
|
boolean fullCtx = true;
|
||||||
// contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
|
||||||
ATNConfigSet s0_closure =
|
ATNConfigSet s0_closure =
|
||||||
computeStartState(dfa.atnStartState, outerContext,
|
computeStartState(dfa.atnStartState, outerContext,
|
||||||
greedy, loopsSimulateTailRecursion,
|
greedy, loopsSimulateTailRecursion,
|
||||||
|
@ -280,7 +278,6 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
outerContext,
|
outerContext,
|
||||||
ATN.INVALID_ALT_NUMBER,
|
ATN.INVALID_ALT_NUMBER,
|
||||||
greedy);
|
greedy);
|
||||||
contextCache = null;
|
|
||||||
return fullCtxSet.uniqueAlt;
|
return fullCtxSet.uniqueAlt;
|
||||||
}
|
}
|
||||||
if ( s.isAcceptState ) {
|
if ( s.isAcceptState ) {
|
||||||
|
@ -312,9 +309,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
" at DFA state "+s.stateNumber);
|
" at DFA state "+s.stateNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
// contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
|
||||||
alt = execATN(dfa, s, input, startIndex, outerContext);
|
alt = execATN(dfa, s, input, startIndex, outerContext);
|
||||||
contextCache = null;
|
|
||||||
// this adds edge even if next state is accept for
|
// this adds edge even if next state is accept for
|
||||||
// same alt; e.g., s0-A->:s1=>2-B->:s2=>2
|
// same alt; e.g., s0-A->:s1=>2-B->:s2=>2
|
||||||
// TODO: This next stuff kills edge, but extra states remain. :(
|
// TODO: This next stuff kills edge, but extra states remain. :(
|
||||||
|
@ -625,7 +620,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
Transition trans = c.state.transition(ti);
|
Transition trans = c.state.transition(ti);
|
||||||
ATNState target = getReachableTarget(trans, t);
|
ATNState target = getReachableTarget(trans, t);
|
||||||
if ( target!=null ) {
|
if ( target!=null ) {
|
||||||
intermediate.add(new ATNConfig(c, target), contextCache);
|
intermediate.add(new ATNConfig(c, target));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -873,7 +868,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
// don't see past end of a rule for any nongreedy decision
|
// don't see past end of a rule for any nongreedy decision
|
||||||
if ( debug ) System.out.println("NONGREEDY at stop state of "+
|
if ( debug ) System.out.println("NONGREEDY at stop state of "+
|
||||||
getRuleName(config.state.ruleIndex));
|
getRuleName(config.state.ruleIndex));
|
||||||
configs.add(config, contextCache);
|
configs.add(config);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// We hit rule end. If we have context info, use it
|
// We hit rule end. If we have context info, use it
|
||||||
|
@ -917,7 +912,6 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
{
|
{
|
||||||
config.context =
|
config.context =
|
||||||
new SingletonPredictionContext(config.context, config.state.stateNumber);
|
new SingletonPredictionContext(config.context, config.state.stateNumber);
|
||||||
if ( contextCache!=null ) config.context = contextCache.add(config.context);
|
|
||||||
// alter config; it's ok, since all calls to closure pass in a fresh config for us to chase
|
// alter config; it's ok, since all calls to closure pass in a fresh config for us to chase
|
||||||
if ( debug ) System.out.println("Loop back; push "+config.state.stateNumber+", stack="+config.context);
|
if ( debug ) System.out.println("Loop back; push "+config.state.stateNumber+", stack="+config.context);
|
||||||
}
|
}
|
||||||
|
@ -926,7 +920,6 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
LoopEndState end = (LoopEndState)config.state;
|
LoopEndState end = (LoopEndState)config.state;
|
||||||
// pop all the way back until we don't see the loopback state anymore
|
// pop all the way back until we don't see the loopback state anymore
|
||||||
config.context = config.context.popAll(end.loopBackStateNumber,
|
config.context = config.context.popAll(end.loopBackStateNumber,
|
||||||
contextCache,
|
|
||||||
configs.fullCtx);
|
configs.fullCtx);
|
||||||
if ( debug ) System.out.println(" becomes "+config.context);
|
if ( debug ) System.out.println(" becomes "+config.context);
|
||||||
}
|
}
|
||||||
|
@ -949,7 +942,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
ATNState p = config.state;
|
ATNState p = config.state;
|
||||||
// optimization
|
// optimization
|
||||||
if ( !p.onlyHasEpsilonTransitions() ) {
|
if ( !p.onlyHasEpsilonTransitions() ) {
|
||||||
configs.add(config, contextCache);
|
configs.add(config);
|
||||||
if ( config.semanticContext!=null && config.semanticContext!= SemanticContext.NONE ) {
|
if ( config.semanticContext!=null && config.semanticContext!= SemanticContext.NONE ) {
|
||||||
configs.hasSemanticContext = true;
|
configs.hasSemanticContext = true;
|
||||||
}
|
}
|
||||||
|
@ -1086,7 +1079,6 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
}
|
}
|
||||||
PredictionContext newContext =
|
PredictionContext newContext =
|
||||||
new SingletonPredictionContext(config.context, config.state.stateNumber);
|
new SingletonPredictionContext(config.context, config.state.stateNumber);
|
||||||
if ( contextCache!=null ) newContext = contextCache.add(newContext);
|
|
||||||
return new ATNConfig(config, t.target, newContext);
|
return new ATNConfig(config, t.target, newContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract PredictionContext popAll(int invokingState,
|
public abstract PredictionContext popAll(int invokingState,
|
||||||
@NotNull PredictionContextCache contextCache,
|
|
||||||
boolean fullCtx);
|
boolean fullCtx);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -119,7 +118,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
|
|
||||||
// dispatch
|
// dispatch
|
||||||
public static PredictionContext merge(PredictionContext a, PredictionContext b,
|
public static PredictionContext merge(PredictionContext a, PredictionContext b,
|
||||||
@NotNull PredictionContextCache contextCache,
|
|
||||||
boolean rootIsWildcard)
|
boolean rootIsWildcard)
|
||||||
{
|
{
|
||||||
if ( (a==null&&b==null) || a==b || a.equals(b) ) return a; // share same graph if both same
|
if ( (a==null&&b==null) || a==b || a.equals(b) ) return a; // share same graph if both same
|
||||||
|
@ -127,7 +125,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
if ( a instanceof SingletonPredictionContext && b instanceof SingletonPredictionContext) {
|
if ( a instanceof SingletonPredictionContext && b instanceof SingletonPredictionContext) {
|
||||||
return mergeSingletons((SingletonPredictionContext)a,
|
return mergeSingletons((SingletonPredictionContext)a,
|
||||||
(SingletonPredictionContext)b,
|
(SingletonPredictionContext)b,
|
||||||
contextCache,
|
|
||||||
rootIsWildcard);
|
rootIsWildcard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,21 +143,19 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
b = new ArrayPredictionContext((SingletonPredictionContext)b);
|
b = new ArrayPredictionContext((SingletonPredictionContext)b);
|
||||||
}
|
}
|
||||||
return mergeArrays((ArrayPredictionContext) a, (ArrayPredictionContext) b,
|
return mergeArrays((ArrayPredictionContext) a, (ArrayPredictionContext) b,
|
||||||
contextCache,
|
|
||||||
rootIsWildcard);
|
rootIsWildcard);
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://www.antlr.org/wiki/download/attachments/32014352/singleton-merge.png
|
// http://www.antlr.org/wiki/download/attachments/32014352/singleton-merge.png
|
||||||
public static PredictionContext mergeSingletons(SingletonPredictionContext a,
|
public static PredictionContext mergeSingletons(SingletonPredictionContext a,
|
||||||
SingletonPredictionContext b,
|
SingletonPredictionContext b,
|
||||||
@NotNull PredictionContextCache contextCache,
|
|
||||||
boolean rootIsWildcard)
|
boolean rootIsWildcard)
|
||||||
{
|
{
|
||||||
PredictionContext rootMerge = mergeRoot(a, b, contextCache, rootIsWildcard);
|
PredictionContext rootMerge = mergeRoot(a, b, rootIsWildcard);
|
||||||
if ( rootMerge!=null ) return rootMerge;
|
if ( rootMerge!=null ) return rootMerge;
|
||||||
|
|
||||||
if ( a.invokingState==b.invokingState ) { // a == b
|
if ( a.invokingState==b.invokingState ) { // a == b
|
||||||
PredictionContext parent = merge(a.parent, b.parent, contextCache, rootIsWildcard);
|
PredictionContext parent = merge(a.parent, b.parent, rootIsWildcard);
|
||||||
// if parent is same as existing a or b parent or reduced to a parent, return it
|
// if parent is same as existing a or b parent or reduced to a parent, return it
|
||||||
if ( parent == a.parent ) return a; // ax + bx = ax, if a=b
|
if ( parent == a.parent ) return a; // ax + bx = ax, if a=b
|
||||||
if ( parent == b.parent ) return b; // ax + bx = bx, if a=b
|
if ( parent == b.parent ) return b; // ax + bx = bx, if a=b
|
||||||
|
@ -169,7 +164,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
// of those graphs. dup a, a' points at merged array
|
// of those graphs. dup a, a' points at merged array
|
||||||
// new joined parent so create new singleton pointing to it, a'
|
// new joined parent so create new singleton pointing to it, a'
|
||||||
PredictionContext a_ = new SingletonPredictionContext(parent, a.invokingState);
|
PredictionContext a_ = new SingletonPredictionContext(parent, a.invokingState);
|
||||||
if ( contextCache!=null ) a_ = contextCache.add(a_);
|
|
||||||
return a_;
|
return a_;
|
||||||
}
|
}
|
||||||
else { // a != b payloads differ
|
else { // a != b payloads differ
|
||||||
|
@ -191,7 +185,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
}
|
}
|
||||||
PredictionContext[] parents = {singleParent, singleParent};
|
PredictionContext[] parents = {singleParent, singleParent};
|
||||||
PredictionContext a_ = new ArrayPredictionContext(parents, payloads);
|
PredictionContext a_ = new ArrayPredictionContext(parents, payloads);
|
||||||
if ( contextCache!=null ) a_ = contextCache.add(a_);
|
|
||||||
return a_;
|
return a_;
|
||||||
}
|
}
|
||||||
// parents differ and can't merge them. Just pack together
|
// parents differ and can't merge them. Just pack together
|
||||||
|
@ -205,7 +198,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
parents = new PredictionContext[] {b.parent, a.parent};
|
parents = new PredictionContext[] {b.parent, a.parent};
|
||||||
}
|
}
|
||||||
PredictionContext a_ = new ArrayPredictionContext(parents, payloads);
|
PredictionContext a_ = new ArrayPredictionContext(parents, payloads);
|
||||||
if ( contextCache!=null ) a_ = contextCache.add(a_);
|
|
||||||
return a_;
|
return a_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,7 +207,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
/** Handle case where at least one of a or b is $ (EMPTY) */
|
/** Handle case where at least one of a or b is $ (EMPTY) */
|
||||||
public static PredictionContext mergeRoot(SingletonPredictionContext a,
|
public static PredictionContext mergeRoot(SingletonPredictionContext a,
|
||||||
SingletonPredictionContext b,
|
SingletonPredictionContext b,
|
||||||
@NotNull PredictionContextCache contextCache,
|
|
||||||
boolean rootIsWildcard)
|
boolean rootIsWildcard)
|
||||||
{
|
{
|
||||||
if ( rootIsWildcard ) {
|
if ( rootIsWildcard ) {
|
||||||
|
@ -229,7 +220,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
PredictionContext[] parents = {null, b.parent};
|
PredictionContext[] parents = {null, b.parent};
|
||||||
PredictionContext joined =
|
PredictionContext joined =
|
||||||
new ArrayPredictionContext(parents, payloads);
|
new ArrayPredictionContext(parents, payloads);
|
||||||
if ( contextCache!=null ) joined = contextCache.add(joined);
|
|
||||||
return joined;
|
return joined;
|
||||||
}
|
}
|
||||||
if ( b == EMPTY ) { // x + $ = [$,x] ($ is always first if present)
|
if ( b == EMPTY ) { // x + $ = [$,x] ($ is always first if present)
|
||||||
|
@ -237,7 +227,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
PredictionContext[] parents = {null, a.parent};
|
PredictionContext[] parents = {null, a.parent};
|
||||||
PredictionContext joined =
|
PredictionContext joined =
|
||||||
new ArrayPredictionContext(parents, payloads);
|
new ArrayPredictionContext(parents, payloads);
|
||||||
if ( contextCache!=null ) joined = contextCache.add(joined);
|
|
||||||
return joined;
|
return joined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,7 +236,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
// http://www.antlr.org/wiki/download/attachments/32014352/array-merge.png
|
// http://www.antlr.org/wiki/download/attachments/32014352/array-merge.png
|
||||||
public static PredictionContext mergeArrays(ArrayPredictionContext a,
|
public static PredictionContext mergeArrays(ArrayPredictionContext a,
|
||||||
ArrayPredictionContext b,
|
ArrayPredictionContext b,
|
||||||
@NotNull PredictionContextCache contextCache,
|
|
||||||
boolean rootIsWildcard)
|
boolean rootIsWildcard)
|
||||||
{
|
{
|
||||||
// merge sorted payloads a + b => M
|
// merge sorted payloads a + b => M
|
||||||
|
@ -277,7 +265,7 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
}
|
}
|
||||||
else { // ax+ay -> a'[x,y]
|
else { // ax+ay -> a'[x,y]
|
||||||
PredictionContext mergedParent =
|
PredictionContext mergedParent =
|
||||||
merge(a_parent, b_parent, contextCache, rootIsWildcard);
|
merge(a_parent, b_parent, rootIsWildcard);
|
||||||
mergedParents[k] = mergedParent;
|
mergedParents[k] = mergedParent;
|
||||||
mergedInvokingStates[k] = payload;
|
mergedInvokingStates[k] = payload;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +313,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
if ( n == 1 ) { // for just one merged element, return singleton top
|
if ( n == 1 ) { // for just one merged element, return singleton top
|
||||||
PredictionContext a_ = new SingletonPredictionContext(mergedParents[0],
|
PredictionContext a_ = new SingletonPredictionContext(mergedParents[0],
|
||||||
mergedInvokingStates[0]);
|
mergedInvokingStates[0]);
|
||||||
a_ = contextCache.add(a_);
|
|
||||||
return a_;
|
return a_;
|
||||||
}
|
}
|
||||||
mergedParents = Arrays.copyOf(mergedParents, n);
|
mergedParents = Arrays.copyOf(mergedParents, n);
|
||||||
|
@ -335,7 +322,6 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
||||||
|
|
||||||
PredictionContext M =
|
PredictionContext M =
|
||||||
new ArrayPredictionContext(mergedParents, mergedInvokingStates);
|
new ArrayPredictionContext(mergedParents, mergedInvokingStates);
|
||||||
if ( contextCache!=null ) M = contextCache.add(M);
|
|
||||||
|
|
||||||
// if we created same array as a or b, return that instead
|
// if we created same array as a or b, return that instead
|
||||||
// TODO: track whether this is possible above during merge sort for speed
|
// TODO: track whether this is possible above during merge sort for speed
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package org.antlr.v4.runtime.atn;
|
package org.antlr.v4.runtime.atn;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.misc.NotNull;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
public class SingletonPredictionContext extends PredictionContext {
|
public class SingletonPredictionContext extends PredictionContext {
|
||||||
|
@ -52,11 +50,10 @@ public class SingletonPredictionContext extends PredictionContext {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PredictionContext popAll(int invokingState,
|
public PredictionContext popAll(int invokingState,
|
||||||
@NotNull PredictionContextCache contextCache,
|
|
||||||
boolean fullCtx)
|
boolean fullCtx)
|
||||||
{
|
{
|
||||||
if ( invokingState == this.invokingState ) {
|
if ( invokingState == this.invokingState ) {
|
||||||
return parent.popAll(invokingState, contextCache, fullCtx);
|
return parent.popAll(invokingState, fullCtx);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ public class TestGraphNodes extends TestCase {
|
||||||
@Test public void test_$_$() {
|
@Test public void test_$_$() {
|
||||||
PredictionContext r = PredictionContext.merge(PredictionContext.EMPTY,
|
PredictionContext r = PredictionContext.merge(PredictionContext.EMPTY,
|
||||||
PredictionContext.EMPTY,
|
PredictionContext.EMPTY,
|
||||||
contextCache,
|
|
||||||
rootIsWildcard());
|
rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
|
@ -36,7 +35,6 @@ public class TestGraphNodes extends TestCase {
|
||||||
@Test public void test_$_$_fullctx() {
|
@Test public void test_$_$_fullctx() {
|
||||||
PredictionContext r = PredictionContext.merge(PredictionContext.EMPTY,
|
PredictionContext r = PredictionContext.merge(PredictionContext.EMPTY,
|
||||||
PredictionContext.EMPTY,
|
PredictionContext.EMPTY,
|
||||||
contextCache,
|
|
||||||
fullCtx());
|
fullCtx());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
|
@ -48,7 +46,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void test_x_$() {
|
@Test public void test_x_$() {
|
||||||
PredictionContext r = PredictionContext.merge(x(), PredictionContext.EMPTY, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(x(), PredictionContext.EMPTY, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -59,7 +57,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void test_x_$_fullctx() {
|
@Test public void test_x_$_fullctx() {
|
||||||
PredictionContext r = PredictionContext.merge(x(), PredictionContext.EMPTY, contextCache, fullCtx());
|
PredictionContext r = PredictionContext.merge(x(), PredictionContext.EMPTY, fullCtx());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -72,7 +70,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void test_$_x() {
|
@Test public void test_$_x() {
|
||||||
PredictionContext r = PredictionContext.merge(PredictionContext.EMPTY, x(), contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(PredictionContext.EMPTY, x(), rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -83,7 +81,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void test_$_x_fullctx() {
|
@Test public void test_$_x_fullctx() {
|
||||||
PredictionContext r = PredictionContext.merge(PredictionContext.EMPTY, x(), contextCache, fullCtx());
|
PredictionContext r = PredictionContext.merge(PredictionContext.EMPTY, x(), fullCtx());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -96,7 +94,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void test_a_a() {
|
@Test public void test_a_a() {
|
||||||
PredictionContext r = PredictionContext.merge(a(), a(), contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a(), a(), rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -112,7 +110,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext a1 = a();
|
PredictionContext a1 = a();
|
||||||
PredictionContext x = x();
|
PredictionContext x = x();
|
||||||
PredictionContext a2 = createSingleton(x, 1);
|
PredictionContext a2 = createSingleton(x, 1);
|
||||||
PredictionContext r = PredictionContext.merge(a1, a2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a1, a2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -128,7 +126,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext a1 = a();
|
PredictionContext a1 = a();
|
||||||
PredictionContext x = x();
|
PredictionContext x = x();
|
||||||
PredictionContext a2 = createSingleton(x, 1);
|
PredictionContext a2 = createSingleton(x, 1);
|
||||||
PredictionContext r = PredictionContext.merge(a1, a2, contextCache, fullCtx());
|
PredictionContext r = PredictionContext.merge(a1, a2, fullCtx());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -146,7 +144,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext x = x();
|
PredictionContext x = x();
|
||||||
PredictionContext a1 = createSingleton(x, 1);
|
PredictionContext a1 = createSingleton(x, 1);
|
||||||
PredictionContext a2 = a();
|
PredictionContext a2 = a();
|
||||||
PredictionContext r = PredictionContext.merge(a1, a2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a1, a2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -162,7 +160,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext x = x();
|
PredictionContext x = x();
|
||||||
PredictionContext a1 = createSingleton(x, 1);
|
PredictionContext a1 = createSingleton(x, 1);
|
||||||
PredictionContext a2 = a();
|
PredictionContext a2 = a();
|
||||||
PredictionContext r = PredictionContext.merge(a1, a2, contextCache, fullCtx());
|
PredictionContext r = PredictionContext.merge(a1, a2, fullCtx());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -177,7 +175,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void test_a_b() {
|
@Test public void test_a_b() {
|
||||||
PredictionContext r = PredictionContext.merge(a(), b(), contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a(), b(), rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -194,7 +192,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext x = x();
|
PredictionContext x = x();
|
||||||
PredictionContext a1 = createSingleton(x, 1);
|
PredictionContext a1 = createSingleton(x, 1);
|
||||||
PredictionContext a2 = createSingleton(x, 1);
|
PredictionContext a2 = createSingleton(x, 1);
|
||||||
PredictionContext r = PredictionContext.merge(a1, a2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a1, a2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -213,7 +211,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext x2 = x();
|
PredictionContext x2 = x();
|
||||||
PredictionContext a1 = createSingleton(x1, 1);
|
PredictionContext a1 = createSingleton(x1, 1);
|
||||||
PredictionContext a2 = createSingleton(x2, 1);
|
PredictionContext a2 = createSingleton(x2, 1);
|
||||||
PredictionContext r = PredictionContext.merge(a1, a2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a1, a2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -234,7 +232,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext b2 = createSingleton(x2, 2);
|
PredictionContext b2 = createSingleton(x2, 2);
|
||||||
PredictionContext a1 = createSingleton(b1, 1);
|
PredictionContext a1 = createSingleton(b1, 1);
|
||||||
PredictionContext a2 = createSingleton(b2, 1);
|
PredictionContext a2 = createSingleton(b2, 1);
|
||||||
PredictionContext r = PredictionContext.merge(a1, a2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a1, a2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -257,7 +255,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext c = createSingleton(x2, 3);
|
PredictionContext c = createSingleton(x2, 3);
|
||||||
PredictionContext a1 = createSingleton(b, 1);
|
PredictionContext a1 = createSingleton(b, 1);
|
||||||
PredictionContext a2 = createSingleton(c, 1);
|
PredictionContext a2 = createSingleton(c, 1);
|
||||||
PredictionContext r = PredictionContext.merge(a1, a2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a1, a2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -278,7 +276,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext x = x();
|
PredictionContext x = x();
|
||||||
PredictionContext a = createSingleton(x, 1);
|
PredictionContext a = createSingleton(x, 1);
|
||||||
PredictionContext b = createSingleton(x, 2);
|
PredictionContext b = createSingleton(x, 2);
|
||||||
PredictionContext r = PredictionContext.merge(a, b, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a, b, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -298,7 +296,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext x2 = x();
|
PredictionContext x2 = x();
|
||||||
PredictionContext a = createSingleton(x1, 1);
|
PredictionContext a = createSingleton(x1, 1);
|
||||||
PredictionContext b = createSingleton(x2, 2);
|
PredictionContext b = createSingleton(x2, 2);
|
||||||
PredictionContext r = PredictionContext.merge(a, b, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a, b, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -316,7 +314,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
@Test public void test_ax_by() {
|
@Test public void test_ax_by() {
|
||||||
PredictionContext a = createSingleton(x(), 1);
|
PredictionContext a = createSingleton(x(), 1);
|
||||||
PredictionContext b = createSingleton(y(), 2);
|
PredictionContext b = createSingleton(y(), 2);
|
||||||
PredictionContext r = PredictionContext.merge(a, b, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a, b, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -337,7 +335,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext x2 = x();
|
PredictionContext x2 = x();
|
||||||
PredictionContext a = a();
|
PredictionContext a = a();
|
||||||
PredictionContext b = createSingleton(x2, 2);
|
PredictionContext b = createSingleton(x2, 2);
|
||||||
PredictionContext r = PredictionContext.merge(a, b, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a, b, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -354,7 +352,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext x2 = x();
|
PredictionContext x2 = x();
|
||||||
PredictionContext a = a();
|
PredictionContext a = a();
|
||||||
PredictionContext b = createSingleton(x2, 2);
|
PredictionContext b = createSingleton(x2, 2);
|
||||||
PredictionContext r = PredictionContext.merge(a, b, contextCache, fullCtx());
|
PredictionContext r = PredictionContext.merge(a, b, fullCtx());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -376,7 +374,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
PredictionContext f = createSingleton(x2, 6);
|
PredictionContext f = createSingleton(x2, 6);
|
||||||
PredictionContext a = createSingleton(e, 1);
|
PredictionContext a = createSingleton(e, 1);
|
||||||
PredictionContext b = createSingleton(f, 2);
|
PredictionContext b = createSingleton(f, 2);
|
||||||
PredictionContext r = PredictionContext.merge(a, b, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(a, b, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -402,7 +400,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
@Test public void test_A$_A$_fullctx() {
|
@Test public void test_A$_A$_fullctx() {
|
||||||
ArrayPredictionContext A1 = array(PredictionContext.EMPTY);
|
ArrayPredictionContext A1 = array(PredictionContext.EMPTY);
|
||||||
ArrayPredictionContext A2 = array(PredictionContext.EMPTY);
|
ArrayPredictionContext A2 = array(PredictionContext.EMPTY);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, fullCtx());
|
PredictionContext r = PredictionContext.merge(A1, A2, fullCtx());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -418,7 +416,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext c = c();
|
SingletonPredictionContext c = c();
|
||||||
ArrayPredictionContext A1 = array(a, b);
|
ArrayPredictionContext A1 = array(a, b);
|
||||||
ArrayPredictionContext A2 = array(c);
|
ArrayPredictionContext A2 = array(c);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -437,7 +435,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext a2 = a();
|
SingletonPredictionContext a2 = a();
|
||||||
ArrayPredictionContext A1 = array(a1);
|
ArrayPredictionContext A1 = array(a1);
|
||||||
ArrayPredictionContext A2 = array(a2);
|
ArrayPredictionContext A2 = array(a2);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -455,7 +453,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext c = c();
|
SingletonPredictionContext c = c();
|
||||||
ArrayPredictionContext A1 = array(a);
|
ArrayPredictionContext A1 = array(a);
|
||||||
ArrayPredictionContext A2 = array(b, c);
|
ArrayPredictionContext A2 = array(b, c);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -475,7 +473,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext c = c();
|
SingletonPredictionContext c = c();
|
||||||
ArrayPredictionContext A1 = array(a, c);
|
ArrayPredictionContext A1 = array(a, c);
|
||||||
ArrayPredictionContext A2 = array(b);
|
ArrayPredictionContext A2 = array(b);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -492,7 +490,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
@Test public void test_Aab_Aa() { // a,b + a
|
@Test public void test_Aab_Aa() { // a,b + a
|
||||||
ArrayPredictionContext A1 = array(a(), b());
|
ArrayPredictionContext A1 = array(a(), b());
|
||||||
ArrayPredictionContext A2 = array(a());
|
ArrayPredictionContext A2 = array(a());
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -508,7 +506,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
@Test public void test_Aab_Ab() { // a,b + b
|
@Test public void test_Aab_Ab() { // a,b + b
|
||||||
ArrayPredictionContext A1 = array(a(), b());
|
ArrayPredictionContext A1 = array(a(), b());
|
||||||
ArrayPredictionContext A2 = array(b());
|
ArrayPredictionContext A2 = array(b());
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -526,7 +524,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext b = createSingleton(y(), 2);
|
SingletonPredictionContext b = createSingleton(y(), 2);
|
||||||
ArrayPredictionContext A1 = array(a);
|
ArrayPredictionContext A1 = array(a);
|
||||||
ArrayPredictionContext A2 = array(b);
|
ArrayPredictionContext A2 = array(b);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -548,7 +546,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext a2 = createSingleton(y(), 1);
|
SingletonPredictionContext a2 = createSingleton(y(), 1);
|
||||||
ArrayPredictionContext A1 = array(a1);
|
ArrayPredictionContext A1 = array(a1);
|
||||||
ArrayPredictionContext A2 = array(a2);
|
ArrayPredictionContext A2 = array(a2);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -568,7 +566,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext a2 = createSingleton(y(), 1);
|
SingletonPredictionContext a2 = createSingleton(y(), 1);
|
||||||
ArrayPredictionContext A1 = array(a1, c());
|
ArrayPredictionContext A1 = array(a1, c());
|
||||||
ArrayPredictionContext A2 = array(a2, d());
|
ArrayPredictionContext A2 = array(a2, d());
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -592,7 +590,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext d = createSingleton(x(), 4);
|
SingletonPredictionContext d = createSingleton(x(), 4);
|
||||||
ArrayPredictionContext A1 = array(a, b);
|
ArrayPredictionContext A1 = array(a, b);
|
||||||
ArrayPredictionContext A2 = array(c, d);
|
ArrayPredictionContext A2 = array(c, d);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -622,7 +620,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext d = createSingleton(x(), 4);
|
SingletonPredictionContext d = createSingleton(x(), 4);
|
||||||
ArrayPredictionContext A1 = array(a, b1);
|
ArrayPredictionContext A1 = array(a, b1);
|
||||||
ArrayPredictionContext A2 = array(b2, d);
|
ArrayPredictionContext A2 = array(b2, d);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -649,7 +647,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext d = createSingleton(x(), 4);
|
SingletonPredictionContext d = createSingleton(x(), 4);
|
||||||
ArrayPredictionContext A1 = array(a, b1);
|
ArrayPredictionContext A1 = array(a, b1);
|
||||||
ArrayPredictionContext A2 = array(b2, d);
|
ArrayPredictionContext A2 = array(b2, d);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -677,7 +675,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext d = createSingleton(u(), 4);
|
SingletonPredictionContext d = createSingleton(u(), 4);
|
||||||
ArrayPredictionContext A1 = array(a, b1);
|
ArrayPredictionContext A1 = array(a, b1);
|
||||||
ArrayPredictionContext A2 = array(b2, d);
|
ArrayPredictionContext A2 = array(b2, d);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
@ -702,7 +700,7 @@ public class TestGraphNodes extends TestCase {
|
||||||
SingletonPredictionContext d = createSingleton(u(), 4);
|
SingletonPredictionContext d = createSingleton(u(), 4);
|
||||||
ArrayPredictionContext A1 = array(a, b);
|
ArrayPredictionContext A1 = array(a, b);
|
||||||
ArrayPredictionContext A2 = array(c, d);
|
ArrayPredictionContext A2 = array(c, d);
|
||||||
PredictionContext r = PredictionContext.merge(A1, A2, contextCache, rootIsWildcard());
|
PredictionContext r = PredictionContext.merge(A1, A2, rootIsWildcard());
|
||||||
System.out.println(PredictionContext.toDOTString(r));
|
System.out.println(PredictionContext.toDOTString(r));
|
||||||
String expecting =
|
String expecting =
|
||||||
"digraph G {\n" +
|
"digraph G {\n" +
|
||||||
|
|
Loading…
Reference in New Issue