commonMain.org.antlr.v4.kotlinruntime.atn.ATNDeserializer.kt Maven / Gradle / Ivy
The newest version!
// Copyright 2017-present Strumenta and contributors, licensed under Apache 2.0.
// Copyright 2024-present Strumenta and contributors, licensed under BSD 3-Clause.
package org.antlr.v4.kotlinruntime.atn
import org.antlr.v4.kotlinruntime.Token
import org.antlr.v4.kotlinruntime.misc.IntervalSet
/**
* @author Sam Harwell
*/
public open class ATNDeserializer(private val deserializationOptions: ATNDeserializationOptions = ATNDeserializationOptions.defaultOptions) {
public companion object {
public const val SERIALIZED_VERSION: Int = 4
}
public open fun deserialize(data: CharArray): ATN =
deserialize(decodeIntsEncodedAs16BitWords(data))
public open fun deserialize(data: IntArray): ATN {
var p = 0
val version = data[p++]
if (version != SERIALIZED_VERSION) {
val reason = "Could not deserialize ATN with version $version (expected $SERIALIZED_VERSION)."
throw UnsupportedOperationException(/* InvalidClassException(ATN::class), */ reason)
}
val grammarType = ATNType.entries[data[p++]]
val maxTokenType = data[p++]
val atn = ATN(grammarType, maxTokenType)
//
// STATES
//
val loopBackStateNumbers = ArrayList>()
val endStateNumbers = ArrayList>()
val nStates = data[p++]
for (i in 0..()
p = deserializeSets(data, p, sets)
//
// EDGES
//
val nEdges = data[p++]
for (i in 0.. 0) {
val transition = atn.ruleToStartState!![i].removeTransition(atn.ruleToStartState!![i].numberOfTransitions - 1)
bypassStart.addTransition(transition)
}
// Link the new states
atn.ruleToStartState!![i].addTransition(EpsilonTransition(bypassStart))
bypassStop.addTransition(EpsilonTransition(endState!!))
val matchState = BasicState()
atn.addState(matchState)
matchState.addTransition(AtomTransition(bypassStop, atn.ruleToTokenType!![i]))
bypassStart.addTransition(EpsilonTransition(matchState))
}
if (deserializationOptions.isVerifyATN) {
// Re-verify after modification
verifyATN(atn)
}
}
return atn
}
private fun deserializeSets(data: IntArray, p: Int, sets: MutableList): Int {
var pp = p
val nSets = data[pp++]
for (i in 0.. {
checkCondition(state.transition(1).target is LoopEndState)
checkCondition(!state.nonGreedy)
}
is LoopEndState -> {
checkCondition(state.transition(1).target is StarBlockStartState)
checkCondition(state.nonGreedy)
}
else -> throw IllegalStateException()
}
}
if (state is StarLoopbackState) {
checkCondition(state.numberOfTransitions == 1)
checkCondition(state.transition(0).target is StarLoopEntryState)
}
if (state is LoopEndState) {
checkCondition(state.loopBackState != null)
}
if (state is RuleStartState) {
checkCondition(state.stopState != null)
}
if (state is BlockStartState) {
checkCondition(state.endState != null)
}
if (state is BlockEndState) {
checkCondition(state.startState != null)
}
if (state is DecisionState) {
checkCondition(state.numberOfTransitions <= 1 || state.decision >= 0)
} else {
checkCondition(state.numberOfTransitions <= 1 || state is RuleStopState)
}
}
}
public open fun checkCondition(condition: Boolean, message: String? = null) {
if (!condition) {
throw IllegalStateException(message)
}
}
public open fun edgeFactory(
atn: ATN,
type: Int,
src: Int,
trg: Int,
arg1: Int,
arg2: Int,
arg3: Int,
sets: List,
): Transition {
val target = atn.states[trg]!!
return when (type) {
Transition.EPSILON -> {
EpsilonTransition(target)
}
Transition.RANGE -> {
if (arg3 != 0) {
RangeTransition(target, Token.EOF, arg2)
} else {
RangeTransition(target, arg1, arg2)
}
}
Transition.RULE -> {
RuleTransition(atn.states[arg1] as RuleStartState, arg2, arg3, target)
}
Transition.PREDICATE -> {
PredicateTransition(target, arg1, arg2, arg3 != 0)
}
Transition.PRECEDENCE -> {
PrecedencePredicateTransition(target, arg1)
}
Transition.ATOM -> {
if (arg3 != 0) {
AtomTransition(target, Token.EOF)
} else {
AtomTransition(target, arg1)
}
}
Transition.ACTION -> {
ActionTransition(target, arg1, arg2, arg3 != 0)
}
Transition.SET -> {
SetTransition(target, sets[arg1])
}
Transition.NOT_SET -> {
NotSetTransition(target, sets[arg1])
}
Transition.WILDCARD -> {
WildcardTransition(target)
}
else -> throw IllegalArgumentException("The specified transition type is not valid.")
}
}
public open fun stateFactory(type: Int, ruleIndex: Int): ATNState? {
val s: ATNState = when (type) {
ATNState.INVALID_TYPE -> return null
ATNState.BASIC -> BasicState()
ATNState.RULE_START -> RuleStartState()
ATNState.BLOCK_START -> BasicBlockStartState()
ATNState.PLUS_BLOCK_START -> PlusBlockStartState()
ATNState.STAR_BLOCK_START -> StarBlockStartState()
ATNState.TOKEN_START -> TokensStartState()
ATNState.RULE_STOP -> RuleStopState()
ATNState.BLOCK_END -> BlockEndState()
ATNState.STAR_LOOP_BACK -> StarLoopbackState()
ATNState.STAR_LOOP_ENTRY -> StarLoopEntryState()
ATNState.PLUS_LOOP_BACK -> PlusLoopbackState()
ATNState.LOOP_END -> LoopEndState()
else -> throw IllegalArgumentException("The specified state type $type is not valid.")
}
s.ruleIndex = ruleIndex
return s
}
protected open fun lexerActionFactory(type: LexerActionType, data1: Int, data2: Int): LexerAction =
when (type) {
LexerActionType.CHANNEL -> LexerChannelAction(data1)
LexerActionType.CUSTOM -> LexerCustomAction(data1, data2)
LexerActionType.MODE -> LexerModeAction(data1)
LexerActionType.MORE -> LexerMoreAction
LexerActionType.POP_MODE -> LexerPopModeAction
LexerActionType.PUSH_MODE -> LexerPushModeAction(data1)
LexerActionType.SKIP -> LexerSkipAction
LexerActionType.TYPE -> LexerTypeAction(data1)
}
/**
* Convert a list of chars (16 uint) that represent a serialized and compressed list of ints for an ATN.
*/
public open fun decodeIntsEncodedAs16BitWords(data16: CharArray, trimToSize: Boolean = false): IntArray {
// Will be strictly smaller, but we waste bit of space to avoid copying during initialization of parsers
val data = IntArray(data16.size)
var i = 0
var i2 = 0
while (i < data16.size) {
val v = data16[i++]
if (v.code and 0x8000 == 0) {
// Hi-bit not set? Implies 1-word value
// 7 bit int
data[i2++] = v.code
} else {
// Hi.bit set. Implies 2-word value
val vnext = data16[i++]
if (v.code == 0xFFFF && vnext.code == 0xFFFF) { // Is it -1?
data[i2++] = -1
} else {
// 31-bit int
data[i2++] = (v.code and 0x7FFF) shl 16 or (vnext.code and 0xFFFF)
}
}
}
if (trimToSize) {
return data.copyOfRange(0, i2)
}
return data
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy