LexerAction

///
///
///
/// Represents a single action which can be executed following the successful
/// match of a lexer rule. Lexer actions are used for both embedded action syntax
/// and ANTLR 4's new lexer command syntax.
///
/// -  Sam Harwell
/// -  4.2
///
public class LexerAction: Hashable {
    ///
    /// Gets the serialization type of the lexer action.
    ///
    /// - returns: The serialization type of the lexer action.
    ///
    public func getActionType() -> LexerActionType {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Gets whether the lexer action is position-dependent. Position-dependent
    /// actions may have different semantics depending on the _org.antlr.v4.runtime.CharStream_
    /// index at the time the action is executed.
    ///
    /// Many lexer commands, including `type`, `skip`, and
    /// `more`, do not check the input index during their execution.
    /// Actions like this are position-independent, and may be stored more
    /// efficiently as part of the _org.antlr.v4.runtime.atn.LexerATNConfig#lexerActionExecutor_.
    ///
    /// - returns: `true` if the lexer action semantics can be affected by the
    /// position of the input _org.antlr.v4.runtime.CharStream_ at the time it is executed;
    /// otherwise, `false`.
    ///
    public func isPositionDependent() -> Bool {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Execute the lexer action in the context of the specified _org.antlr.v4.runtime.Lexer_.
    ///
    /// For position-dependent actions, the input stream must already be
    /// positioned correctly prior to calling this method.
    ///
    /// - parameter lexer: The lexer instance.
    ///
    public func execute(_ lexer: Lexer) throws {
        fatalError(#function + " must be overridden")
    }
    public func hash(into hasher: inout Hasher) {
        fatalError(#function + " must be overridden")
    }
}
public func ==(lhs: LexerAction, rhs: LexerAction) -> Bool {
    if lhs === rhs {
        return true
    }
    if (lhs is LexerChannelAction) && (rhs is LexerChannelAction) {
        return (lhs as! LexerChannelAction) == (rhs as! LexerChannelAction)
    } else if (lhs is LexerCustomAction) && (rhs is LexerCustomAction) {
        return (lhs as! LexerCustomAction) == (rhs as! LexerCustomAction)
    } else if (lhs is LexerIndexedCustomAction) && (rhs is LexerIndexedCustomAction) {
        return (lhs as! LexerIndexedCustomAction) == (rhs as! LexerIndexedCustomAction)
    } else if (lhs is LexerModeAction) && (rhs is LexerModeAction) {
        return (lhs as! LexerModeAction) == (rhs as! LexerModeAction)
    } else if (lhs is LexerMoreAction) && (rhs is LexerMoreAction) {
        return (lhs as! LexerMoreAction) == (rhs as! LexerMoreAction)
    } else if (lhs is LexerPopModeAction) && (rhs is LexerPopModeAction) {
        return (lhs as! LexerPopModeAction) == (rhs as! LexerPopModeAction)
    } else if (lhs is LexerPushModeAction) && (rhs is LexerPushModeAction) {
        return (lhs as! LexerPushModeAction) == (rhs as! LexerPushModeAction)
    } else if (lhs is LexerSkipAction) && (rhs is LexerSkipAction) {
        return (lhs as! LexerSkipAction) == (rhs as! LexerSkipAction)
    } else if (lhs is LexerTypeAction) && (rhs is LexerTypeAction) {
        return (lhs as! LexerTypeAction) == (rhs as! LexerTypeAction)
    }
    return false
}


LexerATNSimulator

///
///
///
/// "dup" of ParserInterpreter
///
open class LexerATNSimulator: ATNSimulator {
    public static let debug = false
    public let dfa_debug = false
    public static let MIN_DFA_EDGE = 0
    public static let MAX_DFA_EDGE = 127  // forces unicode to stay in ATN
    ///
    /// When we hit an accept state in either the DFA or the ATN, we
    /// have to notify the character stream to start buffering characters
    /// via _org.antlr.v4.runtime.IntStream#mark_ and record the current state. The current sim state
    /// includes the current index into the input, the current line,
    /// and current character position in that line. Note that the Lexer is
    /// tracking the starting line and characterization of the token. These
    /// variables track the "state" of the simulator when it hits an accept state.
    ///
    /// We track these variables separately for the DFA and ATN simulation
    /// because the DFA simulation often has to fail over to the ATN
    /// simulation. If the ATN simulation fails, we need the DFA to fall
    /// back to its previously accepted state, if any. If the ATN succeeds,
    /// then the ATN does the accept and the DFA simulator that invoked it
    /// can simply return the predicted token type.
    ///
    internal class SimState {
        internal var index: Int = -1
        internal var line: Int = 0
        internal var charPos: Int = -1
        internal var dfaState: DFAState?
        internal func reset() {
            index = -1
            line = 0
            charPos = -1
            dfaState = nil
        }
    }
    internal weak var recog: Lexer?
    ///
    /// The current token's starting index into the character stream.
    /// Shared across DFA to ATN simulation in case the ATN fails and the
    /// DFA did not have a previous accept state. In this case, we use the
    /// ATN-generated exception object.
    ///
    internal var startIndex = -1
    ///
    /// line number 1..n within the input
    ///
    public var line = 1
    ///
    /// The index of the character relative to the beginning of the line 0..n-1
    ///
    public var charPositionInLine = 0
    public private(set) final var decisionToDFA: [DFA]
    internal var mode = Lexer.DEFAULT_MODE
    ///
    /// Used during DFA/ATN exec to record the most recent accept configuration info
    ///
    internal final var prevAccept = SimState()
    public convenience init(_ atn: ATN, _ decisionToDFA: [DFA],
        _ sharedContextCache: PredictionContextCache) {
            self.init(nil, atn, decisionToDFA, sharedContextCache)
    }
    public init(_ recog: Lexer?, _ atn: ATN,
        _ decisionToDFA: [DFA],
        _ sharedContextCache: PredictionContextCache) {
            self.decisionToDFA = decisionToDFA
            self.recog = recog
            super.init(atn, sharedContextCache)
    }
    open func copyState(_ simulator: LexerATNSimulator) {
        self.charPositionInLine = simulator.charPositionInLine
        self.line = simulator.line
        self.mode = simulator.mode
        self.startIndex = simulator.startIndex
    }
    open func match(_ input: CharStream, _ mode: Int) throws -> Int {
        self.mode = mode
        let mark = input.mark()
        defer {
            try! input.release(mark)
        }
        self.startIndex = input.index()
        self.prevAccept.reset()
        let dfa = decisionToDFA[mode]
        if let s0 = dfa.s0 {
            return try execATN(input, s0)
        }
        else {
            return try matchATN(input)
        }
    }
    override
    open func reset() {
        prevAccept.reset()
        startIndex = -1
        line = 1
        charPositionInLine = 0
        mode = Lexer.DEFAULT_MODE
    }
    override
    open func clearDFA() {
        for d in 0..<decisionToDFA.count {
            decisionToDFA[d] = DFA(atn.getDecisionState(d)!, d)
        }
    }
    internal func matchATN(_ input: CharStream) throws -> Int {
        let startState = atn.modeToStartState[mode]
        if LexerATNSimulator.debug {
            print("matchATN mode \(mode) start: \(startState)\n")
        }
        let old_mode = mode
        let s0_closure = try computeStartState(input, startState)
        let suppressEdge = s0_closure.hasSemanticContext
        s0_closure.hasSemanticContext = false
        let next = addDFAState(s0_closure)
        if !suppressEdge {
            decisionToDFA[mode].s0 = next
        }
        let predict = try execATN(input, next)
        if LexerATNSimulator.debug {
            print("DFA after matchATN: \(decisionToDFA[old_mode].toLexerString())")
        }
        return predict
    }
    internal func execATN(_ input: CharStream, _ ds0: DFAState) throws -> Int {
        //print("enter exec index "+input.index()+" from "+ds0.configs);
        if LexerATNSimulator.debug {
            print("start state closure=\(ds0.configs)\n")
        }
        if ds0.isAcceptState {
            // allow zero-length tokens
            captureSimState(prevAccept, input, ds0)
        }
        var t = try input.LA(1)
        var s = ds0 // s is current/from DFA state
        while true {
            // while more work
            if LexerATNSimulator.debug {
                print("execATN loop starting closure: \(s.configs)\n")
            }
            // As we move src->trg, src->trg, we keep track of the previous trg to
            // avoid looking up the DFA state again, which is expensive.
            // If the previous target was already part of the DFA, we might
            // be able to avoid doing a reach operation upon t. If s!=null,
            // it means that semantic predicates didn't prevent us from
            // creating a DFA state. Once we know s!=null, we check to see if
            // the DFA state has an edge already for t. If so, we can just reuse
            // it's configuration set; there's no point in re-computing it.
            // This is kind of like doing DFA simulation within the ATN
            // simulation because DFA simulation is really just a way to avoid
            // computing reach/closure sets. Technically, once we know that
            // we have a previously added DFA state, we could jump over to
            // the DFA simulator. But, that would mean popping back and forth
            // a lot and making things more complicated algorithmically.
            // This optimization makes a lot of sense for loops within DFA.
            // A character will take us back to an existing DFA state
            // that already has lots of edges out of it. e.g., .* in comments.
            var target: DFAState
            if let existingTarget = getExistingTargetState(s, t) {
                target = existingTarget
            } else {
                target = try computeTargetState(input, s, t)
            }
            if target == ATNSimulator.ERROR {
                break
            }
            // If this is a consumable input element, make sure to consume before
            // capturing the accept state so the input index, line, and char
            // position accurately reflect the state of the interpreter at the
            // end of the token.
            if t != BufferedTokenStream.EOF {
                try consume(input)
            }
            if target.isAcceptState {
                captureSimState(prevAccept, input, target)
                if t == BufferedTokenStream.EOF {
                    break
                }
            }
            t = try input.LA(1)
            s = target // flip; current DFA target becomes new src/from state
        }
        return try failOrAccept(prevAccept, input, s.configs, t)
    }
    ///
    /// Get an existing target state for an edge in the DFA. If the target state
    /// for the edge has not yet been computed or is otherwise not available,
    /// this method returns `null`.
    ///
    /// - parameter s: The current DFA state
    /// - parameter t: The next input symbol
    /// - returns: The existing target DFA state for the given input symbol
    /// `t`, or `null` if the target state for this edge is not
    /// already cached
    ///
    internal func getExistingTargetState(_ s: DFAState, _ t: Int) -> DFAState? {
        if s.edges == nil || t < LexerATNSimulator.MIN_DFA_EDGE || t > LexerATNSimulator.MAX_DFA_EDGE {
            return nil
        }
        let target = s.edges[t - LexerATNSimulator.MIN_DFA_EDGE]
        if LexerATNSimulator.debug && target != nil {
            print("reuse state \(s.stateNumber) edge to \(target!.stateNumber)")
        }
        return target
    }
    ///
    /// Compute a target state for an edge in the DFA, and attempt to add the
    /// computed state and corresponding edge to the DFA.
    ///
    /// - parameter input: The input stream
    /// - parameter s: The current DFA state
    /// - parameter t: The next input symbol
    ///
    /// - returns: The computed target DFA state for the given input symbol
    /// `t`. If `t` does not lead to a valid DFA state, this method
    /// returns _#ERROR_.
    ///
    internal func computeTargetState(_ input: CharStream, _ s: DFAState, _ t: Int) throws -> DFAState {
        let reach = ATNConfigSet(true, isOrdered: true)
        // if we don't find an existing DFA state
        // Fill reach starting from closure, following t transitions
        try getReachableConfigSet(input, s.configs, reach, t)
        if reach.isEmpty() {
            // we got nowhere on t from s
            if !reach.hasSemanticContext {
                // we got nowhere on t, don't throw out this knowledge; it'd
                // cause a failover from DFA later.
                addDFAEdge(s, t, ATNSimulator.ERROR)
            }
            // stop when we can't match any more char
            return ATNSimulator.ERROR
        }
        // Add an edge from s to target DFA found/created for reach
        return addDFAEdge(s, t, reach)
    }
    internal func failOrAccept(_ prevAccept: SimState, _ input: CharStream,
        _ reach: ATNConfigSet, _ t: Int) throws -> Int {
            if let dfaState = prevAccept.dfaState {
                let lexerActionExecutor = dfaState.lexerActionExecutor
                try accept(input, lexerActionExecutor, startIndex,
                    prevAccept.index, prevAccept.line, prevAccept.charPos)
                return dfaState.prediction
            } else {
                // if no accept and EOF is first char, return EOF
                if t == BufferedTokenStream.EOF && input.index() == startIndex {
                    return CommonToken.EOF
                }
                throw ANTLRException.recognition(e: LexerNoViableAltException(recog, input, startIndex, reach))
            }
    }
    ///
    /// Given a starting configuration set, figure out all ATN configurations
    /// we can reach upon input `t`. Parameter `reach` is a return
    /// parameter.
    ///
    internal func getReachableConfigSet(_ input: CharStream, _ closureConfig: ATNConfigSet, _ reach: ATNConfigSet, _ t: Int) throws {
        // this is used to skip processing for configs which have a lower priority
        // than a config that already reached an accept state for the same rule
        var skipAlt = ATN.INVALID_ALT_NUMBER
        for c in closureConfig.configs {
            guard let c = c as? LexerATNConfig else {
                continue
            }
            let currentAltReachedAcceptState = (c.alt == skipAlt)
            if currentAltReachedAcceptState && c.hasPassedThroughNonGreedyDecision() {
                continue
            }
            if LexerATNSimulator.debug {
                print("testing \(getTokenName(t)) at \(c.toString(recog, true))\n")
            }
            let n = c.state.getNumberOfTransitions()
            for ti in 0..<n {
                // for each transition
                let trans = c.state.transition(ti)
                if let target = getReachableTarget(trans, t) {
                    var lexerActionExecutor = c.getLexerActionExecutor()
                    if let lex = lexerActionExecutor {
                        lexerActionExecutor = lex.fixOffsetBeforeMatch(input.index() - startIndex)
                    }
                    let treatEofAsEpsilon = (t == BufferedTokenStream.EOF)
                    if try closure(input,
                        LexerATNConfig(c, target, lexerActionExecutor),
                        reach,
                        currentAltReachedAcceptState,
                        true,
                        treatEofAsEpsilon) {
                            // any remaining configs for this alt have a lower priority than
                            // the one that just reached an accept state.
                            skipAlt = c.alt
                            break
                    }
                }
            }
        }
    }
    internal func accept(_ input: CharStream, _ lexerActionExecutor: LexerActionExecutor?,
        _ startIndex: Int, _ index: Int, _ line: Int, _ charPos: Int) throws {
            if LexerATNSimulator.debug {
                print("ACTION \(String(describing: lexerActionExecutor))\n")
            }
            // seek to after last char in token
            try input.seek(index)
            self.line = line
            self.charPositionInLine = charPos
            //TODO: CHECK
            if let lexerActionExecutor = lexerActionExecutor, let recog = recog {
                try lexerActionExecutor.execute(recog, input, startIndex)
            }
    }
    internal func getReachableTarget(_ trans: Transition, _ t: Int) -> ATNState? {
        if trans.matches(t, Character.MIN_VALUE, Character.MAX_VALUE) {
            return trans.target
        }
        return nil
    }
    final func computeStartState(_ input: CharStream,
        _ p: ATNState) throws -> ATNConfigSet {
            let initialContext = EmptyPredictionContext.Instance
            let configs = ATNConfigSet(true, isOrdered: true)
            let length = p.getNumberOfTransitions()
            for i in 0..<length {
                let target = p.transition(i).target
                let c = LexerATNConfig(target, i + 1, initialContext)
                try closure(input, c, configs, false, false, false)
            }
            return configs
    }
    ///
    /// Since the alternatives within any lexer decision are ordered by
    /// preference, this method stops pursuing the closure as soon as an accept
    /// state is reached. After the first accept state is reached by depth-first
    /// search from `config`, all other (potentially reachable) states for
    /// this rule would have a lower priority.
    ///
    /// - returns: `true` if an accept state is reached, otherwise
    /// `false`.
    ///
    final func closure(_ input: CharStream, _ config: LexerATNConfig, _ configs: ATNConfigSet, _ currentAltReachedAcceptState: Bool, _ speculative: Bool, _ treatEofAsEpsilon: Bool) throws -> Bool {
        var currentAltReachedAcceptState = currentAltReachedAcceptState
        if LexerATNSimulator.debug {
            print("closure(" + config.toString(recog, true) + ")")
        }
        if config.state is RuleStopState {
            if LexerATNSimulator.debug {
                if let recog = recog {
                    print("closure at \(recog.getRuleNames()[config.state.ruleIndex!]) rule stop \(config)\n")
                } else {
                    print("closure at rule stop \(config)\n")
                }
            }
            if config.context?.hasEmptyPath() ?? true {
                if config.context?.isEmpty() ?? true {
                    try configs.add(config)
                    return true
                } else {
                    try configs.add(LexerATNConfig(config, config.state, EmptyPredictionContext.Instance))
                    currentAltReachedAcceptState = true
                }
            }
            if let configContext = config.context , !configContext.isEmpty() {
                let length = configContext.size()
                for i in 0..<length {
                    if configContext.getReturnState(i) != PredictionContext.EMPTY_RETURN_STATE {
                        let newContext = configContext.getParent(i)! // "pop" return state
                        let returnState = atn.states[configContext.getReturnState(i)]
                        let c = LexerATNConfig(config, returnState!, newContext)
                        currentAltReachedAcceptState = try closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon)
                    }
                }
            }
            return currentAltReachedAcceptState
        }
        // optimization
        if !config.state.onlyHasEpsilonTransitions() {
            if !currentAltReachedAcceptState || !config.hasPassedThroughNonGreedyDecision() {
                try configs.add(config)
            }
        }
        let p = config.state
        let length = p.getNumberOfTransitions()
        for i in 0..<length {
            let t = p.transition(i)
            if let c = try getEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon) {
                currentAltReachedAcceptState = try closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon)
            }
        }
        return currentAltReachedAcceptState
    }
    // side-effect: can alter configs.hasSemanticContext
    final func getEpsilonTarget(_ input: CharStream,
        _ config: LexerATNConfig,
        _ t: Transition,
        _ configs: ATNConfigSet,
        _ speculative: Bool,
        _ treatEofAsEpsilon: Bool) throws -> LexerATNConfig? {
            var c: LexerATNConfig? = nil
            switch t.getSerializationType() {
            case Transition.RULE:
                let ruleTransition = t as! RuleTransition
                let newContext = SingletonPredictionContext.create(config.context, ruleTransition.followState.stateNumber)
                c = LexerATNConfig(config, t.target, newContext)
                break
            case Transition.PRECEDENCE:
                throw ANTLRError.unsupportedOperation(msg: "Precedence predicates are not supported in lexers.")
            case Transition.PREDICATE:
                ///
                /// Track traversing semantic predicates. If we traverse,
                /// we cannot add a DFA state for this "reach" computation
                /// because the DFA would not test the predicate again in the
                /// future. Rather than creating collections of semantic predicates
                /// like v3 and testing them on prediction, v4 will test them on the
                /// fly all the time using the ATN not the DFA. This is slower but
                /// semantically it's not used that often. One of the key elements to
                /// this predicate mechanism is not adding DFA states that see
                /// predicates immediately afterwards in the ATN. For example,
                ///
                /// a : ID {p1}? | ID {p2}? ;
                ///
                /// should create the start state for rule 'a' (to save start state
                /// competition), but should not create target of ID state. The
                /// collection of ATN states the following ID references includes
                /// states reached by traversing predicates. Since this is when we
                /// test them, we cannot cash the DFA state target of ID.
                ///
                let pt = t as! PredicateTransition
                if LexerATNSimulator.debug {
                    print("EVAL rule \(pt.ruleIndex):\(pt.predIndex)")
                }
                configs.hasSemanticContext = true
                if try evaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative) {
                    c = LexerATNConfig(config, t.target)
                }
                break
            case Transition.ACTION:
                if config.context == nil || config.context!.hasEmptyPath() {
                    // execute actions anywhere in the start rule for a token.
                    //
                    // TODO: if the entry rule is invoked recursively, some
                    // actions may be executed during the recursive call. The
                    // problem can appear when hasEmptyPath() is true but
                    // isEmpty() is false. In this case, the config needs to be
                    // split into two contexts - one with just the empty path
                    // and another with everything but the empty path.
                    // Unfortunately, the current algorithm does not allow
                    // getEpsilonTarget to return two configurations, so
                    // additional modifications are needed before we can support
                    // the split operation.
                    let lexerActionExecutor = LexerActionExecutor.append(config.getLexerActionExecutor(), atn.lexerActions[(t as! ActionTransition).actionIndex])
                    c = LexerATNConfig(config, t.target, lexerActionExecutor)
                    break
                } else {
                    // ignore actions in referenced rules
                    c = LexerATNConfig(config, t.target)
                    break
                }
            case Transition.EPSILON:
                c = LexerATNConfig(config, t.target)
                break
            case Transition.ATOM: fallthrough
            case Transition.RANGE: fallthrough
            case Transition.SET:
                if treatEofAsEpsilon {
                    if t.matches(BufferedTokenStream.EOF, Character.MIN_VALUE, Character.MAX_VALUE) {
                        c = LexerATNConfig(config, t.target)
                        break
                    }
                }
                break
            default:
                return c
            }
            return c
    }
    ///
    /// Evaluate a predicate specified in the lexer.
    ///
    /// If `speculative` is `true`, this method was called before
    /// _#consume_ for the matched character. This method should call
    /// _#consume_ before evaluating the predicate to ensure position
    /// sensitive values, including _org.antlr.v4.runtime.Lexer#getText_, _org.antlr.v4.runtime.Lexer#getLine_,
    /// and _org.antlr.v4.runtime.Lexer#getCharPositionInLine_, properly reflect the current
    /// lexer state. This method should restore `input` and the simulator
    /// to the original state before returning (i.e. undo the actions made by the
    /// call to _#consume_.
    ///
    /// - parameter input: The input stream.
    /// - parameter ruleIndex: The rule containing the predicate.
    /// - parameter predIndex: The index of the predicate within the rule.
    /// - parameter speculative: `true` if the current index in `input` is
    /// one character before the predicate's location.
    ///
    /// - returns: `true` if the specified predicate evaluates to
    /// `true`.
    ///
    final func evaluatePredicate(_ input: CharStream, _ ruleIndex: Int, _ predIndex: Int, _ speculative: Bool) throws -> Bool {
        // assume true if no recognizer was provided
        guard let recog = recog else {
            return true
        }
        if !speculative {
            return try recog.sempred(nil, ruleIndex, predIndex)
        }
        let savedCharPositionInLine = charPositionInLine
        let savedLine = line
        let index = input.index()
        let marker = input.mark()
        do {
            try consume(input)
            defer
            {
                charPositionInLine = savedCharPositionInLine
                line = savedLine
                try! input.seek(index)
                try! input.release(marker)
            }
            return try recog.sempred(nil, ruleIndex, predIndex)
        }
    }
    final func captureSimState(_ settings: SimState,
        _ input: CharStream,
        _ dfaState: DFAState) {
            settings.index = input.index()
            settings.line = line
            settings.charPos = charPositionInLine
            settings.dfaState = dfaState
    }
    private final func addDFAEdge(_ from: DFAState,
        _ t: Int,
        _ q: ATNConfigSet) -> DFAState {
            ///
            /// leading to this call, ATNConfigSet.hasSemanticContext is used as a
            /// marker indicating dynamic predicate evaluation makes this edge
            /// dependent on the specific input sequence, so the static edge in the
            /// DFA should be omitted. The target DFAState is still created since
            /// execATN has the ability to resynchronize with the DFA state cache
            /// following the predicate evaluation step.
            ///
            /// TJP notes: next time through the DFA, we see a pred again and eval.
            /// If that gets us to a previously created (but dangling) DFA
            /// state, we can continue in pure DFA mode from there.
            ///
            let suppressEdge = q.hasSemanticContext
            q.hasSemanticContext = false
            let to = addDFAState(q)
            if suppressEdge {
                return to
            }
            addDFAEdge(from, t, to)
            return to
    }
    private final func addDFAEdge(_ p: DFAState, _ t: Int, _ q: DFAState) {
        if t < LexerATNSimulator.MIN_DFA_EDGE || t > LexerATNSimulator.MAX_DFA_EDGE {
            // Only track edges within the DFA bounds
            return
        }
        if LexerATNSimulator.debug {
            print("EDGE \(p) -> \(q) upon \(t)")
        }
        p.mutex.synchronized {
            if p.edges == nil {
                //  make room for tokens 1..n and -1 masquerading as index 0
                p.edges = [DFAState?](repeating: nil, count: LexerATNSimulator.MAX_DFA_EDGE - LexerATNSimulator.MIN_DFA_EDGE + 1)
            }
            p.edges[t - LexerATNSimulator.MIN_DFA_EDGE] = q // connect
        }
    }
    ///
    /// Add a new DFA state if there isn't one with this set of
    /// configurations already. This method also detects the first
    /// configuration containing an ATN rule stop state. Later, when
    /// traversing the DFA, we will know which rule to accept.
    ///
    final func addDFAState(_ configs: ATNConfigSet) -> DFAState {
        ///
        /// the lexer evaluates predicates on-the-fly; by this point configs
        /// should not contain any configurations with unevaluated predicates.
        ///
        assert(!configs.hasSemanticContext, "Expected: !configs.hasSemanticContext")
        let proposed = DFAState(configs)
        if let rss = configs.firstConfigWithRuleStopState {
            proposed.isAcceptState = true
            proposed.lexerActionExecutor = (rss as! LexerATNConfig).getLexerActionExecutor()
            proposed.prediction = atn.ruleToTokenType[rss.state.ruleIndex!]
        }
        let dfa = decisionToDFA[mode]
        return dfa.statesMutex.synchronized {
            if let existing = dfa.states[proposed] {
                return existing
            }
            let newState = proposed
            newState.stateNumber = dfa.states.count
            configs.setReadonly(true)
            newState.configs = configs
            dfa.states[newState] = newState
            return newState
        }
    }
    public final func getDFA(_ mode: Int) -> DFA {
        return decisionToDFA[mode]
    }
    ///
    /// Get the text matched so far for the current token.
    ///
    public func getText(_ input: CharStream) -> String {
        // index is first lookahead char, don't include.
        return try! input.getText(Interval.of(startIndex, input.index() - 1))
    }
    public func getLine() -> Int {
        return line
    }
    public func setLine(_ line: Int) {
        self.line = line
    }
    public func getCharPositionInLine() -> Int {
        return charPositionInLine
    }
    public func setCharPositionInLine(_ charPositionInLine: Int) {
        self.charPositionInLine = charPositionInLine
    }
    public func consume(_ input: CharStream) throws {
        let curChar = try input.LA(1)
        if String(Character(integerLiteral: curChar)) == "\n" {
            line += 1
            charPositionInLine = 0
        } else {
            charPositionInLine += 1
        }
        try  input.consume()
    }
    public func getTokenName(_ t: Int) -> String {
        if t == -1 {
            return "EOF"
        }
        //if ( atn.g!=null ) return atn.g.getTokenDisplayName(t);
        return "'" + String(Character(integerLiteral: t)) + "'"
    }
}


