ATNDeserializer

///
///
import Foundation
public class ATNDeserializer {
    public static let SERIALIZED_VERSION = 4
    private let deserializationOptions: ATNDeserializationOptions
    public init(_ deserializationOptions: ATNDeserializationOptions? = nil) {
        self.deserializationOptions = deserializationOptions ?? ATNDeserializationOptions()
    }
    public func deserialize(_ data: [Int]) throws -> ATN {
        var p = 0
        let version = data[p]
        p += 1
        if version != ATNDeserializer.SERIALIZED_VERSION {
            let reason = "Could not deserialize ATN with version \(version) (expected \(ATNDeserializer.SERIALIZED_VERSION))."
            throw ANTLRError.unsupportedOperation(msg: reason)
        }
        let grammarType = ATNType(rawValue: data[p])!
        p += 1
        let maxTokenType = data[p]
        p += 1
        let atn = ATN(grammarType, maxTokenType)
        //
        // STATES
        //
        var loopBackStateNumbers = [(LoopEndState, Int)]()
        var endStateNumbers = [(BlockStartState, Int)]()
        let nstates = data[p]
        p += 1
        for _ in 0..<nstates {
            let stype = data[p]
            p += 1
            // ignore bad type of states
            if stype == ATNState.INVALID_TYPE {
                atn.addState(nil)
                continue
            }
            let ruleIndex = data[p]
            p += 1
            let s = try stateFactory(stype, ruleIndex)!
            if stype == ATNState.LOOP_END {
                // special case
                let loopBackStateNumber = data[p]
                p += 1
                loopBackStateNumbers.append((s as! LoopEndState, loopBackStateNumber))
            } else if let s = s as? BlockStartState {
                let endStateNumber = data[p]
                p += 1
                endStateNumbers.append((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 pair in loopBackStateNumbers {
            pair.0.loopBackState = atn.states[pair.1]
        }
        for pair in endStateNumbers {
            pair.0.endState = atn.states[pair.1] as? BlockEndState
        }
        let numNonGreedyStates = data[p]
        p += 1
        for _ in 0..<numNonGreedyStates {
            let stateNumber = data[p]
            p += 1
            (atn.states[stateNumber] as! DecisionState).nonGreedy = true
        }
        let numPrecedenceStates = data[p]
        p += 1
        for _ in 0..<numPrecedenceStates {
            let stateNumber = data[p]
            p += 1
            (atn.states[stateNumber] as! RuleStartState).isPrecedenceRule = true
        }
        //
        // RULES
        //
        let nrules = data[p]
        p += 1
        var ruleToTokenType = [Int]()
        var ruleToStartState = [RuleStartState]()
        for _ in 0..<nrules {
            let s = data[p]
            p += 1
            let startState = atn.states[s] as! RuleStartState
            ruleToStartState.append(startState)
            if atn.grammarType == ATNType.lexer {
                let tokenType = data[p]
                p += 1
                ruleToTokenType.append(tokenType)
            }
        }
        atn.ruleToStartState = ruleToStartState
        if atn.grammarType == ATNType.lexer {
            atn.ruleToTokenType = ruleToTokenType
        }
        fillRuleToStopState(atn)
        //
        // MODES
        //
        let nmodes = data[p]
        p += 1
        for _ in 0..<nmodes {
            let s = data[p]
            p += 1
            atn.appendModeToStartState(atn.states[s] as! TokensStartState)
        }
        //
        // SETS
        //
        var sets = [IntervalSet]()
        readSets(data, &p, &sets, readInt)
        //
        // EDGES
        //
        let nedges = data[p]
        p += 1
        for _ in 0..<nedges {
            let src = data[p]
            let trg = data[p + 1]
            let ttype = data[p + 2]
            let arg1 = data[p + 3]
            let arg2 = data[p + 4]
            let arg3 = data[p + 5]
            let trans = try edgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets)
            let srcState = atn.states[src]!
            srcState.addTransition(trans)
            p += 6
        }
        deriveEdgesForRuleStopStates(atn)
        try validateStates(atn)
        //
        // DECISIONS
        //
        let ndecisions = data[p]
        p += 1
        if (ndecisions >= 1) {
            for i in 1...ndecisions {
                let s = data[p]
                p += 1
                let decState = atn.states[s] as! DecisionState
                atn.appendDecisionToState(decState)
                decState.decision = i - 1
            }
        }
        //
        // LEXER ACTIONS
        //
        if atn.grammarType == ATNType.lexer {
            let length = data[p]
            p += 1
            var lexerActions = [LexerAction]()
            for _ in 0..<length {
                let actionType = LexerActionType(rawValue: data[p])!
                p += 1
                let data1 = data[p]
                p += 1
                let data2 = data[p]
                p += 1
                let lexerAction = lexerActionFactory(actionType, data1, data2)
                lexerActions.append(lexerAction)
            }
            atn.lexerActions = lexerActions
        }
        try finalizeATN(atn)
        return atn
    }
    private func readInt(_ data: [Int], _ p: inout Int) -> Int {
        let result = data[p]
        p += 1
        return result
    }
    private func readSets(_ data: [Int], _ p: inout Int, _ sets: inout [IntervalSet], _ readUnicode: ([Int], inout Int) -> Int) {
        let nsets = data[p]
        p += 1
        for _ in 0..<nsets {
            let nintervals = data[p]
            p += 1
            let set = IntervalSet()
            sets.append(set)
            let containsEof = (data[p] != 0)
            p += 1
            if containsEof {
                try! set.add(-1)
            }
            for _ in 0..<nintervals {
                try! set.add(readUnicode(data, &p), readUnicode(data, &p))
            }
        }
    }
    private func fillRuleToStopState(_ atn: ATN) {
        let nrules = atn.ruleToStartState.count
        atn.ruleToStopState = [RuleStopState](repeating: RuleStopState(), count: nrules)
        for state in atn.states {
            if let stopState = state as? RuleStopState, let index = stopState.ruleIndex {
                atn.ruleToStopState[index] = stopState
                atn.ruleToStartState[index].stopState = stopState
            }
        }
    }
    /// edges for rule stop states can be derived, so they aren't serialized
    private func deriveEdgesForRuleStopStates(_ atn: ATN) {
        for state in atn.states {
            guard let state = state else {
                continue
            }
            let length = state.getNumberOfTransitions()
            for i in 0..<length {
                let t = state.transition(i)
                guard let ruleTransition = t as? RuleTransition else {
                    continue
                }
                var outermostPrecedenceReturn = -1
                if let targetRuleIndex = ruleTransition.target.ruleIndex {
                    if atn.ruleToStartState[targetRuleIndex].isPrecedenceRule {
                        if ruleTransition.precedence == 0 {
                            outermostPrecedenceReturn = targetRuleIndex
                        }
                    }
                    let returnTransition = EpsilonTransition(ruleTransition.followState, outermostPrecedenceReturn)
                    atn.ruleToStopState[targetRuleIndex].addTransition(returnTransition)
                }
            }
        }
    }
    private func validateStates(_ atn: ATN) throws {
        for state in atn.states {
            if let state = state as? BlockStartState {
                // we need to know the end state to set its start state
                if let stateEndState = state.endState {
                    // block end states can only be associated to a single block start state
                    if stateEndState.startState != nil {
                        throw ANTLRError.illegalState(msg: "state.endState.startState != nil")
                    }
                    stateEndState.startState = state
                }
                else {
                    throw ANTLRError.illegalState(msg: "state.endState == nil")
                }
            }
            else if let loopbackState = state as? PlusLoopbackState {
                let length = loopbackState.getNumberOfTransitions()
                for i in 0..<length {
                    let target = loopbackState.transition(i).target
                    if let startState = target as? PlusBlockStartState {
                        startState.loopBackState = loopbackState
                    }
                }
            }
            else if let loopbackState = state as? StarLoopbackState {
                let length = loopbackState.getNumberOfTransitions()
                for i in 0..<length {
                    let target = loopbackState.transition(i).target
                    if let entryState = target as? StarLoopEntryState {
                        entryState.loopBackState = loopbackState
                    }
                }
            }
        }
    }
    private func finalizeATN(_ atn: ATN) throws {
        markPrecedenceDecisions(atn)
        if deserializationOptions.verifyATN {
            try verifyATN(atn)
        }
        if deserializationOptions.generateRuleBypassTransitions && atn.grammarType == ATNType.parser {
            try generateRuleBypassTransitions(atn)
            if deserializationOptions.verifyATN {
                // reverify after modification
                try verifyATN(atn)
            }
        }
    }
    ///
    /// Analyze the _org.antlr.v4.runtime.atn.StarLoopEntryState_ states in the specified ATN to set
    /// the _org.antlr.v4.runtime.atn.StarLoopEntryState#precedenceRuleDecision_ field to the
    /// correct value.
    ///
    /// - parameter atn: The ATN.
    ///
    internal func markPrecedenceDecisions(_ atn: ATN) {
        for state in atn.states {
            ///
            /// We analyze the ATN to determine if this ATN decision state is the
            /// decision for the closure block that determines whether a
            /// precedence rule should continue or complete.
            ///
            guard let state = state as? StarLoopEntryState, let stateRuleIndex = state.ruleIndex, atn.ruleToStartState[stateRuleIndex].isPrecedenceRule else {
                continue
            }
            let maybeLoopEndState = state.transition(state.getNumberOfTransitions() - 1).target
            if maybeLoopEndState is LoopEndState && maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transition(0).target is RuleStopState {
                state.precedenceRuleDecision = true
            }
        }
    }
    private func generateRuleBypassTransitions(_ atn: ATN) throws {
        let length = atn.ruleToStartState.count
        atn.ruleToTokenType = (0..<length).map { atn.maxTokenType + $0 + 1 }
        for i in 0..<length {
            let bypassStart = BasicBlockStartState()
            bypassStart.ruleIndex = i
            atn.addState(bypassStart)
            let bypassStop = BlockEndState()
            bypassStop.ruleIndex = i
            atn.addState(bypassStop)
            bypassStart.endState = bypassStop
            atn.defineDecisionState(bypassStart)
            bypassStop.startState = bypassStart
            var endState: ATNState?
            var excludeTransition: Transition? = nil
            if atn.ruleToStartState[i].isPrecedenceRule {
                // wrap from the beginning of the rule to the StarLoopEntryState
                endState = nil
                for state in atn.states {
                    guard let state = state, state.ruleIndex == i, state is StarLoopEntryState else {
                        continue
                    }
                    let maybeLoopEndState = state.transition(state.getNumberOfTransitions() - 1).target
                    if !(maybeLoopEndState is LoopEndState) {
                        continue
                    }
                    if maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transition(0).target is RuleStopState {
                        endState = state
                        break
                    }
                }
                if endState == nil {
                    throw ANTLRError.unsupportedOperation(msg: "Couldn't identify final state of the precedence rule prefix section.")
                }
                excludeTransition = (endState as? StarLoopEntryState)?.loopBackState?.transition(0)
            }
            else {
                endState = atn.ruleToStopState[i]
            }
            // all non-excluded transitions that currently target end state need to target blockEnd instead
            for state in atn.states {
                guard let state = state else {
                    continue
                }
                for transition in 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 {
                let transition = atn.ruleToStartState[i].removeTransition(atn.ruleToStartState[i].getNumberOfTransitions() - 1)
                bypassStart.addTransition(transition)
            }
            // link the new states
            atn.ruleToStartState[i].addTransition(EpsilonTransition(bypassStart))
            bypassStop.addTransition(EpsilonTransition(endState!))
            let matchState = BasicState()
            atn.addState(matchState)
            matchState.addTransition(AtomTransition(bypassStop, atn.ruleToTokenType[i]))
            bypassStart.addTransition(EpsilonTransition(matchState))
        }
    }
    internal func verifyATN(_ atn: ATN) throws {
        // verify assumptions
        for state in atn.states {
            guard let state = state else {
                continue
            }
            try checkCondition(state.onlyHasEpsilonTransitions() || state.getNumberOfTransitions() <= 1)
            if let state = state as? PlusBlockStartState {
                try checkCondition(state.loopBackState != nil)
            }
            if let starLoopEntryState = state as? StarLoopEntryState {
                try checkCondition(starLoopEntryState.loopBackState != nil)
                try checkCondition(starLoopEntryState.getNumberOfTransitions() == 2)
                if starLoopEntryState.transition(0).target is StarBlockStartState {
                    try checkCondition(starLoopEntryState.transition(1).target is LoopEndState)
                    try checkCondition(!starLoopEntryState.nonGreedy)
                } else {
                    if starLoopEntryState.transition(0).target is LoopEndState {
                        try checkCondition(starLoopEntryState.transition(1).target is StarBlockStartState)
                        try checkCondition(starLoopEntryState.nonGreedy)
                    } else {
                        throw ANTLRError.illegalState(msg: "IllegalStateException")
                    }
                }
            }
            if let state = state as? StarLoopbackState {
                try checkCondition(state.getNumberOfTransitions() == 1)
                try checkCondition(state.transition(0).target is StarLoopEntryState)
            }
            if state is LoopEndState {
                try checkCondition((state as! LoopEndState).loopBackState != nil)
            }
            if state is RuleStartState {
                try checkCondition((state as! RuleStartState).stopState != nil)
            }
            if state is BlockStartState {
                try checkCondition((state as! BlockStartState).endState != nil)
            }
            if state is BlockEndState {
                try checkCondition((state as! BlockEndState).startState != nil)
            }
            if let decisionState = state as? DecisionState {
                try checkCondition(decisionState.getNumberOfTransitions() <= 1 || decisionState.decision >= 0)
            } else {
                try checkCondition(state.getNumberOfTransitions() <= 1 || state is RuleStopState)
            }
        }
    }
    internal func checkCondition(_ condition: Bool) throws {
        try checkCondition(condition, nil)
    }
    internal func checkCondition(_ condition: Bool, _ message: String?) throws {
        if !condition {
            throw ANTLRError.illegalState(msg: message ?? "")
        }
    }
    internal func edgeFactory(_ atn: ATN,
                              _ type: Int, _ src: Int, _ trg: Int,
                              _ arg1: Int, _ arg2: Int, _ arg3: Int,
                              _ sets: [IntervalSet]) throws -> Transition {
        let target = atn.states[trg]!
        switch type {
        case Transition.EPSILON: return EpsilonTransition(target)
        case Transition.RANGE:
            if arg3 != 0 {
                return RangeTransition(target, CommonToken.EOF, arg2)
            } else {
                return RangeTransition(target, arg1, arg2)
            }
        case Transition.RULE:
            let rt = RuleTransition(atn.states[arg1] as! RuleStartState, arg2, arg3, target)
            return rt
        case Transition.PREDICATE:
            let pt = PredicateTransition(target, arg1, arg2, arg3 != 0)
            return pt
        case Transition.PRECEDENCE:
            return PrecedencePredicateTransition(target, arg1)
        case Transition.ATOM:
            if arg3 != 0 {
                return AtomTransition(target, CommonToken.EOF)
            } else {
                return AtomTransition(target, arg1)
            }
        case Transition.ACTION:
            return ActionTransition(target, arg1, arg2, arg3 != 0)
        case Transition.SET: return SetTransition(target, sets[arg1])
        case Transition.NOT_SET: return NotSetTransition(target, sets[arg1])
        case Transition.WILDCARD: return WildcardTransition(target)
        default:
            throw ANTLRError.illegalState(msg: "The specified transition type is not valid.")
        }
    }
    internal func stateFactory(_ type: Int, _ ruleIndex: Int) throws -> ATNState? {
        var s: ATNState
        switch type {
        case ATNState.INVALID_TYPE: return nil
        case ATNState.BASIC: s = BasicState()
        case ATNState.RULE_START: s = RuleStartState()
        case ATNState.BLOCK_START: s = BasicBlockStartState()
        case ATNState.PLUS_BLOCK_START: s = PlusBlockStartState()
        case ATNState.STAR_BLOCK_START: s = StarBlockStartState()
        case ATNState.TOKEN_START: s = TokensStartState()
        case ATNState.RULE_STOP: s = RuleStopState()
        case ATNState.BLOCK_END: s = BlockEndState()
        case ATNState.STAR_LOOP_BACK: s = StarLoopbackState()
        case ATNState.STAR_LOOP_ENTRY: s = StarLoopEntryState()
        case ATNState.PLUS_LOOP_BACK: s = PlusLoopbackState()
        case ATNState.LOOP_END: s = LoopEndState()
        default:
            let message: String = "The specified state type \(type) is not valid."
            throw ANTLRError.illegalArgument(msg: message)
        }
        s.ruleIndex = ruleIndex
        return s
    }
    internal func lexerActionFactory(_ type: LexerActionType, _ data1: Int, _ data2: Int) -> LexerAction {
        switch type {
        case .channel:
            return LexerChannelAction(data1)
        case .custom:
            return LexerCustomAction(data1, data2)
        case .mode:
            return LexerModeAction(data1)
        case .more:
            return LexerMoreAction.INSTANCE
        case .popMode:
            return LexerPopModeAction.INSTANCE
        case .pushMode:
            return LexerPushModeAction(data1)
        case .skip:
            return LexerSkipAction.INSTANCE
        case .type:
            return LexerTypeAction(data1)
        }
    }
}


SetTransition

///
///
///
/// A transition containing a set of values.
///
public class SetTransition: Transition, CustomStringConvertible {
    public let set: IntervalSet
    // TODO (sam): should we really allow null here?
    public init(_ target: ATNState, _ set: IntervalSet) {
        self.set = set
        super.init(target)
    }
    override
    public func getSerializationType() -> Int {
        return Transition.SET
    }
    override
    public func labelIntervalSet() -> IntervalSet? {
        return set
    }
    override
    public func matches(_ symbol: Int, _ minVocabSymbol: Int, _ maxVocabSymbol: Int) -> Bool {
        return set.contains(symbol)
    }
    public var description: String {
        return set.description
    }
}


LexerPopModeAction

///
///
///
/// Implements the `popMode` lexer action by calling _org.antlr.v4.runtime.Lexer#popMode_.
///
/// The `popMode` command does not have any parameters, so this action is
/// implemented as a singleton instance exposed by _#INSTANCE_.
///
/// -  Sam Harwell
/// -  4.2
///
public final class LexerPopModeAction: LexerAction, CustomStringConvertible {
    ///
    /// Provides a singleton instance of this parameterless lexer action.
    ///
    public static let INSTANCE: LexerPopModeAction = LexerPopModeAction()
    ///
    /// Constructs the singleton instance of the lexer `popMode` command.
    ///
    private override init() {
    }
    ///
    ///
    /// - returns: This method returns _org.antlr.v4.runtime.atn.LexerActionType#popMode_.
    ///
    override
    public func getActionType() -> LexerActionType {
        return LexerActionType.popMode
    }
    ///
    ///
    /// - returns: This method returns `false`.
    ///
    public override func isPositionDependent() -> Bool {
        return false
    }
    ///
    ///
    ///
    /// This action is implemented by calling _org.antlr.v4.runtime.Lexer#popMode_.
    ///
    public override func execute(_ lexer: Lexer) throws {
        try lexer.popMode()
    }
    public override func hash(into hasher: inout Hasher) {
        hasher.combine(ObjectIdentifier(self))
    }
    public var description: String {
        return "popMode"
    }
}
public func ==(lhs: LexerPopModeAction, rhs: LexerPopModeAction) -> Bool {
    return lhs === rhs
}


TokensStartState

///
///
///
/// The Tokens rule start state linking to each lexer rule start state
///
public final class TokensStartState: DecisionState {
    override
    public func getStateType() -> Int {
        return ATNState.TOKEN_START
    }
}


PredictionMode

///
///
///
/// This enumeration defines the prediction modes available in ANTLR 4 along with
/// utility methods for analyzing configuration sets for conflicts and/or
/// ambiguities.
///
public enum PredictionMode {
    ///
    /// The SLL(*) prediction mode. This prediction mode ignores the current
    /// parser context when making predictions. This is the fastest prediction
    /// mode, and provides correct results for many grammars. This prediction
    /// mode is more powerful than the prediction mode provided by ANTLR 3, but
    /// may result in syntax errors for grammar and input combinations which are
    /// not SLL.
    ///
    ///
    /// When using this prediction mode, the parser will either return a correct
    /// parse tree (i.e. the same parse tree that would be returned with the
    /// _#LL_ prediction mode), or it will report a syntax error. If a
    /// syntax error is encountered when using the _#SLL_ prediction mode,
    /// it may be due to either an actual syntax error in the input or indicate
    /// that the particular combination of grammar and input requires the more
    /// powerful _#LL_ prediction abilities to complete successfully.
    ///
    ///
    /// This prediction mode does not provide any guarantees for prediction
    /// behavior for syntactically-incorrect inputs.
    ///
    case SLL
    ///
    /// The LL(*) prediction mode. This prediction mode allows the current parser
    /// context to be used for resolving SLL conflicts that occur during
    /// prediction. This is the fastest prediction mode that guarantees correct
    /// parse results for all combinations of grammars with syntactically correct
    /// inputs.
    ///
    ///
    /// When using this prediction mode, the parser will make correct decisions
    /// for all syntactically-correct grammar and input combinations. However, in
    /// cases where the grammar is truly ambiguous this prediction mode might not
    /// report a precise answer for __exactly which__ alternatives are
    /// ambiguous.
    ///
    ///
    /// This prediction mode does not provide any guarantees for prediction
    /// behavior for syntactically-incorrect inputs.
    ///
    case LL
    ///
    /// The LL(*) prediction mode with exact ambiguity detection. In addition to
    /// the correctness guarantees provided by the _#LL_ prediction mode,
    /// this prediction mode instructs the prediction algorithm to determine the
    /// complete and exact set of ambiguous alternatives for every ambiguous
    /// decision encountered while parsing.
    ///
    ///
    /// This prediction mode may be used for diagnosing ambiguities during
    /// grammar development. Due to the performance overhead of calculating sets
    /// of ambiguous alternatives, this prediction mode should be avoided when
    /// the exact results are not necessary.
    ///
    ///
    /// This prediction mode does not provide any guarantees for prediction
    /// behavior for syntactically-incorrect inputs.
    ///
    case LL_EXACT_AMBIG_DETECTION
    ///
    /// Computes the SLL prediction termination condition.
    ///
    ///
    /// This method computes the SLL prediction termination condition for both of
    /// the following cases.
    ///
    /// * The usual SLL+LL fallback upon SLL conflict
    /// * Pure SLL without LL fallback
    ///
    /// __COMBINED SLL+LL PARSING__
    ///
    /// When LL-fallback is enabled upon SLL conflict, correct predictions are
    /// ensured regardless of how the termination condition is computed by this
    /// method. Due to the substantially higher cost of LL prediction, the
    /// prediction should only fall back to LL when the additional lookahead
    /// cannot lead to a unique SLL prediction.
    ///
    /// Assuming combined SLL+LL parsing, an SLL configuration set with only
    /// conflicting subsets should fall back to full LL, even if the
    /// configuration sets don't resolve to the same alternative (e.g.
    /// `{1,2`} and `{3,4`}. If there is at least one non-conflicting
    /// configuration, SLL could continue with the hopes that more lookahead will
    /// resolve via one of those non-conflicting configurations.
    ///
    /// Here's the prediction termination rule them: SLL (for SLL+LL parsing)
    /// stops when it sees only conflicting configuration subsets. In contrast,
    /// full LL keeps going when there is uncertainty.
    ///
    /// __HEURISTIC__
    ///
    /// As a heuristic, we stop prediction when we see any conflicting subset
    /// unless we see a state that only has one alternative associated with it.
    /// The single-alt-state thing lets prediction continue upon rules like
    /// (otherwise, it would admit defeat too soon):
    ///
    /// `[12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) ';' ;`
    ///
    /// When the ATN simulation reaches the state before `';'`, it has a
    /// DFA state that looks like: `[12|1|[], 6|2|[], 12|2|[]]`. Naturally
    /// `12|1|[]` and `12|2|[]` conflict, but we cannot stop
    /// processing this node because alternative to has another way to continue,
    /// via `[6|2|[]]`.
    ///
    /// It also let's us continue for this rule:
    ///
    /// `[1|1|[], 1|2|[], 8|3|[]] a : A | A | A B ;`
    ///
    /// After matching input A, we reach the stop state for rule A, state 1.
    /// State 8 is the state right before B. Clearly alternatives 1 and 2
    /// conflict and no amount of further lookahead will separate the two.
    /// However, alternative 3 will be able to continue and so we do not stop
    /// working on this state. In the previous example, we're concerned with
    /// states associated with the conflicting alternatives. Here alt 3 is not
    /// associated with the conflicting configs, but since we can continue
    /// looking for input reasonably, don't declare the state done.
    ///
    /// __PURE SLL PARSING__
    ///
    /// To handle pure SLL parsing, all we have to do is make sure that we
    /// combine stack contexts for configurations that differ only by semantic
    /// predicate. From there, we can do the usual SLL termination heuristic.
    ///
    /// __PREDICATES IN SLL+LL PARSING__
    ///
    /// SLL decisions don't evaluate predicates until after they reach DFA stop
    /// states because they need to create the DFA cache that works in all
    /// semantic situations. In contrast, full LL evaluates predicates collected
    /// during start state computation so it can ignore predicates thereafter.
    /// This means that SLL termination detection can totally ignore semantic
    /// predicates.
    ///
    /// Implementation-wise, _org.antlr.v4.runtime.atn.ATNConfigSet_ combines stack contexts but not
    /// semantic predicate contexts so we might see two configurations like the
    /// following.
    ///
    /// `(s, 1, x, {`), (s, 1, x', {p})}
    ///
    /// Before testing these configurations against others, we have to merge
    /// `x` and `x'` (without modifying the existing configurations).
    /// For example, we test `(x+x')==x''` when looking for conflicts in
    /// the following configurations.
    ///
    /// `(s, 1, x, {`), (s, 1, x', {p}), (s, 2, x'', {})}
    ///
    /// If the configuration set has predicates (as indicated by
    /// _org.antlr.v4.runtime.atn.ATNConfigSet#hasSemanticContext_), this algorithm makes a copy of
    /// the configurations to strip out all of the predicates so that a standard
    /// _org.antlr.v4.runtime.atn.ATNConfigSet_ will merge everything ignoring predicates.
    ///
    public static func hasSLLConflictTerminatingPrediction(_ mode: PredictionMode,_ configs: ATNConfigSet) -> Bool {
        var configs = configs
        ///
        /// Configs in rule stop states indicate reaching the end of the decision
        /// rule (local context) or end of start rule (full context). If all
        /// configs meet this condition, then none of the configurations is able
        /// to match additional input so we terminate prediction.
        ///
        if allConfigsInRuleStopStates(configs) {
            return true
        }
        // pure SLL mode parsing
        if mode == PredictionMode.SLL {
            // Don't bother with combining configs from different semantic
            // contexts if we can fail over to full LL; costs more time
            // since we'll often fail over anyway.
            if configs.hasSemanticContext {
                // dup configs, tossing out semantic predicates
                configs = configs.dupConfigsWithoutSemanticPredicates()
            }
            // now we have combined contexts for configs with dissimilar preds
        }
        // pure SLL or combined SLL+LL mode parsing
        let altsets = getConflictingAltSubsets(configs)
        let heuristic = hasConflictingAltSet(altsets) && !hasStateAssociatedWithOneAlt(configs)
        return heuristic
    }
    ///
    /// Checks if any configuration in `configs` is in a
    /// _org.antlr.v4.runtime.atn.RuleStopState_. Configurations meeting this condition have reached
    /// the end of the decision rule (local context) or end of start rule (full
    /// context).
    ///
    /// - parameter configs: the configuration set to test
    /// - returns: `true` if any configuration in `configs` is in a
    /// _org.antlr.v4.runtime.atn.RuleStopState_, otherwise `false`
    ///
    public static func hasConfigInRuleStopState(_ configs: ATNConfigSet) -> Bool {
        return  configs.hasConfigInRuleStopState
    }
    ///
    /// Checks if all configurations in `configs` are in a
    /// _org.antlr.v4.runtime.atn.RuleStopState_. Configurations meeting this condition have reached
    /// the end of the decision rule (local context) or end of start rule (full
    /// context).
    ///
    /// - parameter configs: the configuration set to test
    /// - returns: `true` if all configurations in `configs` are in a
    /// _org.antlr.v4.runtime.atn.RuleStopState_, otherwise `false`
    ///
    public static func allConfigsInRuleStopStates(_ configs: ATNConfigSet) -> Bool {
        return configs.allConfigsInRuleStopStates
    }
    ///
    /// Full LL prediction termination.
    ///
    /// Can we stop looking ahead during ATN simulation or is there some
    /// uncertainty as to which alternative we will ultimately pick, after
    /// consuming more input? Even if there are partial conflicts, we might know
    /// that everything is going to resolve to the same minimum alternative. That
    /// means we can stop since no more lookahead will change that fact. On the
    /// other hand, there might be multiple conflicts that resolve to different
    /// minimums. That means we need more look ahead to decide which of those
    /// alternatives we should predict.
    ///
    /// The basic idea is to split the set of configurations `C`, into
    /// conflicting subsets `(s, _, ctx, _)` and singleton subsets with
    /// non-conflicting configurations. Two configurations conflict if they have
    /// identical _org.antlr.v4.runtime.atn.ATNConfig#state_ and _org.antlr.v4.runtime.atn.ATNConfig#context_ values
    /// but different _org.antlr.v4.runtime.atn.ATNConfig#alt_ value, e.g. `(s, i, ctx, _)`
    /// and `(s, j, ctx, _)` for `i!=j`.
    ///
    /// Reduce these configuration subsets to the set of possible alternatives.
    /// You can compute the alternative subsets in one pass as follows:
    ///
    /// `A_s,ctx = {i | (s, i, ctx, _)`} for each configuration in
    /// `C` holding `s` and `ctx` fixed.
    ///
    /// Or in pseudo-code, for each configuration `c` in `C`:
    ///
    ///
    /// map[c] U= c._org.antlr.v4.runtime.atn.ATNConfig#alt alt_ # map hash/equals uses s and x, not
    /// alt and not pred
    ///
    ///
    /// The values in `map` are the set of `A_s,ctx` sets.
    ///
    /// If `|A_s,ctx|=1` then there is no conflict associated with
    /// `s` and `ctx`.
    ///
    /// Reduce the subsets to singletons by choosing a minimum of each subset. If
    /// the union of these alternative subsets is a singleton, then no amount of
    /// more lookahead will help us. We will always pick that alternative. If,
    /// however, there is more than one alternative, then we are uncertain which
    /// alternative to predict and must continue looking for resolution. We may
    /// or may not discover an ambiguity in the future, even if there are no
    /// conflicting subsets this round.
    ///
    /// The biggest sin is to terminate early because it means we've made a
    /// decision but were uncertain as to the eventual outcome. We haven't used
    /// enough lookahead. On the other hand, announcing a conflict too late is no
    /// big deal; you will still have the conflict. It's just inefficient. It
    /// might even look until the end of file.
    ///
    /// No special consideration for semantic predicates is required because
    /// predicates are evaluated on-the-fly for full LL prediction, ensuring that
    /// no configuration contains a semantic context during the termination
    /// check.
    ///
    /// __CONFLICTING CONFIGS__
    ///
    /// Two configurations `(s, i, x)` and `(s, j, x')`, conflict
    /// when `i!=j` but `x=x'`. Because we merge all
    /// `(s, i, _)` configurations together, that means that there are at
    /// most `n` configurations associated with state `s` for
    /// `n` possible alternatives in the decision. The merged stacks
    /// complicate the comparison of configuration contexts `x` and
    /// `x'`. Sam checks to see if one is a subset of the other by calling
    /// merge and checking to see if the merged result is either `x` or
    /// `x'`. If the `x` associated with lowest alternative `i`
    /// is the superset, then `i` is the only possible prediction since the
    /// others resolve to `min(i)` as well. However, if `x` is
    /// associated with `j>i` then at least one stack configuration for
    /// `j` is not in conflict with alternative `i`. The algorithm
    /// should keep going, looking for more lookahead due to the uncertainty.
    ///
    /// For simplicity, I'm doing a equality check between `x` and
    /// `x'` that lets the algorithm continue to consume lookahead longer
    /// than necessary. The reason I like the equality is of course the
    /// simplicity but also because that is the test you need to detect the
    /// alternatives that are actually in conflict.
    ///
    /// __CONTINUE/STOP RULE__
    ///
    /// Continue if union of resolved alternative sets from non-conflicting and
    /// conflicting alternative subsets has more than one alternative. We are
    /// uncertain about which alternative to predict.
    ///
    /// The complete set of alternatives, `[i for (_,i,_)]`, tells us which
    /// alternatives are still in the running for the amount of input we've
    /// consumed at this point. The conflicting sets let us to strip away
    /// configurations that won't lead to more states because we resolve
    /// conflicts to the configuration with a minimum alternate for the
    /// conflicting set.
    ///
    /// __CASES__
    ///
    /// * no conflicts and more than 1 alternative in set => continue
    ///
    /// * `(s, 1, x)`, `(s, 2, x)`, `(s, 3, z)`,
    /// `(s', 1, y)`, `(s', 2, y)` yields non-conflicting set
    /// `{3`} U conflicting sets `min({1,2`)} U `min({1,2`)} =
    /// `{1,3`} => continue
    ///
    /// * `(s, 1, x)`, `(s, 2, x)`, `(s', 1, y)`,
    /// `(s', 2, y)`, `(s'', 1, z)` yields non-conflicting set
    /// `{1`} U conflicting sets `min({1,2`)} U `min({1,2`)} =
    /// `{1`} => stop and predict 1
    ///
    /// * `(s, 1, x)`, `(s, 2, x)`, `(s', 1, y)`,
    /// `(s', 2, y)` yields conflicting, reduced sets `{1`} U
    /// `{1`} = `{1`} => stop and predict 1, can announce
    /// ambiguity `{1,2`}
    ///
    /// * `(s, 1, x)`, `(s, 2, x)`, `(s', 2, y)`,
    /// `(s', 3, y)` yields conflicting, reduced sets `{1`} U
    /// `{2`} = `{1,2`} => continue
    ///
    /// * `(s, 1, x)`, `(s, 2, x)`, `(s', 3, y)`,
    /// `(s', 4, y)` yields conflicting, reduced sets `{1`} U
    /// `{3`} = `{1,3`} => continue
    ///
    ///
    /// __EXACT AMBIGUITY DETECTION__
    ///
    /// If all states report the same conflicting set of alternatives, then we
    /// know we have the exact ambiguity set.
    ///
    /// `|A_i__|>1` and
    /// `A_i = A_j` for all i, j.
    ///
    /// In other words, we continue examining lookahead until all `A_i`
    /// have more than one alternative and all `A_i` are the same. If
    /// `A={{1,2`, {1,3}}}, then regular LL prediction would terminate
    /// because the resolved set is `{1`}. To determine what the real
    /// ambiguity is, we have to know whether the ambiguity is between one and
    /// two or one and three so we keep going. We can only stop prediction when
    /// we need exact ambiguity detection when the sets look like
    /// `A={{1,2`}} or `{{1,2`,{1,2}}}, etc...
    ///
    public static func resolvesToJustOneViableAlt(_ altsets: [BitSet]) -> Int {
        return getSingleViableAlt(altsets)
    }
    ///
    /// Determines if every alternative subset in `altsets` contains more
    /// than one alternative.
    ///
    /// - parameter altsets: a collection of alternative subsets
    /// - returns: `true` if every _java.util.BitSet_ in `altsets` has
    /// _java.util.BitSet#cardinality cardinality_ > 1, otherwise `false`
    ///
    public static func allSubsetsConflict(_ altsets: [BitSet]) -> Bool {
        return !hasNonConflictingAltSet(altsets)
    }
    ///
    /// Determines if any single alternative subset in `altsets` contains
    /// exactly one alternative.
    ///
    /// - parameter altsets: a collection of alternative subsets
    /// - returns: `true` if `altsets` contains a _java.util.BitSet_ with
    /// _java.util.BitSet#cardinality cardinality_ 1, otherwise `false`
    ///
    public static func hasNonConflictingAltSet(_ altsets: [BitSet]) -> Bool {
        for alts: BitSet in altsets {
            if alts.cardinality() == 1 {
                return true
            }
        }
        return false
    }
    ///
    /// Determines if any single alternative subset in `altsets` contains
    /// more than one alternative.
    ///
    /// - parameter altsets: a collection of alternative subsets
    /// - returns: `true` if `altsets` contains a _java.util.BitSet_ with
    /// _java.util.BitSet#cardinality cardinality_ > 1, otherwise `false`
    ///
    public static func hasConflictingAltSet(_ altsets: [BitSet]) -> Bool {
        for alts: BitSet in altsets {
            if alts.cardinality() > 1 {
                return true
            }
        }
        return false
    }
    ///
    /// Determines if every alternative subset in `altsets` is equivalent.
    ///
    /// - parameter altsets: a collection of alternative subsets
    /// - returns: `true` if every member of `altsets` is equal to the
    /// others, otherwise `false`
    ///
    public static func allSubsetsEqual(_ altsets: [BitSet]) -> Bool {
        let first: BitSet = altsets[0]
        for it in altsets {
            if it != first {
                return false
            }
        }
        return true
    }
    ///
    /// Returns the unique alternative predicted by all alternative subsets in
    /// `altsets`. If no such alternative exists, this method returns
    /// _org.antlr.v4.runtime.atn.ATN#INVALID_ALT_NUMBER_.
    ///
    /// - parameter altsets: a collection of alternative subsets
    ///
    public static func getUniqueAlt(_ altsets: [BitSet]) -> Int {
        let all: BitSet = getAlts(altsets)
        if all.cardinality() == 1 {
            return all.firstSetBit()
        }
        return ATN.INVALID_ALT_NUMBER
    }
    ///
    /// Gets the complete set of represented alternatives for a collection of
    /// alternative subsets. This method returns the union of each _java.util.BitSet_
    /// in `altsets`.
    ///
    /// - parameter altsets: a collection of alternative subsets
    /// - returns: the set of represented alternatives in `altsets`
    ///
    public static func getAlts(_ altsets: Array<BitSet>) -> BitSet {
        let all: BitSet = BitSet()
        for alts: BitSet in altsets {
            all.or(alts)
        }
        return all
    }
    ///
    /// Get union of all alts from configs. - Since: 4.5.1
    ///
    public static func getAlts(_ configs: ATNConfigSet) -> BitSet {
        return configs.getAltBitSet()
    }
    ///
    /// This function gets the conflicting alt subsets from a configuration set.
    /// For each configuration `c` in `configs`:
    ///
    ///
    /// map[c] U= c._org.antlr.v4.runtime.atn.ATNConfig#alt alt_ # map hash/equals uses s and x, not
    /// alt and not pred
    ///
    ///
    public static func getConflictingAltSubsets(_ configs: ATNConfigSet) -> [BitSet] {
        return configs.getConflictingAltSubsets()
    }
    public static func hasStateAssociatedWithOneAlt(_ configs: ATNConfigSet) -> Bool {
        let x = configs.getStateToAltMap()
        for alts in x.values {
            if alts.cardinality() == 1 {
                return true
            }
        }
        return false
    }
    public static func getSingleViableAlt(_ altsets: [BitSet]) -> Int {
        let viableAlts = BitSet()
        for alts in altsets {
            let minAlt = alts.firstSetBit()
            try! viableAlts.set(minAlt)
            if viableAlts.cardinality() > 1 {
                // more than 1 viable alt
                return ATN.INVALID_ALT_NUMBER
            }
        }
        return viableAlts.firstSetBit()
    }
}


ATNConfig

///
///
///
/// A tuple: (ATN state, predicted alt, syntactic, semantic context).
/// The syntactic context is a graph-structured stack node whose
/// path(s) to the root is the rule invocation(s)
/// chain used to arrive at the state.  The semantic context is
/// the tree of semantic predicates encountered before reaching
/// an ATN state.
///
public class ATNConfig: Hashable, CustomStringConvertible {
    ///
    /// This field stores the bit mask for implementing the
    /// _#isPrecedenceFilterSuppressed_ property as a bit within the
    /// existing _#reachesIntoOuterContext_ field.
    ///
    private static let SUPPRESS_PRECEDENCE_FILTER: Int = 0x40000000
    ///
    /// The ATN state associated with this configuration
    ///
    public final let state: ATNState
    ///
    /// What alt (or lexer rule) is predicted by this configuration
    ///
    public final let alt: Int
    ///
    /// The stack of invoking states leading to the rule/states associated
    /// with this config.  We track only those contexts pushed during
    /// execution of the ATN simulator.
    ///
    public internal(set) final var context: PredictionContext?
    ///
    /// We cannot execute predicates dependent upon local context unless
    /// we know for sure we are in the correct context. Because there is
    /// no way to do this efficiently, we simply cannot evaluate
    /// dependent predicates unless we are in the rule that initially
    /// invokes the ATN simulator.
    ///
    ///
    /// closure() tracks the depth of how far we dip into the outer context:
    /// depth > 0.  Note that it may not be totally accurate depth since I
    /// don't ever decrement. TODO: make it a boolean then
    ///
    ///
    /// For memory efficiency, the _#isPrecedenceFilterSuppressed_ method
    /// is also backed by this field. Since the field is publicly accessible, the
    /// highest bit which would not cause the value to become negative is used to
    /// store this field. This choice minimizes the risk that code which only
    /// compares this value to 0 would be affected by the new purpose of the
    /// flag. It also ensures the performance of the existing _org.antlr.v4.runtime.atn.ATNConfig_
    /// constructors as well as certain operations like
    /// _org.antlr.v4.runtime.atn.ATNConfigSet#add(org.antlr.v4.runtime.atn.ATNConfig, DoubleKeyMap)_ method are
    /// __completely__ unaffected by the change.
    ///
    public internal(set) final var reachesIntoOuterContext: Int = 0
    public final let semanticContext: SemanticContext
    public init(_ state: ATNState,
                _ alt: Int,
                _ context: PredictionContext?,
                _ semanticContext: SemanticContext = SemanticContext.Empty.Instance) {
        self.state = state
        self.alt = alt
        self.context = context
        self.semanticContext = semanticContext
    }
    public convenience init(_ c: ATNConfig, _ state: ATNState) {
        self.init(c, state, c.context, c.semanticContext)
    }
    public convenience init(_ c: ATNConfig, _ state: ATNState,
                            _ semanticContext: SemanticContext) {
        self.init(c, state, c.context, semanticContext)
    }
    public convenience init(_ c: ATNConfig,
                            _ semanticContext: SemanticContext) {
        self.init(c, c.state, c.context, semanticContext)
    }
    public convenience init(_ c: ATNConfig, _ state: ATNState,
                            _ context: PredictionContext?) {
        self.init(c, state, context, c.semanticContext)
    }
    public init(_ c: ATNConfig, _ state: ATNState,
                _ context: PredictionContext?,
                _ semanticContext: SemanticContext) {
        self.state = state
        self.alt = c.alt
        self.context = context
        self.semanticContext = semanticContext
        self.reachesIntoOuterContext = c.reachesIntoOuterContext
    }
    ///
    /// This method gets the value of the _#reachesIntoOuterContext_ field
    /// as it existed prior to the introduction of the
    /// _#isPrecedenceFilterSuppressed_ method.
    ///
    public final func getOuterContextDepth() -> Int {
        return reachesIntoOuterContext & ~Self.SUPPRESS_PRECEDENCE_FILTER
    }
    public final func isPrecedenceFilterSuppressed() -> Bool {
        return (reachesIntoOuterContext & Self.SUPPRESS_PRECEDENCE_FILTER) != 0
    }
    public final func setPrecedenceFilterSuppressed(_ value: Bool) {
        if value {
            self.reachesIntoOuterContext |= Self.SUPPRESS_PRECEDENCE_FILTER
        } else {
            self.reachesIntoOuterContext &= ~Self.SUPPRESS_PRECEDENCE_FILTER
        }
    }
    public func hash(into hasher: inout Hasher) {
        hasher.combine(state.stateNumber)
        hasher.combine(alt)
        hasher.combine(context)
        hasher.combine(semanticContext)
    }
    public var description: String {
        //return "MyClass \(string)"
        return toString(nil, true)
    }
    public func toString<T>(_ recog: Recognizer<T>?, _ showAlt: Bool) -> String {
        var buf = "(\(state)"
        if showAlt {
            buf += ",\(alt)"
        }
        if let context = context {
            buf += ",[\(context)]"
        }
        if semanticContext != SemanticContext.Empty.Instance {
            buf += ",\(semanticContext)"
        }
        let outerDepth = getOuterContextDepth()
        if outerDepth > 0 {
            buf += ",up=\(outerDepth)"
        }
        buf += ")"
        return buf
    }
}
///
/// An ATN configuration is equal to another if both have
/// the same state, they predict the same alternative, and
/// syntactic/semantic contexts are the same.
///
public func ==(lhs: ATNConfig, rhs: ATNConfig) -> Bool {
    if lhs === rhs {
        return true
    }
    if let l = lhs as? LexerATNConfig, let r = rhs as? LexerATNConfig {
        return l == r
    }
    if lhs.state.stateNumber != rhs.state.stateNumber {
        return false
    }
    if lhs.alt != rhs.alt {
        return false
    }
    if lhs.isPrecedenceFilterSuppressed() != rhs.isPrecedenceFilterSuppressed() {
        return false
    }
    if lhs.context != rhs.context {
        return false
    }
    return  lhs.semanticContext == rhs.semanticContext
}


PredictionContext

///
///
import Foundation
public class PredictionContext: Hashable, CustomStringConvertible {
    ///
    /// Represents `$` in an array in full context mode, when `$`
    /// doesn't mean wildcard: `$ + x = [$,x]`. Here,
    /// `$` = _#EMPTY_RETURN_STATE_.
    ///
    public static let EMPTY_RETURN_STATE = Int(Int32.max)
    private static let INITIAL_HASH = UInt32(1)
    public static var globalNodeCount = 0
    public final let id: Int = {
        let oldGlobalNodeCount = globalNodeCount
        globalNodeCount += 1
        return oldGlobalNodeCount
    }()
    ///
    /// Stores the computed hash code of this _org.antlr.v4.runtime.atn.PredictionContext_. The hash
    /// code is computed in parts to match the following reference algorithm.
    ///
    ///
    /// private int referenceHashCode() {
    /// int hash = _org.antlr.v4.runtime.misc.MurmurHash#initialize MurmurHash.initialize_(_#INITIAL_HASH_);
    ///
    /// for (int i = 0; i < _#size()_; i++) {
    /// hash = _org.antlr.v4.runtime.misc.MurmurHash#update MurmurHash.update_(hash, _#getParent getParent_(i));
    /// }
    ///
    /// for (int i = 0; i < _#size()_; i++) {
    /// hash = _org.antlr.v4.runtime.misc.MurmurHash#update MurmurHash.update_(hash, _#getReturnState getReturnState_(i));
    /// }
    ///
    /// hash = _org.antlr.v4.runtime.misc.MurmurHash#finish MurmurHash.finish_(hash, 2 * _#size()_);
    /// return hash;
    /// }
    ///
    ///
    public let cachedHashCode: Int
    init(_ cachedHashCode: Int) {
        self.cachedHashCode = cachedHashCode
    }
    ///
    /// Convert a _org.antlr.v4.runtime.RuleContext_ tree to a _org.antlr.v4.runtime.atn.PredictionContext_ graph.
    /// Return _#EMPTY_ if `outerContext` is empty or null.
    ///
    public static func fromRuleContext(_ atn: ATN, _ outerContext: RuleContext?) -> PredictionContext {
        let _outerContext = outerContext ?? ParserRuleContext.EMPTY
        // if we are in RuleContext of start rule, s, then PredictionContext
        // is EMPTY. Nobody called us. (if we are empty, return empty)
        if (_outerContext.parent == nil || _outerContext === ParserRuleContext.EMPTY) {
            return EmptyPredictionContext.Instance
        }
        // If we have a parent, convert it to a PredictionContext graph
        let parent = PredictionContext.fromRuleContext(atn, _outerContext.parent)
        let state = atn.states[_outerContext.invokingState]!
        let transition = state.transition(0) as! RuleTransition
        return SingletonPredictionContext.create(parent, transition.followState.stateNumber)
    }
    public func size() -> Int {
        fatalError(#function + " must be overridden")
    }
    public func getParent(_ index: Int) -> PredictionContext? {
        fatalError(#function + " must be overridden")
    }
    public func getReturnState(_ index: Int) -> Int {
        fatalError(#function + " must be overridden")
    }
    ///
    /// This means only the _#EMPTY_ context is in set.
    ///
    public func isEmpty() -> Bool {
        return self === EmptyPredictionContext.Instance
    }
    public func hasEmptyPath() -> Bool {
        return getReturnState(size() - 1) == PredictionContext.EMPTY_RETURN_STATE
    }
    public func hash(into hasher: inout Hasher) {
        hasher.combine(cachedHashCode)
    }
    static func calculateEmptyHashCode() -> Int {
        let hash = MurmurHash.initialize(INITIAL_HASH)
        return MurmurHash.finish(hash, 0)
    }
    static func calculateHashCode(_ parent: PredictionContext?, _ returnState: Int) -> Int {
        var hash = MurmurHash.initialize(INITIAL_HASH)
        hash = MurmurHash.update(hash, parent)
        hash = MurmurHash.update(hash, returnState)
        return MurmurHash.finish(hash, 2)
    }
    static func calculateHashCode(_ parents: [PredictionContext?], _ returnStates: [Int]) -> Int {
        var hash = MurmurHash.initialize(INITIAL_HASH)
        for parent in parents {
            hash = MurmurHash.update(hash, parent)
        }
        for state in returnStates {
            hash = MurmurHash.update(hash, state)
        }
        return  MurmurHash.finish(hash, 2 * parents.count)
    }
    // dispatch
    public static func merge(
        _ a: PredictionContext,
        _ b: PredictionContext,
        _ rootIsWildcard: Bool,
        _ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?) -> PredictionContext {
        var a = a
        var b = b
            // assert ( a != nil && b != nil,"Expected: a!=null&&b!=null");
            //assert ( a!=nil && b!=nil,"Expected: a!=null&&b!=null"); // must be empty context, never null
            // share same graph if both same
            if a == b {
                return a
            }
            if let spc_a = a as? SingletonPredictionContext, let spc_b = b as? SingletonPredictionContext {
                return mergeSingletons(spc_a, spc_b, rootIsWildcard, &mergeCache)
            }
            // At least one of a or b is array
            // If one is $ and rootIsWildcard, return $ as * wildcard
            if rootIsWildcard {
                if a is EmptyPredictionContext {
                    return a
                }
                if b is EmptyPredictionContext {
                    return b
                }
            }
            // convert singleton so both are arrays to normalize
            if let spc_a = a as? SingletonPredictionContext {
                a = ArrayPredictionContext(spc_a)
            }
            if let spc_b = b as? SingletonPredictionContext {
                b = ArrayPredictionContext(spc_b)
            }
            return mergeArrays(a as! ArrayPredictionContext, b as! ArrayPredictionContext,
                rootIsWildcard, &mergeCache)
    }
    ///
    /// Merge two _org.antlr.v4.runtime.atn.SingletonPredictionContext_ instances.
    ///
    /// Stack tops equal, parents merge is same; return left graph.
    ///
    ///
    /// Same stack top, parents differ; merge parents giving array node, then
    /// remainders of those graphs. A new root node is created to point to the
    /// merged parents.
    ///
    ///
    /// Different stack tops pointing to same parent. Make array node for the
    /// root where both element in the root point to the same (original)
    /// parent.
    ///
    ///
    /// Different stack tops pointing to different parents. Make array node for
    /// the root where each element points to the corresponding original
    /// parent.
    ///
    ///
    /// - parameter a: the first _org.antlr.v4.runtime.atn.SingletonPredictionContext_
    /// - parameter b: the second _org.antlr.v4.runtime.atn.SingletonPredictionContext_
    /// - parameter rootIsWildcard: `true` if this is a local-context merge,
    /// otherwise false to indicate a full-context merge
    /// - parameter mergeCache:
    ///
    public static func mergeSingletons(
        _ a: SingletonPredictionContext,
        _ b: SingletonPredictionContext,
        _ rootIsWildcard: Bool,
        _ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?) -> PredictionContext {
            if let mergeCache = mergeCache {
                var previous = mergeCache.get(a, b)
                if let previous = previous {
                    return previous
                }
                previous = mergeCache.get(b, a)
                if let previous = previous {
                    return previous
                }
            }
            if let rootMerge = mergeRoot(a, b, rootIsWildcard) {
                mergeCache?.put(a, b, rootMerge)
                return rootMerge
            }
            if a.returnState == b.returnState {
                // a == b
                let parent = merge(a.parent!, b.parent!, rootIsWildcard, &mergeCache)
                // if parent is same as existing a or b parent or reduced to a parent, return it
                if parent === a.parent! {
                    return a
                } // ax + bx = ax, if a=b
                if parent === b.parent! {
                    return b
                } // ax + bx = bx, if a=b
                // else: ax + ay = a'[x,y]
                // merge parents x and y, giving array node with x,y then remainders
                // of those graphs.  dup a, a' points at merged array
                // new joined parent so create new singleton pointing to it, a'
                let a_ = SingletonPredictionContext.create(parent, a.returnState);
                mergeCache?.put(a, b, a_)
                return a_
            } else {
                // a != b payloads differ
                // see if we can collapse parents due to $+x parents if local ctx
                var singleParent: PredictionContext? = nil
                //added by janyou
                if a === b || (a.parent != nil && a.parent! == b.parent) {
                    // ax + bx = [a,b]x
                    singleParent = a.parent
                }
                if let singleParent = singleParent {
                    // parents are same
                    // sort payloads and use same parent
                    var payloads = [a.returnState, b.returnState]
                    if a.returnState > b.returnState {
                        payloads[0] = b.returnState
                        payloads[1] = a.returnState
                    }
                    let parents = [singleParent, singleParent]
                    let a_ = ArrayPredictionContext(parents, payloads)
                    mergeCache?.put(a, b, a_)
                    return a_
                }
                // parents differ and can't merge them. Just pack together
                // into array; can't merge.
                // ax + by = [ax,by]
                var payloads = [a.returnState, b.returnState]
                var parents = [a.parent, b.parent]
                if a.returnState > b.returnState {
                    // sort by payload
                    payloads[0] = b.returnState
                    payloads[1] = a.returnState
                    parents = [b.parent, a.parent]
                }
                if a is EmptyPredictionContext {
                    // print("parent is null")
                }
                let a_ = ArrayPredictionContext(parents, payloads)
                mergeCache?.put(a, b, a_)
                return a_
            }
    }
    ///
    /// Handle case where at least one of `a` or `b` is
    /// _#EMPTY_. In the following diagrams, the symbol `$` is used
    /// to represent _#EMPTY_.
    ///
    /// Local-Context Merges
    ///
    /// These local-context merge operations are used when `rootIsWildcard`
    /// is true.
    ///
    /// _#EMPTY_ is superset of any graph; return _#EMPTY_.
    ///
    ///
    /// _#EMPTY_ and anything is `#EMPTY`, so merged parent is
    /// `#EMPTY`; return left graph.
    ///
    ///
    /// Special case of last merge if local context.
    ///
    ///
    /// Full-Context Merges
    ///
    /// These full-context merge operations are used when `rootIsWildcard`
    /// is false.
    ///
    ///
    ///
    /// Must keep all contexts; _#EMPTY_ in array is a special value (and
    /// null parent).
    ///
    ///
    ///
    ///
    /// - parameter a: the first _org.antlr.v4.runtime.atn.SingletonPredictionContext_
    /// - parameter b: the second _org.antlr.v4.runtime.atn.SingletonPredictionContext_
    /// - parameter rootIsWildcard: `true` if this is a local-context merge,
    /// otherwise false to indicate a full-context merge
    ///
    public static func mergeRoot(_ a: SingletonPredictionContext,
        _ b: SingletonPredictionContext,
        _ rootIsWildcard: Bool) -> PredictionContext? {
            if rootIsWildcard {
                if a === EmptyPredictionContext.Instance {
                    return EmptyPredictionContext.Instance
                }  // * + b = *
                if b === EmptyPredictionContext.Instance {
                    return EmptyPredictionContext.Instance
                }  // a + * = *
            } else {
                if a === EmptyPredictionContext.Instance && b === EmptyPredictionContext.Instance {
                    return EmptyPredictionContext.Instance
                } // $ + $ = $
                if a === EmptyPredictionContext.Instance {
                    // $ + x = [$,x]
                    let payloads = [b.returnState, EMPTY_RETURN_STATE]
                    let parents = [b.parent, nil]
                    let joined = ArrayPredictionContext(parents, payloads)
                    return joined
                }
                if b === EmptyPredictionContext.Instance {
                    // x + $ = [$,x] ($ is always first if present)
                    let payloads = [a.returnState, EMPTY_RETURN_STATE]
                    let parents = [a.parent, nil]
                    let joined = ArrayPredictionContext(parents, payloads)
                    return joined
                }
            }
            return nil
    }
    ///
    /// Merge two _org.antlr.v4.runtime.atn.ArrayPredictionContext_ instances.
    ///
    /// Different tops, different parents.
    ///
    ///
    /// Shared top, same parents.
    ///
    ///
    /// Shared top, different parents.
    ///
    ///
    /// Shared top, all shared parents.
    ///
    ///
    /// Equal tops, merge parents and reduce top to
    /// _org.antlr.v4.runtime.atn.SingletonPredictionContext_.
    ///
    ///
    public static func mergeArrays(
        _ a: ArrayPredictionContext,
        _ b: ArrayPredictionContext,
        _ rootIsWildcard: Bool,
        _ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?) -> PredictionContext {
            if let previous = mergeCache?.get(a, b) ?? mergeCache?.get(b, a) {
                return previous
            }
            // merge sorted payloads a + b => M
            var i = 0 // walks a
            var j = 0 // walks b
            var k = 0 // walks target M array
            let aReturnStatesLength = a.returnStates.count
            let bReturnStatesLength = b.returnStates.count
            let mergedReturnStatesLength = aReturnStatesLength + bReturnStatesLength
            var mergedReturnStates = [Int](repeating: 0, count: mergedReturnStatesLength)
            var mergedParents = [PredictionContext?](repeating: nil, count: mergedReturnStatesLength)
            // walk and merge to yield mergedParents, mergedReturnStates
            let aReturnStates = a.returnStates
            let bReturnStates = b.returnStates
            let aParents = a.parents
            let bParents = b.parents
            while i < aReturnStatesLength && j < bReturnStatesLength {
                let a_parent = aParents[i]
                let b_parent = bParents[j]
                if aReturnStates[i] == bReturnStates[j] {
                    // same payload (stack tops are equal), must yield merged singleton
                    let payload = aReturnStates[i]
                    // $+$ = $
                    let both$ = ((payload == EMPTY_RETURN_STATE) && a_parent == nil && b_parent == nil)
                    let ax_ax = (a_parent != nil && b_parent != nil && a_parent == b_parent)
                    if both$ || ax_ax {
                        mergedParents[k] = a_parent // choose left
                        mergedReturnStates[k] = payload
                    } else {
                        // ax+ay -> a'[x,y]
                        let mergedParent = merge(a_parent!, b_parent!, rootIsWildcard, &mergeCache)
                        mergedParents[k] = mergedParent
                        mergedReturnStates[k] = payload
                    }
                    i += 1 // hop over left one as usual
                    j += 1 // but also skip one in right side since we merge
                } else if aReturnStates[i] < bReturnStates[j] {
                    // copy a[i] to M
                    mergedParents[k] = a_parent
                    mergedReturnStates[k] = aReturnStates[i]
                    i += 1
                } else {
                    // b > a, copy b[j] to M
                    mergedParents[k] = b_parent
                    mergedReturnStates[k] = bReturnStates[j]
                    j += 1
                }
                k += 1
            }
            // copy over any payloads remaining in either array
            if i < aReturnStatesLength {
                for p in i..<aReturnStatesLength {
                    mergedParents[k] = aParents[p]
                    mergedReturnStates[k] = aReturnStates[p]
                    k += 1
                }
            } else {
                for p in j..<bReturnStatesLength {
                    mergedParents[k] = bParents[p]
                    mergedReturnStates[k] = bReturnStates[p]
                    k += 1
                }
            }
            // trim merged if we combined a few that had same stack tops
            if k < mergedParents.count {
                // write index < last position; trim
                if k == 1 {
                    // for just one merged element, return singleton top
                    let a_ = SingletonPredictionContext.create(mergedParents[0], mergedReturnStates[0])
                    mergeCache?.put(a, b, a_)
                    //print("merge array 1 \(a_)")
                    return a_
                }
                mergedParents = Array(mergedParents[0 ..< k])
                mergedReturnStates = Array(mergedReturnStates[0 ..< k])
            }
            let M = ArrayPredictionContext(mergedParents, mergedReturnStates)
            // if we created same array as a or b, return that instead
            // TODO: track whether this is possible above during merge sort for speed
            if M == a {
                mergeCache?.put(a, b, a)
                return a
            }
            if M == b {
                mergeCache?.put(a, b, b)
                return b
            }
            //modify by janyou
            //combineCommonParents(&mergedParents)
            M.combineCommonParents()
            mergeCache?.put(a, b, M)
            // print("merge array 4 \(M)")
            return M
    }
    public static func toDOTString(_ context: PredictionContext?) -> String {
        if context == nil {
            return ""
        }
        var buf = ""
        buf += "digraph G {\n"
        buf += "rankdir=LR;\n"
        var nodes = getAllContextNodes(context!)
        nodes.sort { $0.id > $1.id }
        for current in nodes {
            if current is SingletonPredictionContext {
                buf += "  s\(current.id)"
                var returnState = String(current.getReturnState(0))
                if current is EmptyPredictionContext {
                    returnState = "$"
                }
                buf += " [label=\"\(returnState)\"];\n"
                continue
            }
            let arr = current as! ArrayPredictionContext
            buf += "  s\(arr.id) [shape=box, label=\"["
            var first = true
            let returnStates = arr.returnStates
            for inv in returnStates {
                if !first {
                    buf += ", "
                }
                if inv == EMPTY_RETURN_STATE {
                    buf += "$"
                } else {
                    buf += String(inv)
                }
                first = false
            }
            buf += "]\"];\n"
        }
        for current in nodes {
            if current === EmptyPredictionContext.Instance {
                continue
            }
            let length = current.size()
            for i in 0..<length {
                guard let currentParent = current.getParent(i) else {
                    continue
                }
                buf += "  s\(current.id) -> s\(currentParent.id)"
                if current.size() > 1 {
                    buf += " [label=\"parent[\(i)]\"];\n"
                } else {
                    buf += ";\n"
                }
            }
        }
        buf.append("}\n")
        return buf
    }
    // From Sam
    public static func getCachedContext(
        _ context: PredictionContext,
        _ contextCache: PredictionContextCache,
        _ visited: inout [PredictionContext: PredictionContext]) -> PredictionContext {
        if context.isEmpty() {
            return context
        }
        if let visitedContext = visited[context] {
            return visitedContext
        }
        if let cachedContext = contextCache.get(context) {
            visited[context] = cachedContext
            return cachedContext
        }
        var changed = false
        var parents = [PredictionContext?](repeating: nil, count: context.size())
        let length = parents.count
        for i in 0..<length {
            guard let p = context.getParent(i) else {
                return context
            }
            let parent = getCachedContext(p, contextCache, &visited)
            if changed || parent !== p {
                if !changed {
                    parents = [PredictionContext?](repeating: nil, count: context.size())
                    for j in 0..<context.size() {
                        parents[j] = context.getParent(j)
                    }
                    changed = true
                }
                parents[i] = parent
            }
        }
        if !changed {
            contextCache.add(context)
            visited[context] = context
            return context
        }
        let updated: PredictionContext
        if parents.isEmpty {
            updated = EmptyPredictionContext.Instance
        }
        else if parents.count == 1 {
            updated = SingletonPredictionContext.create(parents[0], context.getReturnState(0))
        }
        else {
            let arrayPredictionContext = context as! ArrayPredictionContext
            updated = ArrayPredictionContext(parents, arrayPredictionContext.returnStates)
        }
        contextCache.add(updated)
        visited[updated] = updated
        visited[context] = updated
        return updated
    }
    // ter's recursive version of Sam's getAllNodes()
    public static func getAllContextNodes(_ context: PredictionContext) -> [PredictionContext] {
        var nodes = [PredictionContext]()
        var visited = [PredictionContext: PredictionContext]()
        getAllContextNodes_(context, &nodes, &visited)
        return nodes
    }
    private static func getAllContextNodes_(_ context: PredictionContext?,
                                            _ nodes: inout [PredictionContext],
                                            _ visited: inout [PredictionContext: PredictionContext]) {
        guard let context = context, visited[context] == nil else {
            return
        }
        visited[context] = context
        nodes.append(context)
        let length = context.size()
        for i in 0..<length {
            getAllContextNodes_(context.getParent(i), &nodes, &visited)
        }
    }
    public func toString<T>(_ recog: Recognizer<T>) -> String {
        return String(describing: PredictionContext.self)
        //		return toString(recog, ParserRuleContext.EMPTY);
    }
    public func toStrings<T>(_ recognizer: Recognizer<T>, _ currentState: Int) -> [String] {
        return toStrings(recognizer, EmptyPredictionContext.Instance, currentState)
    }
    // FROM SAM
    public func toStrings<T>(_ recognizer: Recognizer<T>?, _ stop: PredictionContext, _ currentState: Int) -> [String] {
        var result = [String]()
        var perm = 0
        outer: while true {
                var offset = 0
                var last = true
                var p = self
                var stateNumber = currentState
                var localBuffer = "["
                while !p.isEmpty() && p !== stop {
                    var index = 0
                    if p.size() > 0 {
                        var bits = 1
                        while (1 << bits) < p.size() {
                            bits += 1
                        }
                        let mask = (1 << bits) - 1
                        index = (perm >> offset) & mask
                        //last &= index >= p.size() - 1;
                        //last = Bool(Int(last) & (index >= p.size() - 1));
                        last = last && (index >= p.size() - 1)
                        if index >= p.size() {
                            continue outer
                        }
                        offset += bits
                    }
                    if let recognizer = recognizer {
                        if localBuffer.count > 1 {
                            // first char is '[', if more than that this isn't the first rule
                            localBuffer += " "
                        }
                        let atn = recognizer.getATN()
                        let s = atn.states[stateNumber]!
                        let ruleName = recognizer.getRuleNames()[s.ruleIndex!]
                        localBuffer.append(ruleName)
                    }
                    else if p.getReturnState(index) != PredictionContext.EMPTY_RETURN_STATE {
                        if !p.isEmpty() {
                            if localBuffer.count > 1 {
                                // first char is '[', if more than that this isn't the first rule
                                localBuffer += " "
                            }
                            localBuffer += String(p.getReturnState(index))
                        }
                    }
                    stateNumber = p.getReturnState(index)
                    p = p.getParent(index)!
                }
                localBuffer += "]"
                result.append(localBuffer)
                if last {
                    break
                }
                perm += 1
        }
        return result
    }
    public var description: String {
    }
}
public func ==(lhs: RuleContext, rhs: ParserRuleContext) -> Bool {
    if let lhs = lhs as? ParserRuleContext {
        return lhs === rhs
    }
    else {
        return false
    }
}
public func ==(lhs: PredictionContext, rhs: PredictionContext) -> Bool {
    if lhs === rhs {
        return true
    }
    if lhs is EmptyPredictionContext {
        return lhs === rhs
    }
    if let lhs = lhs as? SingletonPredictionContext, let rhs = rhs as? SingletonPredictionContext {
        return lhs == rhs
    }
    if let lhs = lhs as? ArrayPredictionContext, let rhs = rhs as? ArrayPredictionContext {
        return lhs == rhs
    }
    return false
}
public func ==(lhs: ArrayPredictionContext, rhs: SingletonPredictionContext) -> Bool {
    return false
}
public func ==(lhs: SingletonPredictionContext, rhs: ArrayPredictionContext) -> Bool {
    return false
}
public func ==(lhs: SingletonPredictionContext, rhs: EmptyPredictionContext) -> Bool {
    return false
}
public func ==(lhs: EmptyPredictionContext, rhs: ArrayPredictionContext) -> Bool {
    return lhs === rhs
}
public func ==(lhs: EmptyPredictionContext, rhs: SingletonPredictionContext) -> Bool {
    return lhs === rhs
}


ATNDeserializationOptions

///
///
public struct ATNDeserializationOptions {
    public var verifyATN = true
    public var generateRuleBypassTransitions = false
}


AmbiguityInfo

///
///
///
/// This class represents profiling event information for an ambiguity.
/// Ambiguities are decisions where a particular input resulted in an SLL
/// conflict, followed by LL prediction also reaching a conflict state
/// (indicating a true ambiguity in the grammar).
///
///
/// This event may be reported during SLL prediction in cases where the
/// conflicting SLL configuration set provides sufficient information to
/// determine that the SLL conflict is truly an ambiguity. For example, if none
/// of the ATN configurations in the conflicting SLL configuration set have
/// traversed a global follow transition (i.e.
/// _org.antlr.v4.runtime.atn.ATNConfig#reachesIntoOuterContext_ is 0 for all configurations), then
/// the result of SLL prediction for that input is known to be equivalent to the
/// result of LL prediction for that input.
///
///
/// In some cases, the minimum represented alternative in the conflicting LL
/// configuration set is not equal to the minimum represented alternative in the
/// conflicting SLL configuration set. Grammars and inputs which result in this
/// scenario are unable to use _org.antlr.v4.runtime.atn.PredictionMode#SLL_, which in turn means
/// they cannot use the two-stage parsing strategy to improve parsing performance
/// for that input.
///
/// - seealso: org.antlr.v4.runtime.atn.ParserATNSimulator#reportAmbiguity
/// - seealso: org.antlr.v4.runtime.ANTLRErrorListener#reportAmbiguity
///
/// -  4.3
///
public class AmbiguityInfo: DecisionEventInfo {
    ///
    /// The set of alternative numbers for this decision event that lead to a valid parse.
    ///
    public var ambigAlts: BitSet
    ///
    /// Constructs a new instance of the _org.antlr.v4.runtime.atn.AmbiguityInfo_ class with the
    /// specified detailed ambiguity information.
    ///
    /// - parameter decision: The decision number
    /// - parameter configs: The final configuration set identifying the ambiguous
    /// alternatives for the current input
    /// - parameter ambigAlts: The set of alternatives in the decision that lead to a valid parse.
    /// - parameter input: The input token stream
    /// - parameter startIndex: The start index for the current prediction
    /// - parameter stopIndex: The index at which the ambiguity was identified during
    /// prediction
    /// - parameter fullCtx: `true` if the ambiguity was identified during LL
    /// prediction; otherwise, `false` if the ambiguity was identified
    /// during SLL prediction
    ///
    public init(_ decision: Int,
                _ configs: ATNConfigSet,
                _ ambigAlts: BitSet,
                _ input: TokenStream, _ startIndex: Int, _ stopIndex: Int,
                _ fullCtx: Bool) {
        self.ambigAlts = ambigAlts
        super.init(decision, configs, input, startIndex, stopIndex, fullCtx)
    }
}


BlockEndState

///
///
///
/// Terminal node of a simple `(a|b|c)` block.
///
public final class BlockEndState: ATNState {
    public var startState: BlockStartState?
    override
    public func getStateType() -> Int {
        return ATNState.BLOCK_END
    }
}


ActionTransition

///
///
public final class ActionTransition: Transition, CustomStringConvertible {
    public let ruleIndex: Int
    public let actionIndex: Int
    public let isCtxDependent: Bool
    // e.g., $i ref in action
    public convenience init(_ target: ATNState, _ ruleIndex: Int) {
        self.init(target, ruleIndex, -1, false)
    }
    public init(_ target: ATNState, _ ruleIndex: Int, _ actionIndex: Int, _ isCtxDependent: Bool) {
        self.ruleIndex = ruleIndex
        self.actionIndex = actionIndex
        self.isCtxDependent = isCtxDependent
        super.init(target)
    }
    override
    public func getSerializationType() -> Int {
        return Transition.ACTION
    }
    override
    public func isEpsilon() -> Bool {
        return true // we are to be ignored by analysis 'cept for predicates
    }
    override
    public func matches(_ symbol: Int, _ minVocabSymbol: Int, _ maxVocabSymbol: Int) -> Bool {
        return false
    }
    public var description: String {
        return "action_\(ruleIndex):\(actionIndex)"
    }
}


ATNSimulator

///
///
import Foundation
open class ATNSimulator {
    ///
    /// Must distinguish between missing edge and edge we know leads nowhere
    ///
    public static let ERROR: DFAState = {
        let error = DFAState(ATNConfigSet())
        error.stateNumber = Int.max
        return error
    }()
    public let atn: ATN
    ///
    /// The context cache maps all PredictionContext objects that are equals()
    /// to a single cached copy. This cache is shared across all contexts
    /// in all ATNConfigs in all DFA states.  We rebuild each ATNConfigSet
    /// to use only cached nodes/graphs in addDFAState(). We don't want to
    /// fill this during closure() since there are lots of contexts that
    /// pop up but are not used ever again. It also greatly slows down closure().
    ///
    /// This cache makes a huge difference in memory and a little bit in speed.
    /// For the Java grammar on java.*, it dropped the memory requirements
    /// at the end from 25M to 16M. We don't store any of the full context
    /// graphs in the DFA because they are limited to local context only,
    /// but apparently there's a lot of repetition there as well. We optimize
    /// the config contexts before storing the config set in the DFA states
    /// by literally rebuilding them with cached subgraphs only.
    ///
    /// I tried a cache for use during closure operations, that was
    /// whacked after each adaptivePredict(). It cost a little bit
    /// more time I think and doesn't save on the overall footprint
    /// so it's not worth the complexity.
    ///
    internal let sharedContextCache: PredictionContextCache
    public init(_ atn: ATN,
                _ sharedContextCache: PredictionContextCache) {
        self.atn = atn
        self.sharedContextCache = sharedContextCache
    }
    open func reset() {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Clear the DFA cache used by the current instance. Since the DFA cache may
    /// be shared by multiple ATN simulators, this method may affect the
    /// performance (but not accuracy) of other parsers which are being used
    /// concurrently.
    ///
    /// - throws: ANTLRError.unsupportedOperation if the current instance does not
    /// support clearing the DFA.
    ///
    /// - since: 4.3
    ///
    open func clearDFA() throws {
        throw ANTLRError.unsupportedOperation(msg: "This ATN simulator does not support clearing the DFA. ")
    }
    open func getSharedContextCache() -> PredictionContextCache {
        return sharedContextCache
    }
    open func getCachedContext(_ context: PredictionContext) -> PredictionContext {
        //TODO: synced (sharedContextCache!)
        //synced (sharedContextCache!) {
        var visited = [PredictionContext: PredictionContext]()
        return PredictionContext.getCachedContext(context,
                sharedContextCache,
                &visited)
    }
    public static func edgeFactory(_ atn: ATN,
                                  _ type: Int, _ src: Int, _ trg: Int,
                                  _ arg1: Int, _ arg2: Int, _ arg3: Int,
                                  _ sets: Array<IntervalSet>) throws -> Transition {
        return try ATNDeserializer().edgeFactory(atn, type, src, trg, arg1, arg2, arg3, sets)
    }
}


Trees

 */
/// A set of utility routines useful for all kinds of ANTLR trees.
public class Trees {
    /*
    public class func getPS(t: Tree, _ ruleNames: Array<String>,
    _ fontName: String, _ fontSize: Int) -> String {
    let psgen: TreePostScriptGenerator =
    TreePostScriptGenerator(ruleNames, t, fontName, fontSize)
    return psgen.getPS()
    }
    public class func getPS(t: Tree, _ ruleNames: Array<String>) -> String {
    return getPS(t, ruleNames, "Helvetica", 11)
    }
    //TODO: write to file
    public class func writePS(t: Tree, _ ruleNames: Array<String>,
    _ fileName: String,
    _ fontName: String, _ fontSize: Int)
    throws {
    var ps: String = getPS(t, ruleNames, fontName, fontSize)
    var f: FileWriter = FileWriter(fileName)
    var bw: BufferedWriter = BufferedWriter(f)
    try {
    bw.write(ps)
    }
    defer {
    bw.close()
    }
    }
    public class func writePS(t: Tree, _ ruleNames: Array<String>, _ fileName: String)
    throws {
    writePS(t, ruleNames, fileName, "Helvetica", 11)
    }
    */
    /// Print out a whole tree in LISP form. _#getNodeText_ is used on the
    /// node payloads to get the text for the nodes.  Detect
    /// parse trees and extract data appropriately.
    ///
    public static func toStringTree(_ t: Tree) -> String {
        let rulsName: Array<String>? = nil
        return toStringTree(t, rulsName)
    }
    /// Print out a whole tree in LISP form. _#getNodeText_ is used on the
    /// node payloads to get the text for the nodes.  Detect
    /// parse trees and extract data appropriately.
    ///
    public static func toStringTree(_ t: Tree, _ recog: Parser?) -> String {
        let ruleNamesList: [String]? = recog?.getRuleNames()
        return toStringTree(t, ruleNamesList)
    }
    /// Print out a whole tree in LISP form. _#getNodeText_ is used on the
    /// node payloads to get the text for the nodes.  Detect
    /// parse trees and extract data appropriately.
    ///
    public static func toStringTree(_ t: Tree, _ ruleNames: Array<String>?) -> String {
        let s = Utils.escapeWhitespace(getNodeText(t, ruleNames), false)
        if t.getChildCount() == 0 {
            return s
        }
        var buf = "(\(s) "
        let length = t.getChildCount()
        for i in 0..<length {
            if i > 0 {
                buf += " "
            }
            buf += toStringTree(t.getChild(i)!, ruleNames)
        }
        buf += ")"
        return buf
    }
    public static func getNodeText(_ t: Tree, _ recog: Parser?) -> String {
        return getNodeText(t, recog?.getRuleNames())
    }
    public static func getNodeText(_ t: Tree, _ ruleNames: Array<String>?) -> String {
        if let ruleNames = ruleNames {
            if let ruleNode = t as? RuleNode {
                let ruleIndex: Int = ruleNode.getRuleContext().getRuleIndex()
                let ruleName: String = ruleNames[ruleIndex]
                let altNumber = (t as! RuleContext).getAltNumber()
                if altNumber != ATN.INVALID_ALT_NUMBER  {
                    return "\(ruleName):\(altNumber)"
                }
                return ruleName
            } else {
                if let errorNode = t as? ErrorNode {
                    return errorNode.description
                } else if let terminalNode = t as? TerminalNode {
                    if let symbol = terminalNode.getSymbol() {
                        let s: String = symbol.getText()!
                        return s
                    }
                }
            }
        }
        // no recog for rule names
        let payload: AnyObject = t.getPayload()
        if let token = payload as? Token {
            return token.getText()!
        }
        return "\(t.getPayload())"
    }
    /// Return ordered list of all children of this node
    public static func getChildren(_ t: Tree) -> Array<Tree> {
        var kids: Array<Tree> = Array<Tree>()
        let length = t.getChildCount()
        for i in 0..<length {
            kids.append(t.getChild(i)!)
        }
        return kids
    }
    /// Return a list of all ancestors of this node.  The first node of
    /// list is the root and the last is the parent of this node.
    ///
    public static func getAncestors(_ t: Tree) -> Array<Tree> {
        var ancestors: Array<Tree> = Array<Tree>()
        if t.getParent() == nil {
            return ancestors
            //return Collections.emptyList();
        }
        var tp = t.getParent()
        while let tpWrap = tp {
            ancestors.insert(t, at: 0)
            //ancestors.add(0, t); // insert at start
            tp = tpWrap.getParent()
        }
        return ancestors
    }
    public static func findAllTokenNodes(_ t: ParseTree, _ ttype: Int) -> Array<ParseTree> {
        return findAllNodes(t, ttype, true)
    }
    public static func findAllRuleNodes(_ t: ParseTree, _ ruleIndex: Int) -> Array<ParseTree> {
        return findAllNodes(t, ruleIndex, false)
    }
    public static func findAllNodes(_ t: ParseTree, _ index: Int, _ findTokens: Bool) -> Array<ParseTree> {
        var nodes: Array<ParseTree> = Array<ParseTree>()
        _findAllNodes(t, index, findTokens, &nodes)
        return nodes
    }
    public static func _findAllNodes(_ t: ParseTree,
                                    _ index: Int, _ findTokens: Bool, _ nodes: inout Array<ParseTree>) {
        // check this node (the root) first
        if let tnode = t as? TerminalNode , findTokens {
            if tnode.getSymbol()!.getType() == index {
                nodes.append(t)
            }
        } else {
            if let ctx = t as? ParserRuleContext , !findTokens {
                if ctx.getRuleIndex() == index {
                    nodes.append(t)
                }
            }
        }
        // check children
        let length = t.getChildCount()
        for i in 0..<length {
            _findAllNodes(t.getChild(i) as! ParseTree, index, findTokens, &nodes)
        }
    }
    public static func descendants(_ t: ParseTree) -> Array<ParseTree> {
        var nodes: Array<ParseTree> = [t]
        let n: Int = t.getChildCount()
        for i in 0..<n {
            //nodes.addAll(descendants(t.getChild(i)));
            if let child = t.getChild(i) {
                nodes.concat(descendants(child as! ParseTree))
            }
        }
        return nodes
    }
    /// Find smallest subtree of t enclosing range startTokenIndex..stopTokenIndex
    /// inclusively using postorder traversal.  Recursive depth-first-search.
    ///
    /// - Since: 4.5.1
    ///
    public static func getRootOfSubtreeEnclosingRegion(_ t: ParseTree,
                                                      _ startTokenIndex: Int,
                                                      _ stopTokenIndex: Int) -> ParserRuleContext? {
        let n: Int = t.getChildCount()
        for i in 0..<n {
            //TODO t.getChild(i) nil
            //Added by janyou
            guard let child = t.getChild(i) as? ParseTree else {
                return nil
            }
            if let r = getRootOfSubtreeEnclosingRegion(child, startTokenIndex, stopTokenIndex) {
                return r
            }
        }
        if let r = t as? ParserRuleContext {
            if startTokenIndex >= r.getStart()!.getTokenIndex() && // is range fully contained in t?
                    stopTokenIndex <= r.getStop()!.getTokenIndex() {
                return r
            }
        }
        return nil
    }
    private init() {
    }
}


AbstractParseTreeVisitor

 */
open class AbstractParseTreeVisitor<T>: ParseTreeVisitor<T> {
    public override init() {
        super.init()
    }
    ///
    /// The default implementation calls _org.antlr.v4.runtime.tree.ParseTree#accept_ on the
    /// specified tree.
    ///
    open override func visit(_ tree: ParseTree) -> T? {
        return tree.accept(self)
    }
    ///
    /// The default implementation initializes the aggregate result to
    /// _#defaultResult defaultResult()_. Before visiting each child, it
    /// calls _#shouldVisitNextChild shouldVisitNextChild_; if the result
    /// is `false` no more children are visited and the current aggregate
    /// result is returned. After visiting a child, the aggregate result is
    /// updated by calling _#aggregateResult aggregateResult_ with the
    /// previous aggregate result and the result of visiting the child.
    ///
    /// The default implementation is not safe for use in visitors that modify
    /// the tree structure. Visitors that modify the tree should override this
    /// method to behave properly in respect to the specific algorithm in use.
    ///
    open override func visitChildren(_ node: RuleNode) -> T? {
        var result: T? = defaultResult()
        let n = node.getChildCount()
        for i in 0..<n {
            if !shouldVisitNextChild(node, result) {
                break
            }
            let c = node[i]
            let childResult = c.accept(self)
            result = aggregateResult(result, childResult)
        }
        return result
    }
    ///
    /// The default implementation returns the result of
    /// _#defaultResult defaultResult_.
    ///
    open override func visitTerminal(_ node: TerminalNode) -> T? {
        return defaultResult()
    }
    ///
    /// The default implementation returns the result of
    /// _#defaultResult defaultResult_.
    ///
    override
    open func visitErrorNode(_ node: ErrorNode) -> T? {
        return defaultResult()
    }
    ///
    /// Gets the default value returned by visitor methods. This value is
    /// returned by the default implementations of
    /// _#visitTerminal visitTerminal_, _#visitErrorNode visitErrorNode_.
    /// The default implementation of _#visitChildren visitChildren_
    /// initializes its aggregate result to this value.
    ///
    /// The base implementation returns `null`.
    ///
    /// - Returns: The default value returned by visitor methods.
    ///
    open func defaultResult() -> T? {
        return nil
    }
    ///
    /// Aggregates the results of visiting multiple children of a node. After
    /// either all children are visited or _#shouldVisitNextChild_ returns
    /// `false`, the aggregate value is returned as the result of
    /// _#visitChildren_.
    ///
    /// The default implementation returns `nextResult`, meaning
    /// _#visitChildren_ will return the result of the last child visited
    /// (or return the initial value if the node has no children).
    ///
    /// - Parameter aggregate: The previous aggregate value. In the default
    /// implementation, the aggregate value is initialized to
    /// _#defaultResult_, which is passed as the `aggregate` argument
    /// to this method after the first child node is visited.
    /// - Parameter nextResult: The result of the immediately preceeding call to visit
    /// a child node.
    ///
    /// - Returns: The updated aggregate result.
    ///
    open func aggregateResult(_ aggregate: T?, _ nextResult: T?) -> T? {
        return nextResult
    }
    ///
    /// This method is called after visiting each child in
    /// _#visitChildren_. This method is first called before the first
    /// child is visited; at that point `currentResult` will be the initial
    /// value (in the default implementation, the initial value is returned by a
    /// call to _#defaultResult_. This method is not called after the last
    /// child is visited.
    ///
    /// The default implementation always returns `true`, indicating that
    /// `visitChildren` should only return after all children are visited.
    /// One reason to override this method is to provide a "short circuit"
    /// evaluation option for situations where the result of visiting a single
    /// child has the potential to determine the result of the visit operation as
    /// a whole.
    ///
    /// - Parameter node: The _org.antlr.v4.runtime.tree.RuleNode_ whose children are currently being
    /// visited.
    /// - Parameter currentResult: The current aggregate result of the children visited
    /// to the current point.
    ///
    /// - Returns: `true` to continue visiting children. Otherwise return
    /// `false` to stop visiting children and immediately return the
    /// current aggregate result from _#visitChildren_.
    ///
    open func shouldVisitNextChild(_ node: RuleNode, _ currentResult: T?) -> Bool {
        return true
    }
}


SyntaxTree

 */
/// A tree that knows about an interval in a token stream
/// is some kind of syntax tree. Subinterfaces distinguish
/// between parse trees and other kinds of syntax trees we might want to create.
///
public protocol SyntaxTree: Tree {
    ///
    /// Return an _org.antlr.v4.runtime.misc.Interval_ indicating the index in the
    /// _org.antlr.v4.runtime.TokenStream_ of the first and last token associated with this
    /// subtree. If this node is a leaf, then the interval represents a single
    /// token.
    ///
    /// If source interval is unknown, this returns _org.antlr.v4.runtime.misc.Interval#INVALID_.
    ///
    func getSourceInterval() -> Interval
}


TerminalNode

 */
public protocol TerminalNode: ParseTree {
    func getSymbol() -> Token?
}


RuleNode

 */
public protocol RuleNode: ParseTree {
    func getRuleContext() -> RuleContext
}