Pulled Sam's new IntegerList

This commit is contained in:
Terence Parr 2012-07-30 15:20:43 -07:00
commit c893f2af08
12 changed files with 404 additions and 53 deletions

View File

@ -29,9 +29,9 @@
package org.antlr.v4.runtime;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.misc.IntegerStack;
import org.antlr.v4.runtime.misc.Interval;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.List;
@ -91,7 +91,7 @@ public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
/** The token type for the current token */
public int _type;
public ArrayDeque<Integer> _modeStack = new ArrayDeque<Integer>();
public final IntegerStack _modeStack = new IntegerStack();
public int _mode = Lexer.DEFAULT_MODE;
/** You can set the text for the current token to override what is in

View File

@ -0,0 +1,291 @@
/*
[The "BSD license"]
Copyright (c) 2012 Terence Parr
Copyright (c) 2012 Sam Harwell
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.misc;
import java.util.Arrays;
import java.util.Collection;
/**
*
* @author Sam Harwell
*/
public class IntegerList {
private static int[] EMPTY_DATA = new int[0];
private static final int INITIAL_SIZE = 4;
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
@NotNull
private int[] _data;
private int _size;
public IntegerList() {
_data = EMPTY_DATA;
}
public IntegerList(int capacity) {
if (capacity < 0) {
throw new IllegalArgumentException();
}
if (capacity == 0) {
_data = EMPTY_DATA;
} else {
_data = new int[capacity];
}
}
public IntegerList(@NotNull IntegerList list) {
_data = list._data.clone();
_size = list._size;
}
public IntegerList(@NotNull Collection<Integer> list) {
this(list.size());
for (Integer value : list) {
add(value);
}
}
public final void add(int value) {
if (_data.length == _size) {
ensureCapacity(_size + 1);
}
_data[_size] = value;
_size++;
}
public final void addAll(int[] array) {
ensureCapacity(_size + array.length);
System.arraycopy(array, 0, _data, _size, array.length);
_size += array.length;
}
public final void addAll(IntegerList list) {
ensureCapacity(_size + list._size);
System.arraycopy(list._data, 0, _data, _size, list._size);
_size += list._size;
}
public final void addAll(Collection<Integer> list) {
ensureCapacity(_size + list.size());
int current = 0;
for (int x : list) {
_data[_size + current] = x;
}
_size += list.size();
}
public final int get(int index) {
if (index < 0 || index >= _size) {
throw new IndexOutOfBoundsException();
}
return _data[index];
}
public final boolean contains(int value) {
for (int i = 0; i < _size; i++) {
if (_data[i] == value) {
return true;
}
}
return false;
}
public final int set(int index, int value) {
if (index < 0 || index >= _size) {
throw new IndexOutOfBoundsException();
}
int previous = _data[index];
_data[index] = value;
return previous;
}
public final int removeAt(int index) {
int value = get(index);
System.arraycopy(_data, index + 1, _data, index, _size - index - 1);
_data[_size - 1] = 0;
_size--;
return value;
}
public final void removeRange(int fromIndex, int toIndex) {
if (fromIndex < 0 || toIndex < 0 || fromIndex > _size || toIndex > _size) {
throw new IndexOutOfBoundsException();
}
if (fromIndex > toIndex) {
throw new IllegalArgumentException();
}
System.arraycopy(_data, toIndex, _data, fromIndex, _size - toIndex);
Arrays.fill(_data, _size - (toIndex - fromIndex), _size, 0);
_size -= (toIndex - fromIndex);
}
public final boolean isEmpty() {
return _size == 0;
}
public final int size() {
return _size;
}
public final void trimToSize() {
if (_data.length == _size) {
return;
}
_data = Arrays.copyOf(_data, _size);
}
public final void clear() {
Arrays.fill(_data, 0, _size, 0);
_size = 0;
}
public final int[] toArray() {
if (_size == 0) {
return EMPTY_DATA;
}
return Arrays.copyOf(_data, _size);
}
public final void sort() {
Arrays.sort(_data, 0, _size);
}
/**
* Compares the specified object with this list for equality. Returns
* {@code true} if and only if the specified object is also an {@code IntegerList},
* both lists have the same size, and all corresponding pairs of elements in
* the two lists are equal. In other words, two lists are defined to be
* equal if they contain the same elements in the same order.
* <p>
* This implementation first checks if the specified object is this
* list. If so, it returns {@code true}; if not, it checks if the
* specified object is an {@code IntegerList}. If not, it returns {@code false};
* if so, it checks the size of both lists. If the lists are not the same size,
* it returns {@code false}; otherwise it iterates over both lists, comparing
* corresponding pairs of elements. If any comparison returns {@code false},
* this method returns {@code false}.
*
* @param o the object to be compared for equality with this list
* @return {@code true} if the specified object is equal to this list
*/
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof IntegerList)) {
return false;
}
IntegerList other = (IntegerList)o;
if (_size != other._size) {
return false;
}
for (int i = 0; i < _size; i++) {
if (_data[i] != other._data[i]) {
return false;
}
}
return true;
}
/**
* Returns the hash code value for this list.
*
* <p>This implementation uses exactly the code that is used to define the
* list hash function in the documentation for the {@link List#hashCode}
* method.
*
* @return the hash code value for this list
*/
@Override
public int hashCode() {
int hashCode = 1;
for (int i = 0; i < _size; i++) {
hashCode = 31*hashCode + _data[i];
}
return hashCode;
}
/**
* Returns a string representation of this list.
*/
@Override
public String toString() {
return Arrays.toString(toArray());
}
public final int binarySearch(int key) {
return Arrays.binarySearch(_data, key);
}
public final int binarySearch(int fromIndex, int toIndex, int key) {
return Arrays.binarySearch(_data, fromIndex, toIndex, key);
}
private void ensureCapacity(int capacity) {
if (capacity < 0 || capacity > MAX_ARRAY_SIZE) {
throw new OutOfMemoryError();
}
int newLength;
if (_data.length == 0) {
newLength = INITIAL_SIZE;
} else {
newLength = _data.length;
}
while (newLength < capacity) {
newLength = newLength * 2;
if (newLength < 0 || newLength > MAX_ARRAY_SIZE) {
newLength = MAX_ARRAY_SIZE;
}
}
_data = Arrays.copyOf(_data, newLength);
}
}