///
///
public class LL1Analyzer {
    ///
    /// Special value added to the lookahead sets to indicate that we hit
    /// a predicate during analysis if `seeThruPreds==false`.
    ///
    public let HIT_PRED: Int = CommonToken.INVALID_TYPE
    public let atn: ATN
    public init(_ atn: ATN) {
        self.atn = atn
    }
    ///
    /// Calculates the SLL(1) expected lookahead set for each outgoing transition
    /// of an _org.antlr.v4.runtime.atn.ATNState_. The returned array has one element for each
    /// outgoing transition in `s`. If the closure from transition
    /// __i__ leads to a semantic predicate before matching a symbol, the
    /// element at index __i__ of the result will be `null`.
    ///
    /// - parameter s: the ATN state
    /// - returns: the expected symbols for each outgoing transition of `s`.
    ///
    public func getDecisionLookahead(_ s: ATNState?) -> [IntervalSet?]? {
        guard let s = s else {
             return nil
        }
        let length = s.getNumberOfTransitions()
        var look = [IntervalSet?](repeating: nil, count: length)
        for alt in 0..<length {
            look[alt] = IntervalSet()
            var lookBusy = Set<ATNConfig>()
            let seeThruPreds = false // fail to get lookahead upon pred
            _LOOK(s.transition(alt).target, nil, EmptyPredictionContext.Instance,
                    look[alt]!, &lookBusy, BitSet(), seeThruPreds, false)
            // Wipe out lookahead for this alternative if we found nothing
            // or we had a predicate when we !seeThruPreds
            if look[alt]!.size() == 0 || look[alt]!.contains(HIT_PRED) {
                look[alt] = nil
            }
        }
        return look
    }
    ///
    /// Compute set of tokens that can follow `s` in the ATN in the
    /// specified `ctx`.
    ///
    /// If `ctx` is `null` and the end of the rule containing
    /// `s` is reached, _org.antlr.v4.runtime.Token#EPSILON_ is added to the result set.
    /// If `ctx` is not `null` and the end of the outermost rule is
    /// reached, _org.antlr.v4.runtime.Token#EOF_ is added to the result set.
    ///
    /// - parameter s: the ATN state
    /// - parameter ctx: the complete parser context, or `null` if the context
    /// should be ignored
    ///
    /// - returns: The set of tokens that can follow `s` in the ATN in the
    /// specified `ctx`.
    ///
    public func LOOK(_ s: ATNState, _ ctx: RuleContext?) -> IntervalSet {
        return LOOK(s, nil, ctx)
    }
    ///
    /// Compute set of tokens that can follow `s` in the ATN in the
    /// specified `ctx`.
    ///
    /// If `ctx` is `null` and the end of the rule containing
    /// `s` is reached, _org.antlr.v4.runtime.Token#EPSILON_ is added to the result set.
    /// If `ctx` is not `null` and the end of the outermost rule is
    /// reached, _org.antlr.v4.runtime.Token#EOF_ is added to the result set.
    ///
    /// - parameter s: the ATN state
    /// - parameter stopState: the ATN state to stop at. This can be a
    /// _org.antlr.v4.runtime.atn.BlockEndState_ to detect epsilon paths through a closure.
    /// - parameter ctx: the complete parser context, or `null` if the context
    /// should be ignored
    ///
    /// - returns: The set of tokens that can follow `s` in the ATN in the
    /// specified `ctx`.
    ///
    public func LOOK(_ s: ATNState, _ stopState: ATNState?, _ ctx: RuleContext?) -> IntervalSet {
        let r = IntervalSet()
        let seeThruPreds = true // ignore preds; get all lookahead
        let lookContext = ctx != nil ? PredictionContext.fromRuleContext(s.atn!, ctx) : nil
        var config = Set<ATNConfig>()
        _LOOK(s, stopState, lookContext, r, &config, BitSet(), seeThruPreds, true)
        return r
    }
    ///
    /// Compute set of tokens that can follow `s` in the ATN in the
    /// specified `ctx`.
    ///
    /// If `ctx` is `null` and `stopState` or the end of the
    /// rule containing `s` is reached, _org.antlr.v4.runtime.Token#EPSILON_ is added to
    /// the result set. If `ctx` is not `null` and `addEOF` is
    /// `true` and `stopState` or the end of the outermost rule is
    /// reached, _org.antlr.v4.runtime.Token#EOF_ is added to the result set.
    ///
    /// - parameter s: the ATN state.
    /// - parameter stopState: the ATN state to stop at. This can be a
    /// _org.antlr.v4.runtime.atn.BlockEndState_ to detect epsilon paths through a closure.
    /// - parameter ctx: The outer context, or `null` if the outer context should
    /// not be used.
    /// - parameter look: The result lookahead set.
    /// - parameter lookBusy: A set used for preventing epsilon closures in the ATN
    /// from causing a stack overflow. Outside code should pass
    /// `new HashSet<ATNConfig>` for this argument.
    /// - parameter calledRuleStack: A set used for preventing left recursion in the
    /// ATN from causing a stack overflow. Outside code should pass
    /// `new BitSet()` for this argument.
    /// - parameter seeThruPreds: `true` to true semantic predicates as
    /// implicitly `true` and "see through them", otherwise `false`
    /// to treat semantic predicates as opaque and add _#HIT_PRED_ to the
    /// result if one is encountered.
    /// - parameter addEOF: Add _org.antlr.v4.runtime.Token#EOF_ to the result if the end of the
    /// outermost context is reached. This parameter has no effect if `ctx`
    /// is `null`.
    ///
    internal func _LOOK(_ s: ATNState,
                        _ stopState: ATNState?,
                        _ ctx: PredictionContext?,
                        _ look: IntervalSet,
                        _ lookBusy: inout Set<ATNConfig>,
                        _ calledRuleStack: BitSet,
                        _ seeThruPreds: Bool,
                        _ addEOF: Bool) {
        // print ("_LOOK(\(s.stateNumber), ctx=\(ctx)");
        let c = ATNConfig(s, ATN.INVALID_ALT_NUMBER, ctx)
        }
        if s == stopState {
            guard let ctx = ctx else {
                try! look.add(CommonToken.EPSILON)
                return
            }
            if ctx.isEmpty() && addEOF {
                try! look.add(CommonToken.EOF)
                return
            }
        }
        if s is RuleStopState {
            guard let ctx = ctx else {
                try! look.add(CommonToken.EPSILON)
                return
            }
            if ctx.isEmpty() && addEOF {
                try! look.add(CommonToken.EOF)
                return
            }
            if ctx != EmptyPredictionContext.Instance {
                let removed = try! calledRuleStack.get(s.ruleIndex!)
                try! calledRuleStack.clear(s.ruleIndex!)
                defer {
                    if removed {
                         try! calledRuleStack.set(s.ruleIndex!)
                     }
                }
                // run thru all possible stack tops in ctx
                let length = ctx.size()
                for i in 0..<length {
                    let returnState = atn.states[(ctx.getReturnState(i))]!
                    _LOOK(returnState, stopState, ctx.getParent(i), look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
                }
                return
            }
        }
        let n = s.getNumberOfTransitions()
        for i in 0..<n {
            let t = s.transition(i)
            if let rt = t as? RuleTransition {
                if try! calledRuleStack.get(rt.target.ruleIndex!) {
                    continue
                }
                let newContext = SingletonPredictionContext.create(ctx, rt.followState.stateNumber)
                try! calledRuleStack.set(rt.target.ruleIndex!)
                _LOOK(t.target, stopState, newContext, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
                try! calledRuleStack.clear(rt.target.ruleIndex!)
            }
            else if t is AbstractPredicateTransition {
                if seeThruPreds {
                    _LOOK(t.target, stopState, ctx, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
                } else {
                    try! look.add(HIT_PRED)
                }
            }
            else if t.isEpsilon() {
                _LOOK(t.target, stopState, ctx, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
            }
            else if t is WildcardTransition {
                try! look.addAll(IntervalSet.of(CommonToken.MIN_USER_TOKEN_TYPE, atn.maxTokenType))
            }
            else {
                var set = t.labelIntervalSet()
                if set != nil {
                    if t is NotSetTransition {
                        set = set!.complement(IntervalSet.of(CommonToken.MIN_USER_TOKEN_TYPE, atn.maxTokenType)) as? IntervalSet
                    }
                    try! look.addAll(set)
                }
            }
        }
    }
}


PrecedencePredicateTransition

///
///
///
///
/// -  Sam Harwell
///
public final class PrecedencePredicateTransition: AbstractPredicateTransition, CustomStringConvertible {
    public let precedence: Int
    public init(_ target: ATNState, _ precedence: Int) {
        self.precedence = precedence
        super.init(target)
    }
    override
    public func getSerializationType() -> Int {
        return Transition.PRECEDENCE
    }
    override
    public func isEpsilon() -> Bool {
        return true
    }
    override
    public func matches(_ symbol: Int, _ minVocabSymbol: Int, _ maxVocabSymbol: Int) -> Bool {
        return false
    }
    public func getPredicate() -> SemanticContext.PrecedencePredicate {
        return SemanticContext.PrecedencePredicate(precedence)
    }
    public var description: String {
        return "\(precedence)  >= _p"
    }
}


PlusLoopbackState

///
///
///
/// Decision state for `A+` and `(A|B)+`.  It has two transitions:
/// one to the loop back to start of the block and one to exit.
///
public final class PlusLoopbackState: DecisionState {
    override
    public func getStateType() -> Int {
        return ATNState.PLUS_LOOP_BACK
    }
}


BasicState

///
///
///
///
/// -  Sam Harwell
///
public final class BasicState: ATNState {
    override
    public func getStateType() -> Int {
        return ATNState.BASIC
    }
}


AtomTransition

///
///
///
/// TODO: make all transitions sets? no, should remove set edges
///
public final class AtomTransition: Transition, CustomStringConvertible {
    ///
    /// The token type or character value; or, signifies special label.
    ///
    public let label: Int
    public init(_ target: ATNState, _ label: Int) {
        self.label = label
        super.init(target)
    }
    override
    public func getSerializationType() -> Int {
        return Transition.ATOM
    }
    override
    public func labelIntervalSet() -> IntervalSet? {
        return IntervalSet(label)
    }
    override
    public func matches(_ symbol: Int, _ minVocabSymbol: Int, _ maxVocabSymbol: Int) -> Bool {
        return label == symbol
    }
    public var description: String {
        return String(label)
    }
}


LexerMoreAction

///
///
///
/// Implements the `more` lexer action by calling _org.antlr.v4.runtime.Lexer#more_.
///
/// The `more` 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 LexerMoreAction: LexerAction, CustomStringConvertible {
    ///
    /// Provides a singleton instance of this parameterless lexer action.
    ///
    public static let INSTANCE: LexerMoreAction = LexerMoreAction()
    ///
    /// Constructs the singleton instance of the lexer `more` command.
    ///
    private override init() {
    }
    ///
    ///
    /// - returns: This method returns _org.antlr.v4.runtime.atn.LexerActionType#MORE_.
    ///
    override
    public func getActionType() -> LexerActionType {
        return LexerActionType.more
    }
    ///
    ///
    /// - returns: This method returns `false`.
    ///
    override
    public func isPositionDependent() -> Bool {
        return false
    }
    ///
    ///
    ///
    /// This action is implemented by calling _org.antlr.v4.runtime.Lexer#more_.
    ///
    override
    public func execute(_ lexer: Lexer) {
        lexer.more()
    }
    public override func hash(into hasher: inout Hasher) {
        hasher.combine(ObjectIdentifier(self))
    }
    public var description: String {
        return "more"
    }
}
public func ==(lhs: LexerMoreAction, rhs: LexerMoreAction) -> Bool {
    return lhs === rhs
}


ProfilingATNSimulator

///
///
///
/// -  4.3
///
import Foundation
public class ProfilingATNSimulator: ParserATNSimulator {
    private(set) var decisions: [DecisionInfo]
    internal var numDecisions: Int = 0
    internal var _sllStopIndex: Int = 0
    internal var _llStopIndex: Int = 0
    internal var currentDecision: Int = 0
    internal var currentState: DFAState?
    ///
    /// At the point of LL failover, we record how SLL would resolve the conflict so that
    /// we can determine whether or not a decision / input pair is context-sensitive.
    /// If LL gives a different result than SLL's predicted alternative, we have a
    /// context sensitivity for sure. The converse is not necessarily true, however.
    /// It's possible that after conflict resolution chooses minimum alternatives,
    /// SLL could get the same answer as LL. Regardless of whether or not the result indicates
    /// an ambiguity, it is not treated as a context sensitivity because LL prediction
    /// was not required in order to produce a correct prediction for this decision and input sequence.
    /// It may in fact still be a context sensitivity but we don't know by looking at the
    /// minimum alternatives for the current input.
    ///
    internal var conflictingAltResolvedBySLL: Int = 0
    public init(_ parser: Parser) {
        decisions = [DecisionInfo]()
        super.init(parser,
                parser.getInterpreter().atn,
                parser.getInterpreter().decisionToDFA,
                parser.getInterpreter().sharedContextCache)
        numDecisions = atn.decisionToState.count
        for i in 0..<numDecisions {
            decisions.append(DecisionInfo(i))
        }
    }
    override
    public func adaptivePredict(_ input: TokenStream, _ decision: Int,_ outerContext: ParserRuleContext?) throws -> Int {
        let outerContext = outerContext
        self._sllStopIndex = -1
        self._llStopIndex = -1
        self.currentDecision = decision
        let start = ProcessInfo.processInfo.systemUptime //System.nanoTime(); // expensive but useful info
        let alt: Int = try  super.adaptivePredict(input, decision, outerContext)
        let stop = ProcessInfo.processInfo.systemUptime  //System.nanoTime();
        decisions[decision].timeInPrediction += Int64((stop - start) * TimeInterval(NSEC_PER_SEC))
        decisions[decision].invocations += 1
        let SLL_k: Int64 = Int64(_sllStopIndex - _startIndex + 1)
        decisions[decision].SLL_TotalLook += SLL_k
        decisions[decision].SLL_MinLook = decisions[decision].SLL_MinLook == 0 ? SLL_k : min(decisions[decision].SLL_MinLook, SLL_k)
        if SLL_k > decisions[decision].SLL_MaxLook {
            decisions[decision].SLL_MaxLook = SLL_k
            decisions[decision].SLL_MaxLookEvent =
                    LookaheadEventInfo(decision, nil, input, _startIndex, _sllStopIndex, false)
        }
        if _llStopIndex >= 0 {
            let LL_k: Int64 = Int64(_llStopIndex - _startIndex + 1)
            decisions[decision].LL_TotalLook += LL_k
            decisions[decision].LL_MinLook = decisions[decision].LL_MinLook == 0 ? LL_k : min(decisions[decision].LL_MinLook, LL_k)
            if LL_k > decisions[decision].LL_MaxLook {
                decisions[decision].LL_MaxLook = LL_k
                decisions[decision].LL_MaxLookEvent =
                        LookaheadEventInfo(decision, nil, input, _startIndex, _llStopIndex, true)
            }
        }
        defer {
            self.currentDecision = -1
        }
        return alt
    }
    override
    internal func getExistingTargetState(_ previousD: DFAState, _ t: Int) -> DFAState? {
        // this method is called after each time the input position advances
        // during SLL prediction
        _sllStopIndex = _input.index()
        let existingTargetState: DFAState? = super.getExistingTargetState(previousD, t)
        if existingTargetState != nil {
            decisions[currentDecision].SLL_DFATransitions += 1 // count only if we transition over a DFA state
            if existingTargetState == ATNSimulator.ERROR {
                decisions[currentDecision].errors.append(
                ErrorInfo(currentDecision, previousD.configs, _input, _startIndex, _sllStopIndex, false)
                )
            }
        }
        currentState = existingTargetState
        return existingTargetState
    }
    override
    internal func computeTargetState(_ dfa: DFA, _ previousD: DFAState, _ t: Int) throws -> DFAState {
        let state = try super.computeTargetState(dfa, previousD, t)
        currentState = state
        return state
    }
    override
    internal func computeReachSet(_ closure: ATNConfigSet, _ t: Int, _ fullCtx: Bool) throws -> ATNConfigSet? {
        if fullCtx {
            // this method is called after each time the input position advances
            // during full context prediction
            _llStopIndex = _input.index()
        }
        let reachConfigs = try super.computeReachSet(closure, t, fullCtx)
        if fullCtx {
            decisions[currentDecision].LL_ATNTransitions += 1 // count computation even if error
            if reachConfigs != nil {
            } else {
                // no reach on current lookahead symbol. ERROR.
                // TODO: does not handle delayed errors per getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule()
                decisions[currentDecision].errors.append(
                ErrorInfo(currentDecision, closure, _input, _startIndex, _llStopIndex, true)
                )
            }
        } else {
            decisions[currentDecision].SLL_ATNTransitions += 1
            if reachConfigs != nil {
            } else {
                // no reach on current lookahead symbol. ERROR.
                decisions[currentDecision].errors.append(
                ErrorInfo(currentDecision, closure, _input, _startIndex, _sllStopIndex, false)
                )
            }
        }
        return reachConfigs
    }
    override
    internal func evalSemanticContext(_ pred: SemanticContext, _ parserCallStack: ParserRuleContext, _ alt: Int, _ fullCtx: Bool) throws -> Bool {
        let result = try super.evalSemanticContext(pred, parserCallStack, alt, fullCtx)
        if !(pred is SemanticContext.PrecedencePredicate) {
            let fullContext = _llStopIndex >= 0
            let stopIndex = fullContext ? _llStopIndex : _sllStopIndex
            decisions[currentDecision].predicateEvals.append(
                PredicateEvalInfo(currentDecision, _input, _startIndex, stopIndex, pred, result, alt, fullCtx)
            )
        }
        return result
    }
    override
    internal func reportAttemptingFullContext(_ dfa: DFA, _ conflictingAlts: BitSet?, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) {
        if let conflictingAlts = conflictingAlts {
            conflictingAltResolvedBySLL = conflictingAlts.firstSetBit()
        } else {
            let configAlts = configs.getAlts()
            conflictingAltResolvedBySLL = configAlts.firstSetBit()
        }
        decisions[currentDecision].LL_Fallback += 1
        super.reportAttemptingFullContext(dfa, conflictingAlts, configs, startIndex, stopIndex)
    }
    override
    internal func reportContextSensitivity(_ dfa: DFA, _ prediction: Int, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) {
        if prediction != conflictingAltResolvedBySLL {
            decisions[currentDecision].contextSensitivities.append(
            ContextSensitivityInfo(currentDecision, configs, _input, startIndex, stopIndex)
            )
        }
        super.reportContextSensitivity(dfa, prediction, configs, startIndex, stopIndex)
    }
    override
    internal func reportAmbiguity(_ dfa: DFA, _ D: DFAState, _ startIndex: Int, _ stopIndex: Int, _ exact: Bool,
                                  _ ambigAlts: BitSet?, _ configs: ATNConfigSet) {
        var prediction: Int
        if let ambigAlts = ambigAlts {
            prediction = ambigAlts.firstSetBit()
        } else {
            let configAlts = configs.getAlts()
            prediction = configAlts.firstSetBit()
        }
        if configs.fullCtx && prediction != conflictingAltResolvedBySLL {
            // Even though this is an ambiguity we are reporting, we can
            // still detect some context sensitivities.  Both SLL and LL
            // are showing a conflict, hence an ambiguity, but if they resolve
            // to different minimum alternatives we have also identified a
            // context sensitivity.
            decisions[currentDecision].contextSensitivities.append(
            ContextSensitivityInfo(currentDecision, configs, _input, startIndex, stopIndex)
            )
        }
        decisions[currentDecision].ambiguities.append(
        AmbiguityInfo(currentDecision, configs, ambigAlts!,
                _input, startIndex, stopIndex, configs.fullCtx)
        )
        super.reportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts!, configs)
    }
    public func getDecisionInfo() -> [DecisionInfo] {
        return decisions
    }
}


BasicBlockStartState

///
///
///
///
/// -  Sam Harwell
///
public final class BasicBlockStartState: BlockStartState {
    override
    public func getStateType() -> Int {
        return BlockStartState.BLOCK_START
    }
}


ATNConfigSet

///
///
///
/// Specialized _java.util.Set_`<`_org.antlr.v4.runtime.atn.ATNConfig_`>` that can track
/// info about the set, with support for combining similar configurations using a
/// graph-structured stack.
///
public final class ATNConfigSet: Hashable, CustomStringConvertible {
    ///
    /// The reason that we need this is because we don't want the hash map to use
    /// the standard hash code and equals. We need all configurations with the same
    /// `(s,i,_,semctx)` to be equal. Unfortunately, this key effectively doubles
    /// the number of objects associated with ATNConfigs. The other solution is to
    /// use a hash table that lets us specify the equals/hashcode operation.
    ///
    ///
    /// Indicates that the set of configurations is read-only. Do not
    /// allow any code to manipulate the set; DFA states will point at
    /// the sets and they must not change. This does not protect the other
    /// fields; in particular, conflictingAlts is set after
    /// we've made this readonly.
    ///
    private var readonly = false
    ///
    /// All configs but hashed by (s, i, _, pi) not including context. Wiped out
    /// when we go readonly as this set becomes a DFA state.
    ///
    private var configLookup: LookupDictionary
    ///
    /// Track the elements as they are added to the set; supports get(i)
    ///
    public private(set) var configs = [ATNConfig]()
    // TODO: these fields make me pretty uncomfortable but nice to pack up info together, saves recomputation
    // TODO: can we track conflicts as they are added to save scanning configs later?
    public internal(set) var uniqueAlt = ATN.INVALID_ALT_NUMBER
    //TODO no default
    ///
    /// Currently this is only used when we detect SLL conflict; this does
    /// not necessarily represent the ambiguous alternatives. In fact,
    /// I should also point out that this seems to include predicated alternatives
    /// that have predicates that evaluate to false. Computed in computeTargetState().
    ///
    internal var conflictingAlts: BitSet?
    // Used in parser and lexer. In lexer, it indicates we hit a pred
    // while computing a closure operation.  Don't make a DFA state from this.
    public internal(set) var hasSemanticContext = false
    //TODO no default
    public internal(set) var dipsIntoOuterContext = false
    //TODO no default
    ///
    /// Indicates that this configuration set is part of a full context
    /// LL prediction. It will be used to determine how to merge $. With SLL
    /// it's a wildcard whereas it is not for LL context merge.
    ///
    public let fullCtx: Bool
    private var cachedHashCode = -1
    public init(_ fullCtx: Bool = true, isOrdered: Bool = false) {
        configLookup = isOrdered ? LookupDictionary(type: LookupDictionaryType.ordered) : LookupDictionary()
        self.fullCtx = fullCtx
    }
    //override
    public func add(_ config: ATNConfig) throws -> Bool {
        var mergeCache : DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>? = nil
        return try add(config, &mergeCache)
    }
    ///
    /// Adding a new config means merging contexts with existing configs for
    /// `(s, i, pi, _)`, where `s` is the
    /// _org.antlr.v4.runtime.atn.ATNConfig#state_, `i` is the _org.antlr.v4.runtime.atn.ATNConfig#alt_, and
    /// `pi` is the _org.antlr.v4.runtime.atn.ATNConfig#semanticContext_. We use
    /// `(s,i,pi)` as key.
    ///
    /// This method updates _#dipsIntoOuterContext_ and
    /// _#hasSemanticContext_ when necessary.
    ///
    public func add(
        _ config: ATNConfig,
        _ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?) throws -> Bool {
            if readonly {
                throw ANTLRError.illegalState(msg: "This set is readonly")
            }
            if config.semanticContext != SemanticContext.Empty.Instance {
                hasSemanticContext = true
            }
            if config.getOuterContextDepth() > 0 {
                dipsIntoOuterContext = true
            }
            let existing: ATNConfig = getOrAdd(config)
            if existing === config {
                // we added this new one
                cachedHashCode = -1
                configs.append(config)  // track order here
                return true
            }
            // a previous (s,i,pi,_), merge with it and save result
            let rootIsWildcard = !fullCtx
            let merged = PredictionContext.merge(existing.context!, config.context!, rootIsWildcard, &mergeCache)
            // no need to check for existing.context, config.context in cache
            // since only way to create new graphs is "call rule" and here. We
            // cache at both places.
            existing.reachesIntoOuterContext =
                max(existing.reachesIntoOuterContext, config.reachesIntoOuterContext)
            // make sure to preserve the precedence filter suppression during the merge
            if config.isPrecedenceFilterSuppressed() {
                existing.setPrecedenceFilterSuppressed(true)
            }
            existing.context = merged // replace context; no need to alt mapping
            return true
    }
    public func getOrAdd(_ config: ATNConfig) -> ATNConfig {
        return configLookup.getOrAdd(config)
    }
    ///
    /// Return a List holding list of configs
    ///
    public func elements() -> [ATNConfig] {
        return configs
    }
    public func getStates() -> Set<ATNState> {
        var states = Set<ATNState>(minimumCapacity: configs.count)
        for config in configs {
            states.insert(config.state)
        }
        return states
    }
    ///
    /// Gets the complete set of represented alternatives for the configuration
    /// set.
    ///
    /// - returns: the set of represented alternatives in this configuration set
    ///
    /// - since: 4.3
    ///
    public func getAlts() -> BitSet {
        let alts = BitSet()
        for config in configs {
            try! alts.set(config.alt)
        }
        return alts
    }
    public func getPredicates() -> [SemanticContext] {
        var preds = [SemanticContext]()
        for config in configs {
            if config.semanticContext != SemanticContext.Empty.Instance {
                preds.append(config.semanticContext)
            }
        }
        return preds
    }
    public func get(_ i: Int) -> ATNConfig {
        return configs[i]
    }
    public func optimizeConfigs(_ interpreter: ATNSimulator) throws {
        if readonly {
            throw ANTLRError.illegalState(msg: "This set is readonly")
        }
        if configLookup.isEmpty {
            return
        }
        for config in configs {
            config.context = interpreter.getCachedContext(config.context!)
        }
    }
        }
        return false
    }
    public func hash(into hasher: inout Hasher) {
        if isReadonly() {
            if cachedHashCode == -1 {
                cachedHashCode = configsHashValue
            }
            hasher.combine(cachedHashCode)
        }
        else {
            hasher.combine(configsHashValue)
        }
    }
    private var configsHashValue: Int {
        var hashCode = 1
        for item in configs {
            hashCode = hashCode &* 3 &+ item.hashValue
        }
        return hashCode
    }
    public var count: Int {
        return configs.count
    }
    public func size() -> Int {
        return configs.count
    }
    public func isEmpty() -> Bool {
        return configs.isEmpty
    }
    public func contains(_ o: ATNConfig) -> Bool {
        return configLookup.contains(o)
    }
    public func clear() throws {
        if readonly {
            throw ANTLRError.illegalState(msg: "This set is readonly")
        }
        configs.removeAll()
        cachedHashCode = -1
        configLookup.removeAll()
    }
    public func isReadonly() -> Bool {
        return readonly
    }
    public func setReadonly(_ readonly: Bool) {
        self.readonly = readonly
        configLookup.removeAll()
    }
    public var description: String {
        var buf = ""
        buf += String(describing: elements())
        if hasSemanticContext {
            buf += ",hasSemanticContext=true"
        }
        if uniqueAlt != ATN.INVALID_ALT_NUMBER {
            buf += ",uniqueAlt=\(uniqueAlt)"
        }
        if let conflictingAlts = conflictingAlts {
            buf += ",conflictingAlts=\(conflictingAlts)"
        }
        if dipsIntoOuterContext {
            buf += ",dipsIntoOuterContext"
        }
        return buf
    }
    ///
    /// override
    /// public <T> func toArray(a : [T]) -> [T] {
    /// return configLookup.toArray(a);
    ///
    private func configHash(_ stateNumber: Int,_ context: PredictionContext?) -> Int{
        var hashCode = MurmurHash.initialize(7)
        hashCode = MurmurHash.update(hashCode, stateNumber)
        hashCode = MurmurHash.update(hashCode, context)
        return MurmurHash.finish(hashCode, 2)
    }
    public func getConflictingAltSubsets() -> [BitSet] {
        var configToAlts = [Int: BitSet]()
        for cfg in configs {
            let hash = configHash(cfg.state.stateNumber, cfg.context)
            var alts: BitSet
            if let configToAlt = configToAlts[hash] {
                alts = configToAlt
            } else {
                alts = BitSet()
                configToAlts[hash] = alts
            }
            try! alts.set(cfg.alt)
        }
        return Array(configToAlts.values)
    }
    public func getStateToAltMap() -> [Int: BitSet] {
        var m = [Int: BitSet]()
        for cfg in configs {
            var alts: BitSet
            if let mAlts =  m[cfg.state.stateNumber] {
                alts = mAlts
            } else {
                alts = BitSet()
                m[cfg.state.stateNumber] = alts
            }
            try! alts.set(cfg.alt)
        }
        return m
    }
    //for DFAState
    public func getAltSet() -> Set<Int>?  {
        if configs.isEmpty {
            return nil
        }
        var alts = Set<Int>()
        for config in configs {
            alts.insert(config.alt)
        }
        return alts
    }
    //for DiagnosticErrorListener
    public func getAltBitSet() -> BitSet  {
        let result = BitSet()
        for config in configs {
            try! result.set(config.alt)
        }
        return result
    }
    //LexerATNSimulator
    public var firstConfigWithRuleStopState: ATNConfig? {
        for config in configs {
            if config.state is RuleStopState {
                return config
            }
        }
        return nil
    }
    //ParserATNSimulator
    public func getUniqueAlt() -> Int {
        var alt = ATN.INVALID_ALT_NUMBER
        for config in configs {
            if alt == ATN.INVALID_ALT_NUMBER {
                alt = config.alt // found first alt
            } else if config.alt != alt {
                return ATN.INVALID_ALT_NUMBER
            }
        }
        return alt
    }
    public func removeAllConfigsNotInRuleStopState(_ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?,_ lookToEndOfRule: Bool,_ atn: ATN) -> ATNConfigSet {
        if PredictionMode.allConfigsInRuleStopStates(self) {
            return self
        }
        let result = ATNConfigSet(fullCtx)
        for config in configs {
            if config.state is RuleStopState {
                try! result.add(config, &mergeCache)
                continue
            }
            if lookToEndOfRule && config.state.onlyHasEpsilonTransitions() {
                let nextTokens = atn.nextTokens(config.state)
                if nextTokens.contains(CommonToken.EPSILON) {
                    let endOfRuleState = atn.ruleToStopState[config.state.ruleIndex!]
                    try! result.add(ATNConfig(config, endOfRuleState), &mergeCache)
                }
            }
        }
        return result
    }
    public func applyPrecedenceFilter(_ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?,_ parser: Parser,_ _outerContext: ParserRuleContext!) throws -> ATNConfigSet {
        let configSet = ATNConfigSet(fullCtx)
        var statesFromAlt1 = [Int: PredictionContext]()
        for config in configs {
            // handle alt 1 first
            if config.alt != 1 {
                continue
            }
            let updatedContext = try config.semanticContext.evalPrecedence(parser, _outerContext)
            if updatedContext == nil {
                // the configuration was eliminated
                continue
            }
            statesFromAlt1[config.state.stateNumber] = config.context
            if updatedContext != config.semanticContext {
                try! configSet.add(ATNConfig(config, updatedContext!), &mergeCache)
            } else {
                try! configSet.add(config, &mergeCache)
            }
        }
        for config in configs {
            if config.alt == 1 {
                // already handled
                continue
            }
            if !config.isPrecedenceFilterSuppressed() {
                ///
                /// In the future, this elimination step could be updated to also
                /// filter the prediction context for alternatives predicting alt>1
                /// (basically a graph subtraction algorithm).
                ///
                let context = statesFromAlt1[config.state.stateNumber]
                if context != nil && context == config.context {
                    // eliminated
                    continue
                }
            }
            try! configSet.add(config, &mergeCache)
        }
        return configSet
    }
    internal func getPredsForAmbigAlts(_ ambigAlts: BitSet, _ nalts: Int) -> [SemanticContext?]? {
        var altToPred = [SemanticContext?](repeating: nil, count: nalts + 1)
        for config in configs {
            if try! ambigAlts.get(config.alt) {
                altToPred[config.alt] = SemanticContext.or(altToPred[config.alt], config.semanticContext)
            }
        }
        var nPredAlts = 0
        for i in 1...nalts {
            if altToPred[i] == nil {
                altToPred[i] = SemanticContext.Empty.Instance
            }
            else if altToPred[i] != SemanticContext.Empty.Instance {
                nPredAlts += 1
            }
        }
        //		// Optimize away p||p and p&&p TODO: optimize() was a no-op
        //		for (int i = 0; i < altToPred.length; i++) {
        //			altToPred[i] = altToPred[i].optimize();
        //		}
        // nonambig alts are null in altToPred
        return (nPredAlts == 0 ? nil : altToPred)
    }
    public func getAltThatFinishedDecisionEntryRule() -> Int {
        let alts = IntervalSet()
        for config in configs {
            if config.getOuterContextDepth() > 0 ||
                (config.state is RuleStopState &&
                    config.context!.hasEmptyPath()) {
                try! alts.add(config.alt)
            }
        }
        if alts.size() == 0 {
            return ATN.INVALID_ALT_NUMBER
        }
        return alts.getMinElement()
    }
    ///
    /// Walk the list of configurations and split them according to
    /// those that have preds evaluating to true/false.  If no pred, assume
    /// true pred and include in succeeded set.  Returns Pair of sets.
    ///
    /// Create a new set so as not to alter the incoming parameter.
    ///
    /// Assumption: the input stream has been restored to the starting point
    /// prediction, which is where predicates need to evaluate.
    ///
    public func splitAccordingToSemanticValidity(
        _ outerContext: ParserRuleContext,
        _ evalSemanticContext: (SemanticContext, ParserRuleContext, Int, Bool) throws -> Bool) rethrows -> (ATNConfigSet, ATNConfigSet) {
        let succeeded = ATNConfigSet(fullCtx)
        let failed = ATNConfigSet(fullCtx)
        for config in configs {
            if config.semanticContext != SemanticContext.Empty.Instance {
                let predicateEvaluationResult = try evalSemanticContext(config.semanticContext, outerContext, config.alt,fullCtx)
                if predicateEvaluationResult {
                    try! succeeded.add(config)
                } else {
                    try! failed.add(config)
                }
            } else {
                try! succeeded.add(config)
            }
        }
        return (succeeded, failed)
    }
    public func dupConfigsWithoutSemanticPredicates() -> ATNConfigSet {
        let dup = ATNConfigSet()
        for config in configs {
            let c = ATNConfig(config, SemanticContext.Empty.Instance)
        }
        return dup
    }
    public var hasConfigInRuleStopState: Bool {
        return configs.contains(where: { $0.state is RuleStopState })
    }
    public var allConfigsInRuleStopStates: Bool {
        return !configs.contains(where: { !($0.state is RuleStopState) })
    }
}
public func ==(lhs: ATNConfigSet, rhs: ATNConfigSet) -> Bool {
    if lhs === rhs {
        return true
    }
    return
        lhs.configs == rhs.configs && // includes stack context
        lhs.fullCtx == rhs.fullCtx &&
        lhs.uniqueAlt == rhs.uniqueAlt &&
        lhs.conflictingAlts == rhs.conflictingAlts &&
        lhs.hasSemanticContext == rhs.hasSemanticContext &&
        lhs.dipsIntoOuterContext == rhs.dipsIntoOuterContext
}


LexerActionExecutor

///
///
///
/// Represents an executor for a sequence of lexer actions which traversed during
/// the matching operation of a lexer rule (token).
///
/// The executor tracks position information for position-dependent lexer actions
/// efficiently, ensuring that actions appearing only at the end of the rule do
/// not cause bloating of the _org.antlr.v4.runtime.dfa.DFA_ created for the lexer.
///
/// -  Sam Harwell
/// -  4.2
///
public class LexerActionExecutor: Hashable {
    fileprivate final var lexerActions: [LexerAction]
    ///
    /// Caches the result of _#hashCode_ since the hash code is an element
    /// of the performance-critical _org.antlr.v4.runtime.atn.LexerATNConfig#hashCode_ operation.
    ///
    fileprivate final var hashCode: Int
    ///
    /// Constructs an executor for a sequence of _org.antlr.v4.runtime.atn.LexerAction_ actions.
    /// - parameter lexerActions: The lexer actions to execute.
    ///
    public init(_ lexerActions: [LexerAction]) {
        self.lexerActions = lexerActions
        var hash = MurmurHash.initialize()
        for lexerAction: LexerAction in lexerActions {
            hash = MurmurHash.update(hash, lexerAction)
        }
        self.hashCode = MurmurHash.finish(hash, lexerActions.count)
    }
    ///
    /// Creates a _org.antlr.v4.runtime.atn.LexerActionExecutor_ which executes the actions for
    /// the input `lexerActionExecutor` followed by a specified
    /// `lexerAction`.
    ///
    /// - parameter lexerActionExecutor: The executor for actions already traversed by
    /// the lexer while matching a token within a particular
    /// _org.antlr.v4.runtime.atn.LexerATNConfig_. If this is `null`, the method behaves as
    /// though it were an empty executor.
    /// - parameter lexerAction: The lexer action to execute after the actions
    /// specified in `lexerActionExecutor`.
    ///
    /// - returns: A _org.antlr.v4.runtime.atn.LexerActionExecutor_ for executing the combine actions
    /// of `lexerActionExecutor` and `lexerAction`.
    ///
    public static func append(_ lexerActionExecutor: LexerActionExecutor?, _ lexerAction: LexerAction) -> LexerActionExecutor {
        guard let lexerActionExecutor = lexerActionExecutor else {
            return LexerActionExecutor([lexerAction])
        }
        //var lexerActions : [LexerAction] = lexerActionExecutor.lexerActions, //lexerActionExecutor.lexerActions.length + 1);
        var lexerActions: [LexerAction] = lexerActionExecutor.lexerActions
        lexerActions.append(lexerAction)
        //lexerActions[lexerActions.length - 1] = lexerAction;
        return LexerActionExecutor(lexerActions)
    }
    ///
    /// Creates a _org.antlr.v4.runtime.atn.LexerActionExecutor_ which encodes the current offset
    /// for position-dependent lexer actions.
    ///
    /// Normally, when the executor encounters lexer actions where
    /// _org.antlr.v4.runtime.atn.LexerAction#isPositionDependent_ returns `true`, it calls
    /// _org.antlr.v4.runtime.IntStream#seek_ on the input _org.antlr.v4.runtime.CharStream_ to set the input
    /// position to the __end__ of the current token. This behavior provides
    /// for efficient DFA representation of lexer actions which appear at the end
    /// of a lexer rule, even when the lexer rule matches a variable number of
    /// characters.
    ///
    /// Prior to traversing a match transition in the ATN, the current offset
    /// from the token start index is assigned to all position-dependent lexer
    /// actions which have not already been assigned a fixed offset. By storing
    /// the offsets relative to the token start index, the DFA representation of
    /// lexer actions which appear in the middle of tokens remains efficient due
    /// to sharing among tokens of the same length, regardless of their absolute
    /// position in the input stream.
    ///
    /// If the current executor already has offsets assigned to all
    /// position-dependent lexer actions, the method returns `this`.
    ///
    /// - parameter offset: The current offset to assign to all position-dependent
    /// lexer actions which do not already have offsets assigned.
    ///
    /// - returns: A _org.antlr.v4.runtime.atn.LexerActionExecutor_ which stores input stream offsets
    /// for all position-dependent lexer actions.
    ///
    public func fixOffsetBeforeMatch(_ offset: Int) -> LexerActionExecutor {
        var updatedLexerActions: [LexerAction]? = nil
        let length = lexerActions.count
        for i in 0..<length {
            if lexerActions[i].isPositionDependent() && !(lexerActions[i] is LexerIndexedCustomAction) {
                if updatedLexerActions == nil {
                    updatedLexerActions = lexerActions   //lexerActions.clone();
                }
                updatedLexerActions![i] = LexerIndexedCustomAction(offset, lexerActions[i])
            }
        }
        if updatedLexerActions == nil {
            return self
        }
        return LexerActionExecutor(updatedLexerActions!)
    }
    ///
    /// Gets the lexer actions to be executed by this executor.
    /// - returns: The lexer actions to be executed by this executor.
    ///
    public func getLexerActions() -> [LexerAction] {
        return lexerActions
    }
    ///
    /// Execute the actions encapsulated by this executor within the context of a
    /// particular _org.antlr.v4.runtime.Lexer_.
    ///
    /// This method calls _org.antlr.v4.runtime.IntStream#seek_ to set the position of the
    /// `input` _org.antlr.v4.runtime.CharStream_ prior to calling
    /// _org.antlr.v4.runtime.atn.LexerAction#execute_ on a position-dependent action. Before the
    /// method returns, the input position will be restored to the same position
    /// it was in when the method was invoked.
    ///
    /// - parameter lexer: The lexer instance.
    /// - parameter input: The input stream which is the source for the current token.
    /// When this method is called, the current _org.antlr.v4.runtime.IntStream#index_ for
    /// `input` should be the start of the following token, i.e. 1
    /// character past the end of the current token.
    /// - parameter startIndex: The token start index. This value may be passed to
    /// _org.antlr.v4.runtime.IntStream#seek_ to set the `input` position to the beginning
    /// of the token.
    ///
    public func execute(_ lexer: Lexer, _ input: CharStream, _ startIndex: Int) throws {
        var requiresSeek: Bool = false
        let stopIndex: Int = input.index()
        defer {
            if requiresSeek {
                try! input.seek(stopIndex)
            }
        }
        //try {
        for var lexerAction: LexerAction in self.lexerActions {
            if let runLexerAction = lexerAction as? LexerIndexedCustomAction {
                let offset: Int = runLexerAction.getOffset()
                try input.seek(startIndex + offset)
                lexerAction = runLexerAction.getAction()
                requiresSeek = (startIndex + offset) != stopIndex
            } else {
                if lexerAction.isPositionDependent() {
                    try input.seek(stopIndex)
                    requiresSeek = false
                }
            }
            try lexerAction.execute(lexer)
        }
        //}
    }
    public func hash(into hasher: inout Hasher) {
        hasher.combine(hashCode)
    }
}
public func ==(lhs: LexerActionExecutor, rhs: LexerActionExecutor) -> Bool {
    if lhs === rhs {
        return true
    }
    if lhs.lexerActions.count != rhs.lexerActions.count {
        return false
    }
    let length = lhs.lexerActions.count
    for i in 0..<length {
        if !(lhs.lexerActions[i] == rhs.lexerActions[i]) {
            return false
        }
    }
    return lhs.hashCode == rhs.hashCode
}


