use of org.antlr.v4.runtime.atn.LexerCustomAction in project antlr4 by antlr.
the class ATNSerializer method serialize.
/**
* Serialize state descriptors, edge descriptors, and decision→state map
* into list of ints:
*
* grammar-type, (ANTLRParser.LEXER, ...)
* max token type,
* num states,
* state-0-type ruleIndex, state-1-type ruleIndex, ... state-i-type ruleIndex optional-arg ...
* num rules,
* rule-1-start-state rule-1-args, rule-2-start-state rule-2-args, ...
* (args are token type,actionIndex in lexer else 0,0)
* num modes,
* mode-0-start-state, mode-1-start-state, ... (parser has 0 modes)
* num unicode-bmp-sets
* bmp-set-0-interval-count intervals, bmp-set-1-interval-count intervals, ...
* num unicode-smp-sets
* smp-set-0-interval-count intervals, smp-set-1-interval-count intervals, ...
* num total edges,
* src, trg, edge-type, edge arg1, optional edge arg2 (present always), ...
* num decisions,
* decision-0-start-state, decision-1-start-state, ...
*
* Convenient to pack into unsigned shorts to make as Java string.
*/
public IntegerList serialize() {
IntegerList data = new IntegerList();
data.add(ATNDeserializer.SERIALIZED_VERSION);
serializeUUID(data, ATNDeserializer.SERIALIZED_UUID);
// convert grammar type to ATN const to avoid dependence on ANTLRParser
data.add(atn.grammarType.ordinal());
data.add(atn.maxTokenType);
int nedges = 0;
// Note that we use a LinkedHashMap as a set to
// maintain insertion order while deduplicating
// entries with the same key.
Map<IntervalSet, Boolean> sets = new LinkedHashMap<>();
// dump states, count edges and collect sets while doing so
IntegerList nonGreedyStates = new IntegerList();
IntegerList precedenceStates = new IntegerList();
data.add(atn.states.size());
for (ATNState s : atn.states) {
if (s == null) {
// might be optimized away
data.add(ATNState.INVALID_TYPE);
continue;
}
int stateType = s.getStateType();
if (s instanceof DecisionState && ((DecisionState) s).nonGreedy) {
nonGreedyStates.add(s.stateNumber);
}
if (s instanceof RuleStartState && ((RuleStartState) s).isLeftRecursiveRule) {
precedenceStates.add(s.stateNumber);
}
data.add(stateType);
if (s.ruleIndex == -1) {
data.add(Character.MAX_VALUE);
} else {
data.add(s.ruleIndex);
}
if (s.getStateType() == ATNState.LOOP_END) {
data.add(((LoopEndState) s).loopBackState.stateNumber);
} else if (s instanceof BlockStartState) {
data.add(((BlockStartState) s).endState.stateNumber);
}
if (s.getStateType() != ATNState.RULE_STOP) {
// the deserializer can trivially derive these edges, so there's no need to serialize them
nedges += s.getNumberOfTransitions();
}
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
Transition t = s.transition(i);
int edgeType = Transition.serializationTypes.get(t.getClass());
if (edgeType == Transition.SET || edgeType == Transition.NOT_SET) {
SetTransition st = (SetTransition) t;
sets.put(st.set, true);
}
}
}
// non-greedy states
data.add(nonGreedyStates.size());
for (int i = 0; i < nonGreedyStates.size(); i++) {
data.add(nonGreedyStates.get(i));
}
// precedence states
data.add(precedenceStates.size());
for (int i = 0; i < precedenceStates.size(); i++) {
data.add(precedenceStates.get(i));
}
int nrules = atn.ruleToStartState.length;
data.add(nrules);
for (int r = 0; r < nrules; r++) {
ATNState ruleStartState = atn.ruleToStartState[r];
data.add(ruleStartState.stateNumber);
if (atn.grammarType == ATNType.LEXER) {
if (atn.ruleToTokenType[r] == Token.EOF) {
data.add(Character.MAX_VALUE);
} else {
data.add(atn.ruleToTokenType[r]);
}
}
}
int nmodes = atn.modeToStartState.size();
data.add(nmodes);
if (nmodes > 0) {
for (ATNState modeStartState : atn.modeToStartState) {
data.add(modeStartState.stateNumber);
}
}
List<IntervalSet> bmpSets = new ArrayList<>();
List<IntervalSet> smpSets = new ArrayList<>();
for (IntervalSet set : sets.keySet()) {
if (!set.isNil() && set.getMaxElement() <= Character.MAX_VALUE) {
bmpSets.add(set);
} else {
smpSets.add(set);
}
}
serializeSets(data, bmpSets, new CodePointSerializer() {
@Override
public void serializeCodePoint(IntegerList data, int cp) {
data.add(cp);
}
});
serializeSets(data, smpSets, new CodePointSerializer() {
@Override
public void serializeCodePoint(IntegerList data, int cp) {
serializeInt(data, cp);
}
});
Map<IntervalSet, Integer> setIndices = new HashMap<>();
int setIndex = 0;
for (IntervalSet bmpSet : bmpSets) {
setIndices.put(bmpSet, setIndex++);
}
for (IntervalSet smpSet : smpSets) {
setIndices.put(smpSet, setIndex++);
}
data.add(nedges);
for (ATNState s : atn.states) {
if (s == null) {
// might be optimized away
continue;
}
if (s.getStateType() == ATNState.RULE_STOP) {
continue;
}
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
Transition t = s.transition(i);
if (atn.states.get(t.target.stateNumber) == null) {
throw new IllegalStateException("Cannot serialize a transition to a removed state.");
}
int src = s.stateNumber;
int trg = t.target.stateNumber;
int edgeType = Transition.serializationTypes.get(t.getClass());
int arg1 = 0;
int arg2 = 0;
int arg3 = 0;
switch(edgeType) {
case Transition.RULE:
trg = ((RuleTransition) t).followState.stateNumber;
arg1 = ((RuleTransition) t).target.stateNumber;
arg2 = ((RuleTransition) t).ruleIndex;
arg3 = ((RuleTransition) t).precedence;
break;
case Transition.PRECEDENCE:
PrecedencePredicateTransition ppt = (PrecedencePredicateTransition) t;
arg1 = ppt.precedence;
break;
case Transition.PREDICATE:
PredicateTransition pt = (PredicateTransition) t;
arg1 = pt.ruleIndex;
arg2 = pt.predIndex;
arg3 = pt.isCtxDependent ? 1 : 0;
break;
case Transition.RANGE:
arg1 = ((RangeTransition) t).from;
arg2 = ((RangeTransition) t).to;
if (arg1 == Token.EOF) {
arg1 = 0;
arg3 = 1;
}
break;
case Transition.ATOM:
arg1 = ((AtomTransition) t).label;
if (arg1 == Token.EOF) {
arg1 = 0;
arg3 = 1;
}
break;
case Transition.ACTION:
ActionTransition at = (ActionTransition) t;
arg1 = at.ruleIndex;
arg2 = at.actionIndex;
if (arg2 == -1) {
arg2 = 0xFFFF;
}
arg3 = at.isCtxDependent ? 1 : 0;
break;
case Transition.SET:
arg1 = setIndices.get(((SetTransition) t).set);
break;
case Transition.NOT_SET:
arg1 = setIndices.get(((SetTransition) t).set);
break;
case Transition.WILDCARD:
break;
}
data.add(src);
data.add(trg);
data.add(edgeType);
data.add(arg1);
data.add(arg2);
data.add(arg3);
}
}
int ndecisions = atn.decisionToState.size();
data.add(ndecisions);
for (DecisionState decStartState : atn.decisionToState) {
data.add(decStartState.stateNumber);
}
//
if (atn.grammarType == ATNType.LEXER) {
data.add(atn.lexerActions.length);
for (LexerAction action : atn.lexerActions) {
data.add(action.getActionType().ordinal());
switch(action.getActionType()) {
case CHANNEL:
int channel = ((LexerChannelAction) action).getChannel();
data.add(channel != -1 ? channel : 0xFFFF);
data.add(0);
break;
case CUSTOM:
int ruleIndex = ((LexerCustomAction) action).getRuleIndex();
int actionIndex = ((LexerCustomAction) action).getActionIndex();
data.add(ruleIndex != -1 ? ruleIndex : 0xFFFF);
data.add(actionIndex != -1 ? actionIndex : 0xFFFF);
break;
case MODE:
int mode = ((LexerModeAction) action).getMode();
data.add(mode != -1 ? mode : 0xFFFF);
data.add(0);
break;
case MORE:
data.add(0);
data.add(0);
break;
case POP_MODE:
data.add(0);
data.add(0);
break;
case PUSH_MODE:
mode = ((LexerPushModeAction) action).getMode();
data.add(mode != -1 ? mode : 0xFFFF);
data.add(0);
break;
case SKIP:
data.add(0);
data.add(0);
break;
case TYPE:
int type = ((LexerTypeAction) action).getType();
data.add(type != -1 ? type : 0xFFFF);
data.add(0);
break;
default:
String message = String.format(Locale.getDefault(), "The specified lexer action type %s is not valid.", action.getActionType());
throw new IllegalArgumentException(message);
}
}
}
// don't adjust the first value since that's the version number
for (int i = 1; i < data.size(); i++) {
if (data.get(i) < Character.MIN_VALUE || data.get(i) > Character.MAX_VALUE) {
throw new UnsupportedOperationException("Serialized ATN data element " + data.get(i) + " element " + i + " out of range " + (int) Character.MIN_VALUE + ".." + (int) Character.MAX_VALUE);
}
int value = (data.get(i) + 2) & 0xFFFF;
data.set(i, value);
}
return data;
}
use of org.antlr.v4.runtime.atn.LexerCustomAction in project antlr4 by antlr.
the class SwiftTarget method serializeTojson.
// added by janyou -->
public String serializeTojson(ATN atn) {
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("version", ATNDeserializer.SERIALIZED_VERSION);
builder.add("uuid", ATNDeserializer.SERIALIZED_UUID.toString());
// convert grammar type to ATN const to avoid dependence on ANTLRParser
builder.add("grammarType", atn.grammarType.ordinal());
builder.add("maxTokenType", atn.maxTokenType);
// states
int nedges = 0;
Map<IntervalSet, Integer> setIndices = new HashMap<IntervalSet, Integer>();
List<IntervalSet> sets = new ArrayList<IntervalSet>();
JsonArrayBuilder statesBuilder = Json.createArrayBuilder();
IntegerList nonGreedyStates = new IntegerList();
IntegerList precedenceStates = new IntegerList();
for (ATNState s : atn.states) {
JsonObjectBuilder stateBuilder = Json.createObjectBuilder();
if (s == null) {
// might be optimized away
statesBuilder.addNull();
continue;
}
int stateType = s.getStateType();
stateBuilder.add("stateType", stateType);
// stateBuilder.add("stateNumber",s.stateNumber);
stateBuilder.add("ruleIndex", s.ruleIndex);
if (s instanceof DecisionState && ((DecisionState) s).nonGreedy) {
nonGreedyStates.add(s.stateNumber);
}
if (s instanceof RuleStartState && ((RuleStartState) s).isLeftRecursiveRule) {
precedenceStates.add(s.stateNumber);
}
if (s.getStateType() == ATNState.LOOP_END) {
stateBuilder.add("detailStateNumber", ((LoopEndState) s).loopBackState.stateNumber);
} else if (s instanceof BlockStartState) {
stateBuilder.add("detailStateNumber", ((BlockStartState) s).endState.stateNumber);
}
if (s.getStateType() != ATNState.RULE_STOP) {
// the deserializer can trivially derive these edges, so there's no need to serialize them
nedges += s.getNumberOfTransitions();
}
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
Transition t = s.transition(i);
int edgeType = Transition.serializationTypes.get(t.getClass());
if (edgeType == Transition.SET || edgeType == Transition.NOT_SET) {
SetTransition st = (SetTransition) t;
if (!setIndices.containsKey(st.set)) {
sets.add(st.set);
setIndices.put(st.set, sets.size() - 1);
}
}
}
statesBuilder.add(stateBuilder);
}
builder.add("states", statesBuilder);
// non-greedy states
JsonArrayBuilder nonGreedyStatesBuilder = Json.createArrayBuilder();
for (int i = 0; i < nonGreedyStates.size(); i++) {
nonGreedyStatesBuilder.add(nonGreedyStates.get(i));
}
builder.add("nonGreedyStates", nonGreedyStatesBuilder);
// precedence states
JsonArrayBuilder precedenceStatesBuilder = Json.createArrayBuilder();
for (int i = 0; i < precedenceStates.size(); i++) {
precedenceStatesBuilder.add(precedenceStates.get(i));
}
builder.add("precedenceStates", precedenceStatesBuilder);
JsonArrayBuilder ruleToStartStateBuilder = Json.createArrayBuilder();
int nrules = atn.ruleToStartState.length;
for (int r = 0; r < nrules; r++) {
JsonObjectBuilder stateBuilder = Json.createObjectBuilder();
ATNState ruleStartState = atn.ruleToStartState[r];
stateBuilder.add("stateNumber", ruleStartState.stateNumber);
if (atn.grammarType == ATNType.LEXER) {
// if (atn.ruleToTokenType[r] == Token.EOF) {
// //data.add(Character.MAX_VALUE);
// stateBuilder.add("ruleToTokenType",-1);
// }
// else {
// //data.add(atn.ruleToTokenType[r]);
stateBuilder.add("ruleToTokenType", atn.ruleToTokenType[r]);
// }
}
ruleToStartStateBuilder.add(stateBuilder);
}
builder.add("ruleToStartState", ruleToStartStateBuilder);
JsonArrayBuilder modeToStartStateBuilder = Json.createArrayBuilder();
int nmodes = atn.modeToStartState.size();
if (nmodes > 0) {
for (ATNState modeStartState : atn.modeToStartState) {
modeToStartStateBuilder.add(modeStartState.stateNumber);
}
}
builder.add("modeToStartState", modeToStartStateBuilder);
JsonArrayBuilder nsetsBuilder = Json.createArrayBuilder();
int nsets = sets.size();
// data.add(nsets);
builder.add("nsets", nsets);
for (IntervalSet set : sets) {
JsonObjectBuilder setBuilder = Json.createObjectBuilder();
boolean containsEof = set.contains(Token.EOF);
if (containsEof && set.getIntervals().get(0).b == Token.EOF) {
// data.add(set.getIntervals().size() - 1);
setBuilder.add("size", set.getIntervals().size() - 1);
} else {
// data.add(set.getIntervals().size());
setBuilder.add("size", set.getIntervals().size());
}
setBuilder.add("containsEof", containsEof ? 1 : 0);
JsonArrayBuilder IntervalsBuilder = Json.createArrayBuilder();
for (Interval I : set.getIntervals()) {
JsonObjectBuilder IntervalBuilder = Json.createObjectBuilder();
if (I.a == Token.EOF) {
if (I.b == Token.EOF) {
continue;
} else {
IntervalBuilder.add("a", 0);
// data.add(0);
}
} else {
IntervalBuilder.add("a", I.a);
// data.add(I.a);
}
IntervalBuilder.add("b", I.b);
IntervalsBuilder.add(IntervalBuilder);
}
setBuilder.add("Intervals", IntervalsBuilder);
nsetsBuilder.add(setBuilder);
}
builder.add("IntervalSet", nsetsBuilder);
// builder.add("nedges",nedges);
JsonArrayBuilder allTransitionsBuilder = Json.createArrayBuilder();
for (ATNState s : atn.states) {
if (s == null) {
// might be optimized away
continue;
}
if (s.getStateType() == ATNState.RULE_STOP) {
continue;
}
JsonArrayBuilder transitionsBuilder = Json.createArrayBuilder();
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
JsonObjectBuilder transitionBuilder = Json.createObjectBuilder();
Transition t = s.transition(i);
if (atn.states.get(t.target.stateNumber) == null) {
throw new IllegalStateException("Cannot serialize a transition to a removed state.");
}
int src = s.stateNumber;
int trg = t.target.stateNumber;
int edgeType = Transition.serializationTypes.get(t.getClass());
int arg1 = 0;
int arg2 = 0;
int arg3 = 0;
switch(edgeType) {
case Transition.RULE:
trg = ((RuleTransition) t).followState.stateNumber;
arg1 = ((RuleTransition) t).target.stateNumber;
arg2 = ((RuleTransition) t).ruleIndex;
arg3 = ((RuleTransition) t).precedence;
break;
case Transition.PRECEDENCE:
PrecedencePredicateTransition ppt = (PrecedencePredicateTransition) t;
arg1 = ppt.precedence;
break;
case Transition.PREDICATE:
PredicateTransition pt = (PredicateTransition) t;
arg1 = pt.ruleIndex;
arg2 = pt.predIndex;
arg3 = pt.isCtxDependent ? 1 : 0;
break;
case Transition.RANGE:
arg1 = ((RangeTransition) t).from;
arg2 = ((RangeTransition) t).to;
if (arg1 == Token.EOF) {
arg1 = 0;
arg3 = 1;
}
break;
case Transition.ATOM:
arg1 = ((AtomTransition) t).label;
if (arg1 == Token.EOF) {
arg1 = 0;
arg3 = 1;
}
break;
case Transition.ACTION:
ActionTransition at = (ActionTransition) t;
arg1 = at.ruleIndex;
arg2 = at.actionIndex;
// if (arg2 == -1) {
// arg2 = 0xFFFF;
// }
arg3 = at.isCtxDependent ? 1 : 0;
break;
case Transition.SET:
arg1 = setIndices.get(((SetTransition) t).set);
break;
case Transition.NOT_SET:
arg1 = setIndices.get(((SetTransition) t).set);
break;
case Transition.WILDCARD:
break;
}
transitionBuilder.add("src", src);
transitionBuilder.add("trg", trg);
transitionBuilder.add("edgeType", edgeType);
transitionBuilder.add("arg1", arg1);
transitionBuilder.add("arg2", arg2);
transitionBuilder.add("arg3", arg3);
transitionsBuilder.add(transitionBuilder);
}
allTransitionsBuilder.add(transitionsBuilder);
}
builder.add("allTransitionsBuilder", allTransitionsBuilder);
int ndecisions = atn.decisionToState.size();
// data.add(ndecisions);
JsonArrayBuilder decisionToStateBuilder = Json.createArrayBuilder();
for (DecisionState decStartState : atn.decisionToState) {
// data.add(decStartState.stateNumber);
decisionToStateBuilder.add(decStartState.stateNumber);
}
builder.add("decisionToState", decisionToStateBuilder);
//
// LEXER ACTIONS
//
JsonArrayBuilder lexerActionsBuilder = Json.createArrayBuilder();
if (atn.grammarType == ATNType.LEXER) {
// data.add(atn.lexerActions.length);
for (LexerAction action : atn.lexerActions) {
JsonObjectBuilder lexerActionBuilder = Json.createObjectBuilder();
lexerActionBuilder.add("actionType", action.getActionType().ordinal());
// data.add(action.getActionType().ordinal());
switch(action.getActionType()) {
case CHANNEL:
int channel = ((LexerChannelAction) action).getChannel();
lexerActionBuilder.add("a", channel);
lexerActionBuilder.add("b", 0);
break;
case CUSTOM:
int ruleIndex = ((LexerCustomAction) action).getRuleIndex();
int actionIndex = ((LexerCustomAction) action).getActionIndex();
lexerActionBuilder.add("a", ruleIndex);
lexerActionBuilder.add("b", actionIndex);
break;
case MODE:
int mode = ((LexerModeAction) action).getMode();
lexerActionBuilder.add("a", mode);
lexerActionBuilder.add("b", 0);
break;
case MORE:
lexerActionBuilder.add("a", 0);
lexerActionBuilder.add("b", 0);
break;
case POP_MODE:
lexerActionBuilder.add("a", 0);
lexerActionBuilder.add("b", 0);
break;
case PUSH_MODE:
mode = ((LexerPushModeAction) action).getMode();
lexerActionBuilder.add("a", mode);
lexerActionBuilder.add("b", 0);
break;
case SKIP:
lexerActionBuilder.add("a", 0);
lexerActionBuilder.add("b", 0);
break;
case TYPE:
int type = ((LexerTypeAction) action).getType();
lexerActionBuilder.add("a", type);
lexerActionBuilder.add("b", 0);
break;
default:
String message = String.format(Locale.getDefault(), "The specified lexer action type %s is not valid.", action.getActionType());
throw new IllegalArgumentException(message);
}
lexerActionsBuilder.add(lexerActionBuilder);
}
}
builder.add("lexerActions", lexerActionsBuilder);
// don't adjust the first value since that's the version number
// for (int i = 1; i < data.size(); i++) {
// if (data.get(i) < Character.MIN_VALUE || data.get(i) > Character.MAX_VALUE) {
// throw new UnsupportedOperationException("Serialized ATN data element out of range.");
// }
//
// int value = (data.get(i) + 2) & 0xFFFF;
// data.set(i, value);
// }
JsonObject data = builder.build();
// System.out.print(data.toString());
return data.toString();
}
use of org.antlr.v4.runtime.atn.LexerCustomAction in project antlr4 by tunnelvisionlabs.
the class ATNDeserializer method deserialize.
@SuppressWarnings("deprecation")
public ATN deserialize(@NotNull char[] data) {
data = data.clone();
// was implemented.
for (int i = 1; i < data.length; i++) {
data[i] = (char) (data[i] - 2);
}
int p = 0;
int version = toInt(data[p++]);
if (version != SERIALIZED_VERSION) {
String reason = String.format(Locale.getDefault(), "Could not deserialize ATN with version %d (expected %d).", version, SERIALIZED_VERSION);
throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason));
}
UUID uuid = toUUID(data, p);
p += 8;
if (!SUPPORTED_UUIDS.contains(uuid)) {
String reason = String.format(Locale.getDefault(), "Could not deserialize ATN with UUID %s (expected %s or a legacy UUID).", uuid, SERIALIZED_UUID);
throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason));
}
boolean supportsLexerActions = isFeatureSupported(ADDED_LEXER_ACTIONS, uuid);
ATNType grammarType = ATNType.values()[toInt(data[p++])];
int maxTokenType = toInt(data[p++]);
ATN atn = new ATN(grammarType, maxTokenType);
//
// STATES
//
List<Tuple2<LoopEndState, Integer>> loopBackStateNumbers = new ArrayList<Tuple2<LoopEndState, Integer>>();
List<Tuple2<BlockStartState, Integer>> endStateNumbers = new ArrayList<Tuple2<BlockStartState, Integer>>();
int nstates = toInt(data[p++]);
for (int i = 0; i < nstates; i++) {
int stype = toInt(data[p++]);
// ignore bad type of states
if (stype == ATNState.INVALID_TYPE) {
atn.addState(null);
continue;
}
int ruleIndex = toInt(data[p++]);
if (ruleIndex == Character.MAX_VALUE) {
ruleIndex = -1;
}
ATNState s = stateFactory(stype, ruleIndex);
if (stype == ATNState.LOOP_END) {
// special case
int loopBackStateNumber = toInt(data[p++]);
loopBackStateNumbers.add(Tuple.create((LoopEndState) s, loopBackStateNumber));
} else if (s instanceof BlockStartState) {
int endStateNumber = toInt(data[p++]);
endStateNumbers.add(Tuple.create((BlockStartState) s, endStateNumber));
}
atn.addState(s);
}
// delay the assignment of loop back and end states until we know all the state instances have been initialized
for (Tuple2<LoopEndState, Integer> pair : loopBackStateNumbers) {
pair.getItem1().loopBackState = atn.states.get(pair.getItem2());
}
for (Tuple2<BlockStartState, Integer> pair : endStateNumbers) {
pair.getItem1().endState = (BlockEndState) atn.states.get(pair.getItem2());
}
int numNonGreedyStates = toInt(data[p++]);
for (int i = 0; i < numNonGreedyStates; i++) {
int stateNumber = toInt(data[p++]);
((DecisionState) atn.states.get(stateNumber)).nonGreedy = true;
}
int numSllDecisions = toInt(data[p++]);
for (int i = 0; i < numSllDecisions; i++) {
int stateNumber = toInt(data[p++]);
((DecisionState) atn.states.get(stateNumber)).sll = true;
}
int numPrecedenceStates = toInt(data[p++]);
for (int i = 0; i < numPrecedenceStates; i++) {
int stateNumber = toInt(data[p++]);
((RuleStartState) atn.states.get(stateNumber)).isPrecedenceRule = true;
}
//
// RULES
//
int nrules = toInt(data[p++]);
if (atn.grammarType == ATNType.LEXER) {
atn.ruleToTokenType = new int[nrules];
}
atn.ruleToStartState = new RuleStartState[nrules];
for (int i = 0; i < nrules; i++) {
int s = toInt(data[p++]);
RuleStartState startState = (RuleStartState) atn.states.get(s);
startState.leftFactored = toInt(data[p++]) != 0;
atn.ruleToStartState[i] = startState;
if (atn.grammarType == ATNType.LEXER) {
int tokenType = toInt(data[p++]);
if (tokenType == 0xFFFF) {
tokenType = Token.EOF;
}
atn.ruleToTokenType[i] = tokenType;
if (!isFeatureSupported(ADDED_LEXER_ACTIONS, uuid)) {
// this piece of unused metadata was serialized prior to the
// addition of LexerAction
int actionIndexIgnored = toInt(data[p++]);
if (actionIndexIgnored == 0xFFFF) {
actionIndexIgnored = -1;
}
}
}
}
atn.ruleToStopState = new RuleStopState[nrules];
for (ATNState state : atn.states) {
if (!(state instanceof RuleStopState)) {
continue;
}
RuleStopState stopState = (RuleStopState) state;
atn.ruleToStopState[state.ruleIndex] = stopState;
atn.ruleToStartState[state.ruleIndex].stopState = stopState;
}
//
// MODES
//
int nmodes = toInt(data[p++]);
for (int i = 0; i < nmodes; i++) {
int s = toInt(data[p++]);
atn.modeToStartState.add((TokensStartState) atn.states.get(s));
}
atn.modeToDFA = new DFA[nmodes];
for (int i = 0; i < nmodes; i++) {
atn.modeToDFA[i] = new DFA(atn.modeToStartState.get(i));
}
//
// SETS
//
List<IntervalSet> sets = new ArrayList<IntervalSet>();
// First, read all sets with 16-bit Unicode code points <= U+FFFF.
p = deserializeSets(data, p, sets, getUnicodeDeserializer(UnicodeDeserializingMode.UNICODE_BMP));
// deserialize sets with 32-bit arguments <= U+10FFFF.
if (isFeatureSupported(ADDED_UNICODE_SMP, uuid)) {
int previousSetCount = sets.size();
p = deserializeSets(data, p, sets, getUnicodeDeserializer(UnicodeDeserializingMode.UNICODE_SMP));
atn.setHasUnicodeSMPTransitions(sets.size() > previousSetCount);
}
//
// EDGES
//
int nedges = toInt(data[p++]);
for (int i = 0; i < nedges; i++) {
int src = toInt(data[p]);
int trg = toInt(data[p + 1]);
int ttype = toInt(data[p + 2]);
int arg1 = toInt(data[p + 3]);
int arg2 = toInt(data[p + 4]);
int arg3 = toInt(data[p + 5]);
Transition trans = edgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets);
// System.out.println("EDGE "+trans.getClass().getSimpleName()+" "+
// src+"->"+trg+
// " "+Transition.serializationNames[ttype]+
// " "+arg1+","+arg2+","+arg3);
ATNState srcState = atn.states.get(src);
srcState.addTransition(trans);
p += 6;
}
// edges for rule stop states can be derived, so they aren't serialized
// Map rule stop state -> return state -> outermost precedence return
Set<Tuple3<Integer, Integer, Integer>> returnTransitions = new LinkedHashSet<Tuple3<Integer, Integer, Integer>>();
for (ATNState state : atn.states) {
boolean returningToLeftFactored = state.ruleIndex >= 0 && atn.ruleToStartState[state.ruleIndex].leftFactored;
for (int i = 0; i < state.getNumberOfTransitions(); i++) {
Transition t = state.transition(i);
if (!(t instanceof RuleTransition)) {
continue;
}
RuleTransition ruleTransition = (RuleTransition) t;
boolean returningFromLeftFactored = atn.ruleToStartState[ruleTransition.target.ruleIndex].leftFactored;
if (!returningFromLeftFactored && returningToLeftFactored) {
continue;
}
int outermostPrecedenceReturn = -1;
if (atn.ruleToStartState[ruleTransition.target.ruleIndex].isPrecedenceRule) {
if (ruleTransition.precedence == 0) {
outermostPrecedenceReturn = ruleTransition.target.ruleIndex;
}
}
returnTransitions.add(Tuple.create(ruleTransition.target.ruleIndex, ruleTransition.followState.stateNumber, outermostPrecedenceReturn));
}
}
// Add all elements from returnTransitions to the ATN
for (Tuple3<Integer, Integer, Integer> returnTransition : returnTransitions) {
EpsilonTransition transition = new EpsilonTransition(atn.states.get(returnTransition.getItem2()), returnTransition.getItem3());
atn.ruleToStopState[returnTransition.getItem1()].addTransition(transition);
}
for (ATNState state : atn.states) {
if (state instanceof BlockStartState) {
// we need to know the end state to set its start state
if (((BlockStartState) state).endState == null) {
throw new IllegalStateException();
}
// block end states can only be associated to a single block start state
if (((BlockStartState) state).endState.startState != null) {
throw new IllegalStateException();
}
((BlockStartState) state).endState.startState = (BlockStartState) state;
}
if (state instanceof PlusLoopbackState) {
PlusLoopbackState loopbackState = (PlusLoopbackState) state;
for (int i = 0; i < loopbackState.getNumberOfTransitions(); i++) {
ATNState target = loopbackState.transition(i).target;
if (target instanceof PlusBlockStartState) {
((PlusBlockStartState) target).loopBackState = loopbackState;
}
}
} else if (state instanceof StarLoopbackState) {
StarLoopbackState loopbackState = (StarLoopbackState) state;
for (int i = 0; i < loopbackState.getNumberOfTransitions(); i++) {
ATNState target = loopbackState.transition(i).target;
if (target instanceof StarLoopEntryState) {
((StarLoopEntryState) target).loopBackState = loopbackState;
}
}
}
}
//
// DECISIONS
//
int ndecisions = toInt(data[p++]);
for (int i = 1; i <= ndecisions; i++) {
int s = toInt(data[p++]);
DecisionState decState = (DecisionState) atn.states.get(s);
atn.decisionToState.add(decState);
decState.decision = i - 1;
}
//
if (atn.grammarType == ATNType.LEXER) {
if (supportsLexerActions) {
atn.lexerActions = new LexerAction[toInt(data[p++])];
for (int i = 0; i < atn.lexerActions.length; i++) {
LexerActionType actionType = LexerActionType.values()[toInt(data[p++])];
int data1 = toInt(data[p++]);
if (data1 == 0xFFFF) {
data1 = -1;
}
int data2 = toInt(data[p++]);
if (data2 == 0xFFFF) {
data2 = -1;
}
LexerAction lexerAction = lexerActionFactory(actionType, data1, data2);
atn.lexerActions[i] = lexerAction;
}
} else {
// for compatibility with older serialized ATNs, convert the old
// serialized action index for action transitions to the new
// form, which is the index of a LexerCustomAction
List<LexerAction> legacyLexerActions = new ArrayList<LexerAction>();
for (ATNState state : atn.states) {
for (int i = 0; i < state.getNumberOfTransitions(); i++) {
Transition transition = state.transition(i);
if (!(transition instanceof ActionTransition)) {
continue;
}
int ruleIndex = ((ActionTransition) transition).ruleIndex;
int actionIndex = ((ActionTransition) transition).actionIndex;
LexerCustomAction lexerAction = new LexerCustomAction(ruleIndex, actionIndex);
state.setTransition(i, new ActionTransition(transition.target, ruleIndex, legacyLexerActions.size(), false));
legacyLexerActions.add(lexerAction);
}
}
atn.lexerActions = legacyLexerActions.toArray(new LexerAction[legacyLexerActions.size()]);
}
}
markPrecedenceDecisions(atn);
atn.decisionToDFA = new DFA[ndecisions];
for (int i = 0; i < ndecisions; i++) {
atn.decisionToDFA[i] = new DFA(atn.decisionToState.get(i), i);
}
if (deserializationOptions.isVerifyATN()) {
verifyATN(atn);
}
if (deserializationOptions.isGenerateRuleBypassTransitions() && atn.grammarType == ATNType.PARSER) {
atn.ruleToTokenType = new int[atn.ruleToStartState.length];
for (int i = 0; i < atn.ruleToStartState.length; i++) {
atn.ruleToTokenType[i] = atn.maxTokenType + i + 1;
}
for (int i = 0; i < atn.ruleToStartState.length; i++) {
BasicBlockStartState bypassStart = new BasicBlockStartState();
bypassStart.ruleIndex = i;
atn.addState(bypassStart);
BlockEndState bypassStop = new BlockEndState();
bypassStop.ruleIndex = i;
atn.addState(bypassStop);
bypassStart.endState = bypassStop;
atn.defineDecisionState(bypassStart);
bypassStop.startState = bypassStart;
ATNState endState;
Transition excludeTransition = null;
if (atn.ruleToStartState[i].isPrecedenceRule) {
// wrap from the beginning of the rule to the StarLoopEntryState
endState = null;
for (ATNState state : atn.states) {
if (state.ruleIndex != i) {
continue;
}
if (!(state instanceof StarLoopEntryState)) {
continue;
}
ATNState maybeLoopEndState = state.transition(state.getNumberOfTransitions() - 1).target;
if (!(maybeLoopEndState instanceof LoopEndState)) {
continue;
}
if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transition(0).target instanceof RuleStopState) {
endState = state;
break;
}
}
if (endState == null) {
throw new UnsupportedOperationException("Couldn't identify final state of the precedence rule prefix section.");
}
excludeTransition = ((StarLoopEntryState) endState).loopBackState.transition(0);
} else {
endState = atn.ruleToStopState[i];
}
// all non-excluded transitions that currently target end state need to target blockEnd instead
for (ATNState state : atn.states) {
for (Transition transition : state.transitions) {
if (transition == excludeTransition) {
continue;
}
if (transition.target == endState) {
transition.target = bypassStop;
}
}
}
// all transitions leaving the rule start state need to leave blockStart instead
while (atn.ruleToStartState[i].getNumberOfTransitions() > 0) {
Transition transition = atn.ruleToStartState[i].removeTransition(atn.ruleToStartState[i].getNumberOfTransitions() - 1);
bypassStart.addTransition(transition);
}
// link the new states
atn.ruleToStartState[i].addTransition(new EpsilonTransition(bypassStart));
bypassStop.addTransition(new EpsilonTransition(endState));
ATNState matchState = new BasicState();
atn.addState(matchState);
matchState.addTransition(new AtomTransition(bypassStop, atn.ruleToTokenType[i]));
bypassStart.addTransition(new EpsilonTransition(matchState));
}
if (deserializationOptions.isVerifyATN()) {
// reverify after modification
verifyATN(atn);
}
}
if (deserializationOptions.isOptimize()) {
while (true) {
int optimizationCount = 0;
optimizationCount += inlineSetRules(atn);
optimizationCount += combineChainedEpsilons(atn);
boolean preserveOrder = atn.grammarType == ATNType.LEXER;
optimizationCount += optimizeSets(atn, preserveOrder);
if (optimizationCount == 0) {
break;
}
}
if (deserializationOptions.isVerifyATN()) {
// reverify after modification
verifyATN(atn);
}
}
identifyTailCalls(atn);
return atn;
}
use of org.antlr.v4.runtime.atn.LexerCustomAction in project antlr4 by tunnelvisionlabs.
the class ATNSerializer method serialize.
/**
* Serialize state descriptors, edge descriptors, and decision→state map
* into list of ints:
*
* grammar-type, (ANTLRParser.LEXER, ...)
* max token type,
* num states,
* state-0-type ruleIndex, state-1-type ruleIndex, ... state-i-type ruleIndex optional-arg ...
* num rules,
* rule-1-start-state rule-1-args, rule-2-start-state rule-2-args, ...
* (args are token type,actionIndex in lexer else 0,0)
* num modes,
* mode-0-start-state, mode-1-start-state, ... (parser has 0 modes)
* num unicode-bmp-sets
* bmp-set-0-interval-count intervals, bmp-set-1-interval-count intervals, ...
* num unicode-smp-sets
* smp-set-0-interval-count intervals, smp-set-1-interval-count intervals, ...
* num total edges,
* src, trg, edge-type, edge arg1, optional edge arg2 (present always), ...
* num decisions,
* decision-0-start-state, decision-1-start-state, ...
*
* Convenient to pack into unsigned shorts to make as Java string.
*/
public IntegerList serialize() {
IntegerList data = new IntegerList();
data.add(ATNDeserializer.SERIALIZED_VERSION);
serializeUUID(data, ATNDeserializer.SERIALIZED_UUID);
// convert grammar type to ATN const to avoid dependence on ANTLRParser
data.add(atn.grammarType.ordinal());
data.add(atn.maxTokenType);
int nedges = 0;
// Note that we use a LinkedHashMap as a set to
// maintain insertion order while deduplicating
// entries with the same key.
Map<IntervalSet, Boolean> sets = new LinkedHashMap<IntervalSet, Boolean>();
// dump states, count edges and collect sets while doing so
IntegerList nonGreedyStates = new IntegerList();
IntegerList sllStates = new IntegerList();
IntegerList precedenceStates = new IntegerList();
data.add(atn.states.size());
for (ATNState s : atn.states) {
if (s == null) {
// might be optimized away
data.add(ATNState.INVALID_TYPE);
continue;
}
int stateType = s.getStateType();
if (s instanceof DecisionState) {
DecisionState decisionState = (DecisionState) s;
if (decisionState.nonGreedy) {
nonGreedyStates.add(s.stateNumber);
}
if (decisionState.sll) {
sllStates.add(s.stateNumber);
}
}
if (s instanceof RuleStartState && ((RuleStartState) s).isPrecedenceRule) {
precedenceStates.add(s.stateNumber);
}
data.add(stateType);
if (s.ruleIndex == -1) {
data.add(Character.MAX_VALUE);
} else {
data.add(s.ruleIndex);
}
if (s.getStateType() == ATNState.LOOP_END) {
data.add(((LoopEndState) s).loopBackState.stateNumber);
} else if (s instanceof BlockStartState) {
data.add(((BlockStartState) s).endState.stateNumber);
}
if (s.getStateType() != ATNState.RULE_STOP) {
// the deserializer can trivially derive these edges, so there's no need to serialize them
nedges += s.getNumberOfTransitions();
}
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
Transition t = s.transition(i);
int edgeType = Transition.serializationTypes.get(t.getClass());
if (edgeType == Transition.SET || edgeType == Transition.NOT_SET) {
SetTransition st = (SetTransition) t;
sets.put(st.set, true);
}
}
}
// non-greedy states
data.add(nonGreedyStates.size());
for (int i = 0; i < nonGreedyStates.size(); i++) {
data.add(nonGreedyStates.get(i));
}
// SLL decisions
data.add(sllStates.size());
for (int i = 0; i < sllStates.size(); i++) {
data.add(sllStates.get(i));
}
// precedence states
data.add(precedenceStates.size());
for (int i = 0; i < precedenceStates.size(); i++) {
data.add(precedenceStates.get(i));
}
int nrules = atn.ruleToStartState.length;
data.add(nrules);
for (int r = 0; r < nrules; r++) {
ATNState ruleStartState = atn.ruleToStartState[r];
data.add(ruleStartState.stateNumber);
boolean leftFactored = ruleNames.get(ruleStartState.ruleIndex).indexOf(ATNSimulator.RULE_VARIANT_DELIMITER) >= 0;
data.add(leftFactored ? 1 : 0);
if (atn.grammarType == ATNType.LEXER) {
if (atn.ruleToTokenType[r] == Token.EOF) {
data.add(Character.MAX_VALUE);
} else {
data.add(atn.ruleToTokenType[r]);
}
}
}
int nmodes = atn.modeToStartState.size();
data.add(nmodes);
if (nmodes > 0) {
for (ATNState modeStartState : atn.modeToStartState) {
data.add(modeStartState.stateNumber);
}
}
List<IntervalSet> bmpSets = new ArrayList<IntervalSet>();
List<IntervalSet> smpSets = new ArrayList<IntervalSet>();
for (IntervalSet set : sets.keySet()) {
if (set.getMaxElement() <= Character.MAX_VALUE) {
bmpSets.add(set);
} else {
smpSets.add(set);
}
}
serializeSets(data, bmpSets, new CodePointSerializer() {
@Override
public void serializeCodePoint(IntegerList data, int cp) {
data.add(cp);
}
});
serializeSets(data, smpSets, new CodePointSerializer() {
@Override
public void serializeCodePoint(IntegerList data, int cp) {
serializeInt(data, cp);
}
});
Map<IntervalSet, Integer> setIndices = new HashMap<IntervalSet, Integer>();
int setIndex = 0;
for (IntervalSet bmpSet : bmpSets) {
setIndices.put(bmpSet, setIndex++);
}
for (IntervalSet smpSet : smpSets) {
setIndices.put(smpSet, setIndex++);
}
data.add(nedges);
for (ATNState s : atn.states) {
if (s == null) {
// might be optimized away
continue;
}
if (s.getStateType() == ATNState.RULE_STOP) {
continue;
}
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
Transition t = s.transition(i);
if (atn.states.get(t.target.stateNumber) == null) {
throw new IllegalStateException("Cannot serialize a transition to a removed state.");
}
int src = s.stateNumber;
int trg = t.target.stateNumber;
int edgeType = Transition.serializationTypes.get(t.getClass());
int arg1 = 0;
int arg2 = 0;
int arg3 = 0;
switch(edgeType) {
case Transition.RULE:
trg = ((RuleTransition) t).followState.stateNumber;
arg1 = ((RuleTransition) t).target.stateNumber;
arg2 = ((RuleTransition) t).ruleIndex;
arg3 = ((RuleTransition) t).precedence;
break;
case Transition.PRECEDENCE:
PrecedencePredicateTransition ppt = (PrecedencePredicateTransition) t;
arg1 = ppt.precedence;
break;
case Transition.PREDICATE:
PredicateTransition pt = (PredicateTransition) t;
arg1 = pt.ruleIndex;
arg2 = pt.predIndex;
arg3 = pt.isCtxDependent ? 1 : 0;
break;
case Transition.RANGE:
arg1 = ((RangeTransition) t).from;
arg2 = ((RangeTransition) t).to;
if (arg1 == Token.EOF) {
arg1 = 0;
arg3 = 1;
}
break;
case Transition.ATOM:
arg1 = ((AtomTransition) t).label;
if (arg1 == Token.EOF) {
arg1 = 0;
arg3 = 1;
}
break;
case Transition.ACTION:
ActionTransition at = (ActionTransition) t;
arg1 = at.ruleIndex;
arg2 = at.actionIndex;
if (arg2 == -1) {
arg2 = 0xFFFF;
}
arg3 = at.isCtxDependent ? 1 : 0;
break;
case Transition.SET:
arg1 = setIndices.get(((SetTransition) t).set);
break;
case Transition.NOT_SET:
arg1 = setIndices.get(((SetTransition) t).set);
break;
case Transition.WILDCARD:
break;
}
data.add(src);
data.add(trg);
data.add(edgeType);
data.add(arg1);
data.add(arg2);
data.add(arg3);
}
}
int ndecisions = atn.decisionToState.size();
data.add(ndecisions);
for (DecisionState decStartState : atn.decisionToState) {
data.add(decStartState.stateNumber);
}
//
if (atn.grammarType == ATNType.LEXER) {
data.add(atn.lexerActions.length);
for (LexerAction action : atn.lexerActions) {
data.add(action.getActionType().ordinal());
switch(action.getActionType()) {
case CHANNEL:
int channel = ((LexerChannelAction) action).getChannel();
data.add(channel != -1 ? channel : 0xFFFF);
data.add(0);
break;
case CUSTOM:
int ruleIndex = ((LexerCustomAction) action).getRuleIndex();
int actionIndex = ((LexerCustomAction) action).getActionIndex();
data.add(ruleIndex != -1 ? ruleIndex : 0xFFFF);
data.add(actionIndex != -1 ? actionIndex : 0xFFFF);
break;
case MODE:
int mode = ((LexerModeAction) action).getMode();
data.add(mode != -1 ? mode : 0xFFFF);
data.add(0);
break;
case MORE:
data.add(0);
data.add(0);
break;
case POP_MODE:
data.add(0);
data.add(0);
break;
case PUSH_MODE:
mode = ((LexerPushModeAction) action).getMode();
data.add(mode != -1 ? mode : 0xFFFF);
data.add(0);
break;
case SKIP:
data.add(0);
data.add(0);
break;
case TYPE:
int type = ((LexerTypeAction) action).getType();
data.add(type != -1 ? type : 0xFFFF);
data.add(0);
break;
default:
String message = String.format(Locale.getDefault(), "The specified lexer action type %s is not valid.", action.getActionType());
throw new IllegalArgumentException(message);
}
}
}
// don't adjust the first value since that's the version number
for (int i = 1; i < data.size(); i++) {
if (data.get(i) < Character.MIN_VALUE || data.get(i) > Character.MAX_VALUE) {
throw new UnsupportedOperationException("Serialized ATN data element " + data.get(i) + " element " + i + " out of range " + (int) Character.MIN_VALUE + ".." + (int) Character.MAX_VALUE);
}
int value = (data.get(i) + 2) & 0xFFFF;
data.set(i, value);
}
return data;
}
use of org.antlr.v4.runtime.atn.LexerCustomAction in project antlr4 by tunnelvisionlabs.
the class LexerATNFactory method action.
@Override
public Handle action(ActionAST action) {
int ruleIndex = currentRule.index;
int actionIndex = g.lexerActions.get(action);
LexerCustomAction lexerAction = new LexerCustomAction(ruleIndex, actionIndex);
return action(action, lexerAction);
}
Aggregations