View File

@ -0,0 +1,61 @@
/*
[The "BSD license"]
Copyright (c) 2012 Terence Parr
Copyright (c) 2012 Sam Harwell
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.misc;
/**
*
* @author Sam Harwell
*/
public class IntegerStack extends IntegerList {
public IntegerStack() {
}
public IntegerStack(int capacity) {
super(capacity);
}
public IntegerStack(@NotNull IntegerStack list) {
super(list);
}
public final void push(int value) {
add(value);
}
public final int pop() {
return removeAt(size() - 1);
}
public final int peek() {
return get(size() - 1);
}
}

View File

@ -530,6 +530,20 @@ public class IntervalSet implements IntSet {
return n;
}
public IntegerList toIntegerList() {
IntegerList values = new IntegerList(size());
int n = intervals.size();
for (int i = 0; i < n; i++) {
Interval I = intervals.get(i);
int a = I.a;
int b = I.b;
for (int v=a; v<=b; v++) {
values.add(v);
}
}
return values;
}
@Override
public List<Integer> toList() {
List<Integer> values = new ArrayList<Integer>();
@ -579,19 +593,7 @@ public class IntervalSet implements IntSet {
}
public int[] toArray() {
int[] values = new int[size()];
int n = intervals.size();
int j = 0;
for (int i = 0; i < n; i++) {
Interval I = intervals.get(i);
int a = I.a;
int b = I.b;
for (int v=a; v<=b; v++) {
values[j] = v;
j++;
}
}
return values;
return toIntegerList().toArray();
}
@Override

View File

@ -43,6 +43,7 @@ import org.antlr.v4.runtime.atn.RangeTransition;
import org.antlr.v4.runtime.atn.RuleTransition;
import org.antlr.v4.runtime.atn.SetTransition;
import org.antlr.v4.runtime.atn.Transition;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.tool.Grammar;
@ -82,8 +83,8 @@ public class ATNSerializer {
*
* Convenient to pack into unsigned shorts to make as Java string.
*/
public List<Integer> serialize() {
List<Integer> data = new ArrayList<Integer>();
public IntegerList serialize() {
IntegerList data = new IntegerList();
// convert grammar type to ATN const to avoid dependence on ANTLRParser
if ( g.getType()== ANTLRParser.LEXER ) data.add(ATN.LEXER);
else if ( g.getType()== ANTLRParser.PARSER ) data.add(ATN.PARSER);
@ -288,7 +289,7 @@ public class ATNSerializer {
return new String(Utils.toCharArray(getSerialized(g, atn)));
}
public static List<Integer> getSerialized(Grammar g, ATN atn) {
public static IntegerList getSerialized(Grammar g, ATN atn) {
return new ATNSerializer(g, atn).serialize();
}
@ -297,7 +298,7 @@ public class ATNSerializer {
}
public static String getDecoded(Grammar g, ATN atn) {
List<Integer> serialized = getSerialized(g, atn);
IntegerList serialized = getSerialized(g, atn);
char[] data = Utils.toCharArray(serialized);
return new ATNSerializer(g, atn).decode(data);
}

View File

@ -32,17 +32,19 @@ package org.antlr.v4.codegen.model;
import org.antlr.v4.automata.ATNSerializer;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.misc.IntegerList;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
public class SerializedATN extends OutputModelObject {
// TODO: make this into a kind of decl or multiple?
public List<String> serialized;
public SerializedATN(OutputModelFactory factory, ATN atn) {
super(factory);
List<Integer> data = ATNSerializer.getSerialized(factory.getGrammar(), atn);
IntegerList data = ATNSerializer.getSerialized(factory.getGrammar(), atn);
serialized = new ArrayList<String>(data.size());
for (int c : data) {
for (int c : data.toArray()) {
String encoded = factory.getGenerator().target.encodeIntAsCharEscape(c == -1 ? Character.MAX_VALUE : c);
serialized.add(encoded);
}

View File

@ -29,9 +29,12 @@
package org.antlr.v4.misc;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.tool.ast.GrammarAST;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** */
public class Utils {
@ -137,13 +140,6 @@ public class Utils {
// return x;
// }
public static int[] toIntArray(List<Integer> list) {
if ( list==null ) return null;
int[] a = new int[list.size()];
for (int i=0; i<list.size(); i++) a[i] = list.get(i);
return a;
}
public static String capitalize(String s) {
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
@ -152,11 +148,11 @@ public class Utils {
return Character.toLowerCase(s.charAt(0)) + s.substring(1);
}
public static char[] toCharArray(List<Integer> data) {
public static char[] toCharArray(IntegerList data) {
if ( data==null ) return null;
char[] cdata = new char[data.size()];
for (int i=0; i<data.size(); i++) {
cdata[i] = (char)(int)data.get(i);
cdata[i] = (char)data.get(i);
}
return cdata;
}

View File

@ -51,12 +51,12 @@ import org.antlr.v4.runtime.atn.StarLoopbackState;
import org.antlr.v4.runtime.atn.Transition;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.dfa.DFAState;
import org.antlr.v4.runtime.misc.IntegerList;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupDir;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@ -144,9 +144,9 @@ public class DOTGenerator {
if ( alts!=null ) {
buf.append("\\n");
// separate alts
List<Integer> altList = new ArrayList<Integer>();
IntegerList altList = new IntegerList();
altList.addAll(alts);
Collections.sort(altList);
altList.sort();
Set<ATNConfig> configurations = s.configs;
for (int altIndex = 0; altIndex < altList.size(); altIndex++) {
int alt = altList.get(altIndex);

View File

@ -46,6 +46,7 @@ import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.IntSet;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.Nullable;
@ -59,7 +60,6 @@ import org.antlr.v4.tool.ast.TerminalAST;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@ -467,9 +467,9 @@ public class Grammar implements AttributeResolver {
return tokenName;
}
public List<String> getTokenDisplayNames(Collection<Integer> types) {
public List<String> getTokenDisplayNames(IntegerList types) {
List<String> names = new ArrayList<String>();
for (int t : types) names.add(getTokenDisplayName(t));
for (int t : types.toArray()) names.add(getTokenDisplayName(t));
return names;
}

View File

@ -50,6 +50,7 @@ import org.antlr.v4.runtime.atn.ATNState;
import org.antlr.v4.runtime.atn.DecisionState;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.Nullable;
import org.antlr.v4.semantics.SemanticPipeline;
@ -184,8 +185,8 @@ public abstract class BaseTest {
// dfa.minimized = dmin.minimize();
// }
List<Integer> getTypesFromString(Grammar g, String expecting) {
List<Integer> expectingTokenTypes = new ArrayList<Integer>();
IntegerList getTypesFromString(Grammar g, String expecting) {
IntegerList expectingTokenTypes = new IntegerList();
if ( expecting!=null && !expecting.trim().isEmpty() ) {
for (String tname : expecting.replace(" ", "").split(",")) {
int ttype = g.getTokenType(tname);
@ -195,9 +196,9 @@ public abstract class BaseTest {
return expectingTokenTypes;
}
public List<Integer> getTokenTypesViaATN(String input, LexerATNSimulator lexerATN) {
public IntegerList getTokenTypesViaATN(String input, LexerATNSimulator lexerATN) {
ANTLRInputStream in = new ANTLRInputStream(input);
List<Integer> tokenTypes = new ArrayList<Integer>();
IntegerList tokenTypes = new IntegerList();
int ttype;
do {
ttype = lexerATN.matchATN(in);
@ -1065,9 +1066,9 @@ public abstract class BaseTest {
public void assertNull(Object object) { try {Assert.assertNull(object);} catch (Error e) {lastTestFailed=true; throw e;} }
public static class IntTokenStream implements TokenStream {
List<Integer> types;
IntegerList types;
int p=0;
public IntTokenStream(List<Integer> types) { this.types = types; }
public IntTokenStream(IntegerList types) { this.types = types; }
@Override
public void consume() { p++; }

View File

@ -6,6 +6,7 @@ import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNState;
import org.antlr.v4.runtime.atn.BlockStartState;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.tool.DOTGenerator;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.LexerGrammar;
@ -13,9 +14,6 @@ import org.antlr.v4.tool.Rule;
import org.antlr.v4.tool.interp.ParserInterpreter;
import org.junit.Test;
import java.util.List;
// NOTICE: TOKENS IN LEXER, PARSER MUST BE SAME OR TOKEN TYPE MISMATCH
// NOTICE: TOKENS IN LEXER, PARSER MUST BE SAME OR TOKEN TYPE MISMATCH
// NOTICE: TOKENS IN LEXER, PARSER MUST BE SAME OR TOKEN TYPE MISMATCH
@ -274,7 +272,7 @@ public class TestATNInterpreter extends BaseTest {
{
ATN lexatn = createATN(lg);
LexerATNSimulator lexInterp = new LexerATNSimulator(lexatn,null,null);
List<Integer> types = getTokenTypesViaATN(inputString, lexInterp);
IntegerList types = getTokenTypesViaATN(inputString, lexInterp);
System.out.println(types);
semanticProcess(lg);

View File

@ -40,6 +40,7 @@ import org.antlr.v4.runtime.atn.DecisionState;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.atn.ParserATNSimulator;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.tool.DOTGenerator;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.LexerGrammar;
@ -47,8 +48,6 @@ import org.antlr.v4.tool.Rule;
import org.antlr.v4.tool.interp.ParserInterpreter;
import org.junit.Test;
import java.util.List;
// NOTICE: TOKENS IN LEXER, PARSER MUST BE SAME OR TOKEN TYPE MISMATCH
// NOTICE: TOKENS IN LEXER, PARSER MUST BE SAME OR TOKEN TYPE MISMATCH
// NOTICE: TOKENS IN LEXER, PARSER MUST BE SAME OR TOKEN TYPE MISMATCH
@ -480,7 +479,7 @@ public class TestATNParserPrediction extends BaseTest {
Tool.internalOption_ShowATNConfigsInDFA = true;
ATN lexatn = createATN(lg);
LexerATNSimulator lexInterp = new LexerATNSimulator(lexatn,null,null);
List<Integer> types = getTokenTypesViaATN(inputString, lexInterp);
IntegerList types = getTokenTypesViaATN(inputString, lexInterp);
System.out.println(types);
semanticProcess(lg);
@ -547,7 +546,7 @@ public class TestATNParserPrediction extends BaseTest {
ParserATNSimulator<Token> interp =
new ParserATNSimulator<Token>(atn, new DFA[atn.getNumberOfDecisions()],null);
List<Integer> types = getTokenTypesViaATN(inputString, lexInterp);
IntegerList types = getTokenTypesViaATN(inputString, lexInterp);
System.out.println(types);
TokenStream input = new IntTokenStream(types);
try {
@ -577,7 +576,7 @@ public class TestATNParserPrediction extends BaseTest {
ParserInterpreter interp = new ParserInterpreter(g, null);
for (int i=0; i<inputString.length; i++) {
// Check DFA
List<Integer> types = getTokenTypesViaATN(inputString[i], lexInterp);
IntegerList types = getTokenTypesViaATN(inputString[i], lexInterp);
System.out.println(types);
TokenStream input = new IntTokenStream(types);
try {