ArrayPredictionContext

///
///
public class ArrayPredictionContext: PredictionContext {
    ///
    /// Parent can be null only if full ctx mode and we make an array
    /// from _#EMPTY_ and non-empty. We merge _#EMPTY_ by using null parent and
    /// returnState == _#EMPTY_RETURN_STATE_.
    ///
    public private(set) final var parents: [PredictionContext?]
    ///
    /// Sorted for merge, no duplicates; if present,
    /// _#EMPTY_RETURN_STATE_ is always last.
    ///
    public final let returnStates: [Int]
    public convenience init(_ a: SingletonPredictionContext) {
        let parents = [a.parent]
        self.init(parents, [a.returnState])
    }
    public init(_ parents: [PredictionContext?], _ returnStates: [Int]) {
        self.parents = parents
        self.returnStates = returnStates
        super.init(PredictionContext.calculateHashCode(parents, returnStates))
    }
    override
    final public func isEmpty() -> Bool {
        // since EMPTY_RETURN_STATE can only appear in the last position, we
        // don't need to verify that size==1
        return returnStates[0] == PredictionContext.EMPTY_RETURN_STATE
    }
    override
    final public func size() -> Int {
        return returnStates.count
    }
    override
    final public func getParent(_ index: Int) -> PredictionContext? {
        return parents[index]
    }
    override
    final public func getReturnState(_ index: Int) -> Int {
        return returnStates[index]
    }
    override
    public var description: String {
        if isEmpty() {
            return "[]"
        }
        var buf = "["
        for (i, returnState) in returnStates.enumerated() {
            if i > 0 {
                buf += ", "
            }
            if returnState == PredictionContext.EMPTY_RETURN_STATE {
                buf += "$"
                continue
            }
            buf += "\(returnState)"
            if let parent = parents[i] {
                buf += " \(parent)"
            }
            else {
                buf += "null"
            }
        }
        buf += "]"
        return buf
    }
    internal final func combineCommonParents() {
        let length = parents.count
        var uniqueParents: Dictionary<PredictionContext, PredictionContext> =
        Dictionary<PredictionContext, PredictionContext>()
        for p in parents {
            if let parent: PredictionContext = p {
                // if !uniqueParents.keys.contains(parent) {
                if uniqueParents[parent] == nil {
                    uniqueParents[parent] = parent  // don't replace
                }
            }
        }
        for p in 0..<length {
            if let parent: PredictionContext = parents[p] {
                parents[p] = uniqueParents[parent]
            }
        }
    }
}
public func ==(lhs: ArrayPredictionContext, rhs: ArrayPredictionContext) -> Bool {
    if lhs === rhs {
        return true
    }
    if lhs.hashValue != rhs.hashValue {
        return false
    }
    return lhs.returnStates == rhs.returnStates && lhs.parents == rhs.parents
}