Skip to content

Commit

Permalink
Implement Java-specific ATN data optimization (-2) shift
Browse files Browse the repository at this point in the history
Add ATNDataReader, ATNDataWriter
Clean up ATN serializer/deserializer code
  • Loading branch information
KvanTTT committed Feb 6, 2022
1 parent 8333d1a commit 0f1da3e
Show file tree
Hide file tree
Showing 14 changed files with 332 additions and 395 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ protected ATN createATN(Grammar g, boolean useSerializer) {

ATN atn = g.atn;
if ( useSerializer ) {
char[] serialized = ATNSerializer.getSerializedAsChars(atn);
char[] serialized = ATNSerializer.getSerializedAsChars(atn, g.getLanguage());
return new ATNDeserializer().deserialize(serialized);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void testParseFile() throws IOException, NoSuchFieldException, IllegalAcc
Assert.assertNull(channels);
Assert.assertNull(modes);

char[] atnChars = ATNSerializer.getSerializedAsChars(atn);
char[] atnChars = ATNSerializer.getSerializedAsChars(atn, g.getLanguage());
Assert.assertEquals(ATNDeserializer.SERIALIZED_VERSION, atnChars[0]);
}

Expand Down
45 changes: 45 additions & 0 deletions runtime/Java/src/org/antlr/v4/runtime/atn/ATNDataReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.antlr.v4.runtime.atn;

public class ATNDataReader {
private final static int JavaOptimizeOffset2 = ((1 << 16) - 1) - ATNDataWriter.JavaOptimizeOffset + 1;

private final char[] data;
private int p;

public ATNDataReader(char[] data) {
this.data = data;
}

public int readUInt32() {
return readUInt16() | (readUInt16() << 16);
}

public int readUInt16() {
return readUInt16(true);
}

public int readUInt16(boolean normalize) {
int result = data[p++];
// Each char value in data is shifted by +2 at the entry to this method.
// This is an encoding optimization targeting the serialized values 0
// and -1 (serialized to 0xFFFF), each of which are very common in the
// serialized form of the ATN. In the modified UTF-8 that Java uses for
// compiled string literals, these two character values have multi-byte
// forms. By shifting each value by +2, they become characters 2 and 1
// prior to writing the string, each of which have single-byte
// representations. Since the shift occurs in the tool during ATN
// serialization, each target is responsible for adjusting the values
// during deserialization.
//
// As a special case, note that the first element of data is not
// adjusted because it contains the major version number of the
// serialized ATN, which was fixed at 3 at the time the value shifting
// was implemented.
if (normalize) {
return result >= ATNDataWriter.JavaOptimizeOffset
? result - ATNDataWriter.JavaOptimizeOffset
: result + JavaOptimizeOffset2;
}
return result;
}
}
36 changes: 36 additions & 0 deletions runtime/Java/src/org/antlr/v4/runtime/atn/ATNDataWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.antlr.v4.runtime.atn;

import org.antlr.v4.runtime.misc.IntegerList;

public class ATNDataWriter {
public static final int JavaOptimizeOffset = 2;

private final IntegerList data;
private final String language;
private final boolean isJava;

public ATNDataWriter(IntegerList data, String language) {
this.data = data;
this.language = language;
this.isJava = language.equals("Java");
}

public void writeUInt32(int value) {
writeUInt16((char)value);
writeUInt16((char)(value >> 16));
}

public void writeUInt16(int value) {
writeUInt16(value, true);
}

public void writeUInt16(int value, boolean optimize) {
if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) {
throw new UnsupportedOperationException("Serialized ATN data element "+
data.size() + " element " + value + " out of range "+
(int)Character.MIN_VALUE + ".." + (int)Character.MAX_VALUE);
}

data.add(isJava && optimize ? (value + JavaOptimizeOffset) & 0xFFFF : value);
}
}
Loading

0 comments on commit 0f1da3e

Please sign in to comment.