Create ATNType enumeration for ATN.grammarType field, use UUID instead of incrementing a version number for improved reliability across branches
This commit is contained in:
parent
507f331bd0
commit
36abbda44f
|
@ -44,9 +44,6 @@ import java.util.Map;
|
|||
public class ATN {
|
||||
public static final int INVALID_ALT_NUMBER = 0;
|
||||
|
||||
public static final int PARSER = 1;
|
||||
public static final int LEXER = 2;
|
||||
|
||||
@NotNull
|
||||
public final List<ATNState> states = new ArrayList<ATNState>();
|
||||
|
||||
|
@ -64,8 +61,11 @@ public class ATN {
|
|||
public final Map<String, TokensStartState> modeNameToStartState =
|
||||
new LinkedHashMap<String, TokensStartState>();
|
||||
|
||||
// runtime for parsers, lexers
|
||||
public int grammarType; // ATN.LEXER, ...
|
||||
/**
|
||||
* The type of the ATN.
|
||||
*/
|
||||
public ATNType grammarType;
|
||||
|
||||
public int maxTokenType;
|
||||
|
||||
// runtime for lexer only
|
||||
|
|
|
@ -40,11 +40,23 @@ import java.util.ArrayList;
|
|||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class ATNSimulator {
|
||||
public static final int SERIALIZED_VERSION;
|
||||
static {
|
||||
SERIALIZED_VERSION = 2;
|
||||
/* This value should never change. Updates following this version are
|
||||
* reflected as change in the unique ID SERIALIZED_UUID.
|
||||
*/
|
||||
SERIALIZED_VERSION = 3;
|
||||
}
|
||||
|
||||
public static final UUID SERIALIZED_UUID;
|
||||
static {
|
||||
/* WARNING: DO NOT MERGE THIS LINE. If UUIDs differ during a merge,
|
||||
* resolve the conflict by generating a new ID!
|
||||
*/
|
||||
SERIALIZED_UUID = UUID.fromString("065C46D6-8859-4FD7-A158-83E693BF2B52");
|
||||
}
|
||||
|
||||
/** Must distinguish between missing edge and edge we know leads nowhere */
|
||||
|
@ -115,7 +127,14 @@ public abstract class ATNSimulator {
|
|||
throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason));
|
||||
}
|
||||
|
||||
atn.grammarType = toInt(data[p++]);
|
||||
UUID uuid = toUUID(data, p);
|
||||
p += 8;
|
||||
if (!uuid.equals(SERIALIZED_UUID)) {
|
||||
String reason = String.format(Locale.getDefault(), "Could not deserialize ATN with UUID %s (expected %s).", uuid, SERIALIZED_UUID);
|
||||
throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason));
|
||||
}
|
||||
|
||||
atn.grammarType = ATNType.values()[toInt(data[p++])];
|
||||
atn.maxTokenType = toInt(data[p++]);
|
||||
|
||||
//
|
||||
|
@ -164,7 +183,7 @@ public abstract class ATNSimulator {
|
|||
// RULES
|
||||
//
|
||||
int nrules = toInt(data[p++]);
|
||||
if ( atn.grammarType == ATN.LEXER ) {
|
||||
if ( atn.grammarType == ATNType.LEXER ) {
|
||||
atn.ruleToTokenType = new int[nrules];
|
||||
atn.ruleToActionIndex = new int[nrules];
|
||||
}
|
||||
|
@ -173,7 +192,7 @@ public abstract class ATNSimulator {
|
|||
int s = toInt(data[p++]);
|
||||
RuleStartState startState = (RuleStartState)atn.states.get(s);
|
||||
atn.ruleToStartState[i] = startState;
|
||||
if ( atn.grammarType == ATN.LEXER ) {
|
||||
if ( atn.grammarType == ATNType.LEXER ) {
|
||||
int tokenType = toInt(data[p++]);
|
||||
atn.ruleToTokenType[i] = tokenType;
|
||||
int actionIndex = toInt(data[p++]);
|
||||
|
@ -376,6 +395,21 @@ public abstract class ATNSimulator {
|
|||
return c==65535 ? -1 : c;
|
||||
}
|
||||
|
||||
public static int toInt32(char[] data, int offset) {
|
||||
return (int)data[offset] | ((int)data[offset + 1] << 16);
|
||||
}
|
||||
|
||||
public static long toLong(char[] data, int offset) {
|
||||
long lowOrder = toInt32(data, offset) & 0x00000000FFFFFFFFL;
|
||||
return lowOrder | ((long)toInt32(data, offset + 2) << 32);
|
||||
}
|
||||
|
||||
public static UUID toUUID(char[] data, int offset) {
|
||||
long leastSigBits = toLong(data, offset);
|
||||
long mostSigBits = toLong(data, offset + 4);
|
||||
return new UUID(mostSigBits, leastSigBits);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Transition edgeFactory(@NotNull ATN atn,
|
||||
int type, int src, int trg,
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* [The "BSD license"]
|
||||
* Copyright (c) 2013 Terence Parr
|
||||
* Copyright (c) 2013 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.atn;
|
||||
|
||||
/**
|
||||
* Represents the type of recognizer an ATN applies to.
|
||||
*
|
||||
* @author Sam Harwell
|
||||
*/
|
||||
public enum ATNType {
|
||||
|
||||
/**
|
||||
* A lexer grammar.
|
||||
*/
|
||||
LEXER,
|
||||
|
||||
/**
|
||||
* A parser grammar.
|
||||
*/
|
||||
PARSER,
|
||||
|
||||
}
|
|
@ -35,6 +35,7 @@ import org.antlr.v4.parse.ANTLRParser;
|
|||
import org.antlr.v4.runtime.atn.ATN;
|
||||
import org.antlr.v4.runtime.atn.ATNSimulator;
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.atn.ATNType;
|
||||
import org.antlr.v4.runtime.atn.ActionTransition;
|
||||
import org.antlr.v4.runtime.atn.AtomTransition;
|
||||
import org.antlr.v4.runtime.atn.BlockStartState;
|
||||
|
@ -55,6 +56,8 @@ import java.io.InvalidClassException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ATNSerializer {
|
||||
public Grammar g;
|
||||
|
@ -90,15 +93,17 @@ public class ATNSerializer {
|
|||
public IntegerList serialize() {
|
||||
IntegerList data = new IntegerList();
|
||||
data.add(ATNSimulator.SERIALIZED_VERSION);
|
||||
serializeUUID(data, ATNSimulator.SERIALIZED_UUID);
|
||||
|
||||
// convert grammar type to ATN const to avoid dependence on ANTLRParser
|
||||
switch (g.getType()) {
|
||||
case ANTLRParser.LEXER:
|
||||
data.add(ATN.LEXER);
|
||||
data.add(ATNType.LEXER.ordinal());
|
||||
break;
|
||||
|
||||
case ANTLRParser.PARSER:
|
||||
case ANTLRParser.COMBINED:
|
||||
data.add(ATN.PARSER);
|
||||
data.add(ATNType.PARSER.ordinal());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -285,6 +290,13 @@ public class ATNSerializer {
|
|||
throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason));
|
||||
}
|
||||
|
||||
UUID uuid = ATNSimulator.toUUID(data, p);
|
||||
p += 8;
|
||||
if (!uuid.equals(ATNSimulator.SERIALIZED_UUID)) {
|
||||
String reason = String.format(Locale.getDefault(), "Could not deserialize ATN with UUID %s (expected %s).", uuid, ATNSimulator.SERIALIZED_UUID);
|
||||
throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason));
|
||||
}
|
||||
|
||||
int grammarType = ATNSimulator.toInt(data[p++]);
|
||||
int maxType = ATNSimulator.toInt(data[p++]);
|
||||
buf.append("max type ").append(maxType).append("\n");
|
||||
|
@ -384,4 +396,19 @@ public class ATNSerializer {
|
|||
char[] data = Utils.toCharArray(serialized);
|
||||
return new ATNSerializer(g, atn).decode(data);
|
||||
}
|
||||
|
||||
private void serializeUUID(IntegerList data, UUID uuid) {
|
||||
serializeLong(data, uuid.getLeastSignificantBits());
|
||||
serializeLong(data, uuid.getMostSignificantBits());
|
||||
}
|
||||
|
||||
private void serializeLong(IntegerList data, long value) {
|
||||
serializeInt(data, (int)value);
|
||||
serializeInt(data, (int)(value >> 32));
|
||||
}
|
||||
|
||||
private void serializeInt(IntegerList data, int value) {
|
||||
data.add((char)value);
|
||||
data.add((char)(value >> 16));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue