All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.org.antlr.v4.kotlinruntime.atn.ATNDeserializer.kt Maven / Gradle / Ivy

// 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