forked from jasder/antlr
v4: DFAState.configs now ATNConfig[] instead of OrderedHashSet<ATNConfig>
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9511]
This commit is contained in:
parent
4d942c37c8
commit
682e60b065
|
@ -37,12 +37,12 @@ public class LexerNoViableAltException extends RecognitionException {
|
|||
public int startIndex;
|
||||
|
||||
/** Which configurations did we try at input.index() that couldn't match input.LA(1)? */
|
||||
public OrderedHashSet<ATNConfig> deadEndConfigs;
|
||||
public ATNConfig[] deadEndConfigs;
|
||||
|
||||
public LexerNoViableAltException(Lexer lexer,
|
||||
CharStream input,
|
||||
int startIndex,
|
||||
OrderedHashSet<ATNConfig> deadEndConfigs) {
|
||||
ATNConfig[] deadEndConfigs) {
|
||||
super(lexer, input, null);
|
||||
this.startIndex = startIndex;
|
||||
this.deadEndConfigs = deadEndConfigs;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
package org.antlr.v4.runtime;
|
||||
|
||||
import org.antlr.v4.runtime.atn.ATNConfig;
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
|
||||
/** The parser could not decide which path in the decision to take based
|
||||
|
@ -36,7 +37,7 @@ import org.antlr.v4.runtime.misc.OrderedHashSet;
|
|||
*/
|
||||
public class NoViableAltException extends RecognitionException {
|
||||
/** Which configurations did we try at input.index() that couldn't match input.LT(1)? */
|
||||
public OrderedHashSet<ATNConfig> deadEndConfigs;
|
||||
public ATNConfig[] deadEndConfigs;
|
||||
|
||||
/** The token object at the start index; the input stream might
|
||||
* not be buffering tokens so get a reference to it. (At the
|
||||
|
@ -59,7 +60,7 @@ public class NoViableAltException extends RecognitionException {
|
|||
Token startToken,
|
||||
Token offendingToken,
|
||||
Symbol offendingNode,
|
||||
OrderedHashSet<ATNConfig> deadEndConfigs,
|
||||
@Nullable ATNConfig[] deadEndConfigs,
|
||||
ParserRuleContext ctx)
|
||||
{
|
||||
super(recognizer, input, ctx);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
package org.antlr.v4.runtime;
|
||||
|
||||
import org.antlr.v4.runtime.atn.ATNConfig;
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
import org.antlr.v4.runtime.tree.ASTNodeStream;
|
||||
import org.antlr.v4.runtime.tree.TreeParser;
|
||||
|
@ -50,7 +51,7 @@ public class NoViableTreeGrammarAltException extends NoViableAltException {
|
|||
ASTNodeStream<Symbol> input,
|
||||
Symbol startNode,
|
||||
Symbol offendingNode,
|
||||
OrderedHashSet<ATNConfig> deadEndConfigs,
|
||||
@Nullable ATNConfig[] deadEndConfigs,
|
||||
ParserRuleContext ctx) {
|
||||
super(recognizer, input,
|
||||
input.getTreeAdaptor().getToken(startNode),
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.antlr.v4.runtime.misc.OrderedHashSet;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/** "dup" of ParserInterpreter */
|
||||
public class LexerATNSimulator extends ATNSimulator {
|
||||
|
@ -339,7 +340,7 @@ public class LexerATNSimulator extends ATNSimulator {
|
|||
if ( t==CharStream.EOF && input.index()==startIndex ) {
|
||||
return Token.EOF;
|
||||
}
|
||||
throw new LexerNoViableAltException(recog, input, startIndex, reach);
|
||||
throw new LexerNoViableAltException(recog, input, startIndex, reach.toArray(new ATNConfig[reach.size()]));
|
||||
}
|
||||
|
||||
int ruleIndex = atnPrevAccept.config.state.ruleIndex;
|
||||
|
@ -545,10 +546,10 @@ public class LexerATNSimulator extends ATNSimulator {
|
|||
if ( dfa_debug ) {
|
||||
System.out.format("no edge for %s\n", getTokenName(input.LA(1)));
|
||||
System.out.format("ATN exec upon %s at DFA state %d = %s\n",
|
||||
input.substring(startIndex, input.index()), s.stateNumber, s.configs);
|
||||
input.substring(startIndex, input.index()), s.stateNumber, Arrays.toString(s.configs));
|
||||
}
|
||||
|
||||
int ttype = exec(input, s.configs);
|
||||
int ttype = exec(input, new OrderedHashSet<ATNConfig>(s.configs));
|
||||
|
||||
if ( dfa_debug ) {
|
||||
System.out.format("back from DFA update, ttype=%d, dfa[mode %d]=\n%s\n",
|
||||
|
@ -653,8 +654,9 @@ public class LexerATNSimulator extends ATNSimulator {
|
|||
if ( traversedPredicate ) return null; // cannot cache
|
||||
|
||||
newState.stateNumber = dfa[mode].states.size();
|
||||
newState.configs = new OrderedHashSet<ATNConfig>();
|
||||
newState.configs.addAll(configs);
|
||||
// Note: the configs array is copied in the DFAState ctor, no need to copy again
|
||||
//newState.configs = new OrderedHashSet<ATNConfig>();
|
||||
//newState.configs.addAll(configs);
|
||||
dfa[mode].states.put(newState, newState);
|
||||
return newState;
|
||||
}
|
||||
|
|
|
@ -202,7 +202,7 @@ public class ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
// start all over with ATN; can't use DFA
|
||||
input.seek(startIndex);
|
||||
DFA throwAwayDFA = new DFA(dfa.atnStartState);
|
||||
int alt = execATN(input, throwAwayDFA, startIndex, s0.configs, false);
|
||||
int alt = execATN(input, throwAwayDFA, startIndex, new OrderedHashSet<ATNConfig>(s0.configs), false);
|
||||
s.ctxToPrediction.put(outerContext, alt);
|
||||
return alt;
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ public class ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
" at DFA state "+s.stateNumber);
|
||||
}
|
||||
try {
|
||||
alt = execATN(input, dfa, startIndex, s.configs, false);
|
||||
alt = execATN(input, dfa, startIndex, new OrderedHashSet<ATNConfig>(s.configs), false);
|
||||
// this adds edge even if next state is accept for
|
||||
// same alt; e.g., s0-A->:s1=>2-B->:s2=>2
|
||||
// TODO: This next stuff kills edge, but extra states remain. :(
|
||||
|
@ -1033,8 +1033,9 @@ public class ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
DFAState newState = proposed;
|
||||
|
||||
newState.stateNumber = dfa.states.size();
|
||||
newState.configs = new OrderedHashSet<ATNConfig>();
|
||||
newState.configs.addAll(configs);
|
||||
// Note: the configs array is copied in the DFAState ctor, no need to copy again
|
||||
//newState.configs = new OrderedHashSet<ATNConfig>();
|
||||
//newState.configs.addAll(configs);
|
||||
dfa.states.put(newState, newState);
|
||||
if ( debug ) System.out.println("adding new DFA state: "+newState);
|
||||
return newState;
|
||||
|
@ -1100,7 +1101,16 @@ public class ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
@NotNull
|
||||
public NoViableAltException noViableAlt(@NotNull SymbolStream<Symbol> input,
|
||||
@NotNull ParserRuleContext outerContext,
|
||||
@NotNull OrderedHashSet<ATNConfig> configs,
|
||||
@NotNull Set<ATNConfig> configs,
|
||||
int startIndex)
|
||||
{
|
||||
return noViableAlt(input, outerContext, configs.toArray(new ATNConfig[configs.size()]), startIndex);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public NoViableAltException noViableAlt(@NotNull SymbolStream<Symbol> input,
|
||||
@NotNull ParserRuleContext outerContext,
|
||||
@NotNull ATNConfig[] configs,
|
||||
int startIndex)
|
||||
{
|
||||
if ( parser instanceof TreeParser) {
|
||||
|
|
|
@ -35,10 +35,7 @@ import org.antlr.v4.runtime.atn.SemanticContext;
|
|||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/** A DFA state represents a set of possible ATN configurations.
|
||||
* As Aho, Sethi, Ullman p. 117 says "The DFA uses its state
|
||||
|
@ -69,7 +66,7 @@ public class DFAState {
|
|||
|
||||
/** The set of ATN configurations (state,alt,context) for this DFA state */
|
||||
@Nullable
|
||||
public OrderedHashSet<ATNConfig> configs = new OrderedHashSet<ATNConfig>();
|
||||
public ATNConfig[] configs;
|
||||
|
||||
/** edges[symbol] points to target of symbol */
|
||||
@Nullable
|
||||
|
@ -139,17 +136,21 @@ public class DFAState {
|
|||
|
||||
public DFAState(int stateNumber) { this.stateNumber = stateNumber; }
|
||||
|
||||
public DFAState(OrderedHashSet<ATNConfig> configs) { this.configs = configs; }
|
||||
public DFAState(OrderedHashSet<ATNConfig> configs) { this.configs = configs.elements().toArray(new ATNConfig[configs.size()]); }
|
||||
|
||||
/** Get the set of all alts mentioned by all ATN configurations in this
|
||||
* DFA state.
|
||||
*/
|
||||
public Set<Integer> getAltSet() {
|
||||
// TODO (sam): what to do when configs==null?
|
||||
if (configs == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Set<Integer> alts = new HashSet<Integer>();
|
||||
for (ATNConfig c : configs) {
|
||||
alts.add(c.alt);
|
||||
}
|
||||
|
||||
if ( alts.size()==0 ) return null;
|
||||
return alts;
|
||||
}
|
||||
|
@ -167,11 +168,15 @@ public class DFAState {
|
|||
/** A decent hash for a DFA state is the sum of the ATN state/alt pairs. */
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// TODO (sam): what to do when configs==null?
|
||||
if (configs == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int h = 0;
|
||||
for (ATNConfig c : configs) {
|
||||
h += c.alt;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
@ -190,9 +195,9 @@ public class DFAState {
|
|||
public boolean equals(Object o) {
|
||||
// compare set of ATN configurations in this set with other
|
||||
if ( this==o ) return true;
|
||||
if (!(o instanceof DFAState)) return false;
|
||||
DFAState other = (DFAState)o;
|
||||
// TODO (sam): what to do when configs==null?
|
||||
boolean sameSet = this.configs.equals(other.configs);
|
||||
boolean sameSet = this.configs == other.configs || (this.configs != null && Arrays.equals(this.configs, other.configs));
|
||||
// System.out.println("DFAState.equals: "+configs+(sameSet?"==":"!=")+other.configs);
|
||||
return sameSet;
|
||||
}
|
||||
|
@ -200,7 +205,7 @@ public class DFAState {
|
|||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(stateNumber + ":" + configs);
|
||||
buf.append(stateNumber).append(":").append(Arrays.toString(configs));
|
||||
if ( isAcceptState ) {
|
||||
buf.append("=>");
|
||||
if ( predicates!=null ) {
|
||||
|
|
|
@ -29,10 +29,7 @@
|
|||
|
||||
package org.antlr.v4.runtime.misc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/** A HashMap that remembers the order that the elements were added.
|
||||
* You can alter the ith element with set(i,value) too :) Unique list.
|
||||
|
@ -43,6 +40,13 @@ public class OrderedHashSet<T> extends LinkedHashSet<T> {
|
|||
/** Track the elements as they are added to the set */
|
||||
protected List<T> elements = new ArrayList<T>();
|
||||
|
||||
public OrderedHashSet() {
|
||||
}
|
||||
|
||||
public OrderedHashSet(T[] values) {
|
||||
Collections.addAll(this, values);
|
||||
}
|
||||
|
||||
public T get(int i) {
|
||||
return elements.get(i);
|
||||
}
|
||||
|
@ -94,6 +98,12 @@ public class OrderedHashSet<T> extends LinkedHashSet<T> {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
} else if (!(o instanceof OrderedHashSet<?>)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// System.out.print("equals " + this + ", " + o+" = ");
|
||||
boolean same = elements!=null && elements.equals(((OrderedHashSet<?>)o).elements);
|
||||
// System.out.println(same);
|
||||
|
|
|
@ -32,6 +32,7 @@ package org.antlr.v4.tool;
|
|||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.*;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
import org.stringtemplate.v4.*;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -106,25 +107,24 @@ public class DOTGenerator {
|
|||
|
||||
protected String getStateLabel(DFAState s) {
|
||||
if ( s==null ) return "null";
|
||||
StringBuffer buf = new StringBuffer(250);
|
||||
StringBuilder buf = new StringBuilder(250);
|
||||
buf.append('s');
|
||||
buf.append(s.stateNumber);
|
||||
if ( s.isAcceptState ) {
|
||||
buf.append("=>"+s.prediction);
|
||||
buf.append("=>").append(s.prediction);
|
||||
}
|
||||
// if ( Tool.internalOption_ShowATNConfigsInDFA ) {
|
||||
if ( false ) {
|
||||
Set<Integer> alts = ((DFAState)s).getAltSet();
|
||||
Set<Integer> alts = s.getAltSet();
|
||||
if ( alts!=null ) {
|
||||
buf.append("\\n");
|
||||
// separate alts
|
||||
List<Integer> altList = new ArrayList<Integer>();
|
||||
altList.addAll(alts);
|
||||
Collections.sort(altList);
|
||||
Set<ATNConfig> configurations = ((DFAState)s).configs;
|
||||
Set<ATNConfig> configurations = new OrderedHashSet<ATNConfig>(s.configs);
|
||||
for (int altIndex = 0; altIndex < altList.size(); altIndex++) {
|
||||
Integer altI = (Integer) altList.get(altIndex);
|
||||
int alt = altI.intValue();
|
||||
int alt = altList.get(altIndex);
|
||||
if ( altIndex>0 ) {
|
||||
buf.append("\\n");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue