?, _ stop: RuleContext?) -> String {
- let buf: StringBuilder = StringBuilder()
+ open func toString(_ ruleNames: [String]?, _ stop: RuleContext?) -> String {
+ let buf = StringBuilder()
var p: RuleContext? = self
buf.append("[")
- while let pWrap = p , pWrap !== stop {
- if ruleNames == nil {
+ while let pWrap = p, pWrap !== stop {
+ if let ruleNames = ruleNames {
+ let ruleIndex = pWrap.getRuleIndex()
+ let ruleIndexInRange = (ruleIndex >= 0 && ruleIndex < ruleNames.count)
+ let ruleName = (ruleIndexInRange ? ruleNames[ruleIndex] : String(ruleIndex))
+ buf.append(ruleName)
+ }
+ else {
if !pWrap.isEmpty() {
buf.append(pWrap.invokingState)
}
- } else {
- let ruleIndex: Int = pWrap.getRuleIndex()
- let ruleIndexInRange: Bool = ruleIndex >= 0 && ruleIndex < ruleNames!.count
- let ruleName: String = ruleIndexInRange ? ruleNames![ruleIndex] : String(ruleIndex)
- buf.append(ruleName)
}
if pWrap.parent != nil && (ruleNames != nil || !pWrap.parent!.isEmpty()) {
diff --git a/runtime/Swift/Sources/Antlr4/Token.swift b/runtime/Swift/Sources/Antlr4/Token.swift
index a249adc2a..264318ddd 100644
--- a/runtime/Swift/Sources/Antlr4/Token.swift
+++ b/runtime/Swift/Sources/Antlr4/Token.swift
@@ -98,5 +98,7 @@ public protocol Token: class, CustomStringConvertible {
///
func getInputStream() -> CharStream?
+ func getTokenSourceAndStream() -> TokenSourceAndStream
+
var visited: Bool { get set }
}
diff --git a/runtime/Swift/Sources/Antlr4/TokenFactory.swift b/runtime/Swift/Sources/Antlr4/TokenFactory.swift
index c7ce67cee..63fa74b3c 100644
--- a/runtime/Swift/Sources/Antlr4/TokenFactory.swift
+++ b/runtime/Swift/Sources/Antlr4/TokenFactory.swift
@@ -8,7 +8,6 @@
/// the error handling strategy (to create missing tokens). Notifying the parser
/// of a new factory means that it notifies it's token source and error strategy.
///
-
public protocol TokenFactory {
//typealias Symbol
@@ -16,10 +15,33 @@ public protocol TokenFactory {
/// error handling strategy. If text!=null, than the start and stop positions
/// are wiped to -1 in the text override is set in the CommonToken.
///
- func create(_ source: (TokenSource?, CharStream?), _ type: Int, _ text: String?,
+ func create(_ source: TokenSourceAndStream, _ type: Int, _ text: String?,
_ channel: Int, _ start: Int, _ stop: Int,
_ line: Int, _ charPositionInLine: Int) -> Token
/// Generically useful
func create(_ type: Int, _ text: String) -> Token
}
+
+
+/**
+ Holds the references to the TokenSource and CharStream used to create a Token.
+ These are together to reduce memory footprint by having one instance of
+ TokenSourceAndStream shared across many tokens. The references here are weak
+ to avoid retain cycles.
+ */
+public class TokenSourceAndStream {
+ ///
+ /// An empty TokenSourceAndStream which is used as the default value of
+ /// _#source_ for tokens that do not have a source.
+ ///
+ public static let EMPTY = TokenSourceAndStream()
+
+ public weak var tokenSource: TokenSource?
+ public weak var stream: CharStream?
+
+ public init(_ tokenSource: TokenSource? = nil, _ stream: CharStream? = nil) {
+ self.tokenSource = tokenSource
+ self.stream = stream
+ }
+}
diff --git a/runtime/Swift/Sources/Antlr4/UnbufferedCharStream.swift b/runtime/Swift/Sources/Antlr4/UnbufferedCharStream.swift
new file mode 100644
index 000000000..7ef18facb
--- /dev/null
+++ b/runtime/Swift/Sources/Antlr4/UnbufferedCharStream.swift
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+import Foundation
+
+
+/** Do not buffer up the entire char stream. It does keep a small buffer
+ * for efficiency and also buffers while a mark exists (set by the
+ * lookahead prediction in parser). "Unbuffered" here refers to fact
+ * that it doesn't buffer all data, not that's it's on demand loading of char.
+ *
+ * Before 4.7, this class used the default environment encoding to convert
+ * bytes to UTF-16, and held the UTF-16 bytes in the buffer as chars.
+ *
+ * As of 4.7, the class uses UTF-8 by default, and the buffer holds Unicode
+ * code points in the buffer as ints.
+ */
+open class UnbufferedCharStream: CharStream {
+ private let bufferSize: Int
+
+ /**
+ * A moving window buffer of the data being scanned. While there's a marker,
+ * we keep adding to buffer. Otherwise, {@link #consume consume()} resets so
+ * we start filling at index 0 again.
+ */
+ internal var data: [Int]
+
+ /**
+ * The number of characters currently in {@link #data data}.
+ *
+ * This is not the buffer capacity, that's {@code data.length}.
+ */
+ internal var n = 0
+
+ /**
+ * 0..n-1 index into {@link #data data} of next character.
+ *
+ * The {@code LA(1)} character is {@code data[p]}. If {@code p == n}, we are
+ * out of buffered characters.
+ */
+ internal var p = 0
+
+ /**
+ * Count up with {@link #mark mark()} and down with
+ * {@link #release release()}. When we {@code release()} the last mark,
+ * {@code numMarkers} reaches 0 and we reset the buffer. Copy
+ * {@code data[p]..data[n-1]} to {@code data[0]..data[(n-1)-p]}.
+ */
+ internal var numMarkers = 0
+
+ /**
+ * This is the {@code LA(-1)} character for the current position.
+ */
+ internal var lastChar = -1
+
+ /**
+ * When {@code numMarkers > 0}, this is the {@code LA(-1)} character for the
+ * first character in {@link #data data}. Otherwise, this is unspecified.
+ */
+ internal var lastCharBufferStart = 0
+
+ /**
+ * Absolute character index. It's the index of the character about to be
+ * read via {@code LA(1)}. Goes from 0 to the number of characters in the
+ * entire stream, although the stream size is unknown before the end is
+ * reached.
+ */
+ internal var currentCharIndex = 0
+
+ internal let input: InputStream
+ private var unicodeIterator: UnicodeScalarStreamIterator
+
+
+ /** The name or source of this char stream. */
+ public var name: String = ""
+
+ public init(_ input: InputStream, _ bufferSize: Int = 256) {
+ self.input = input
+ self.bufferSize = bufferSize
+ self.data = [Int](repeating: 0, count: bufferSize)
+ let si = UInt8StreamIterator(input)
+ self.unicodeIterator = UnicodeScalarStreamIterator(si)
+ }
+
+ public func consume() throws {
+ if try LA(1) == CommonToken.EOF {
+ throw ANTLRError.illegalState(msg: "cannot consume EOF")
+ }
+
+ // buf always has at least data[p==0] in this method due to ctor
+ lastChar = data[p] // track last char for LA(-1)
+
+ if p == n - 1 && numMarkers == 0 {
+ n = 0
+ p = -1 // p++ will leave this at 0
+ lastCharBufferStart = lastChar
+ }
+
+ p += 1
+ currentCharIndex += 1
+ sync(1)
+ }
+
+ /**
+ * Make sure we have 'need' elements from current position {@link #p p}.
+ * Last valid {@code p} index is {@code data.length-1}. {@code p+need-1} is
+ * the char index 'need' elements ahead. If we need 1 element,
+ * {@code (p+1-1)==p} must be less than {@code data.length}.
+ */
+ internal func sync(_ want: Int) {
+ let need = (p + want - 1) - n + 1 // how many more elements we need?
+ if need > 0 {
+ fill(need)
+ }
+ }
+
+ /**
+ * Add {@code n} characters to the buffer. Returns the number of characters
+ * actually added to the buffer. If the return value is less than {@code n},
+ * then EOF was reached before {@code n} characters could be added.
+ */
+ @discardableResult internal func fill(_ toAdd: Int) -> Int {
+ for i in 0 ..< toAdd {
+ if n > 0 && data[n - 1] == CommonToken.EOF {
+ return i
+ }
+
+ guard let c = nextChar() else {
+ return i
+ }
+ add(c)
+ }
+
+ return n
+ }
+
+ /**
+ * Override to provide different source of characters than
+ * {@link #input input}.
+ */
+ internal func nextChar() -> Int? {
+ if let next = unicodeIterator.next() {
+ return Int(next.value)
+ }
+ else if unicodeIterator.hasErrorOccurred {
+ return nil
+ }
+ else {
+ return nil
+ }
+ }
+
+ internal func add(_ c: Int) {
+ if n >= data.count {
+ data += [Int](repeating: 0, count: data.count)
+ }
+ data[n] = c
+ n += 1
+ }
+
+ public func LA(_ i: Int) throws -> Int {
+ if i == -1 {
+ return lastChar // special case
+ }
+ sync(i)
+ let index = p + i - 1
+ if index < 0 {
+ throw ANTLRError.indexOutOfBounds(msg: "")
+ }
+ if index >= n {
+ return CommonToken.EOF
+ }
+ return data[index]
+ }
+
+ /**
+ * Return a marker that we can release later.
+ *
+ * The specific marker value used for this class allows for some level of
+ * protection against misuse where {@code seek()} is called on a mark or
+ * {@code release()} is called in the wrong order.
+ */
+ public func mark() -> Int {
+ if numMarkers == 0 {
+ lastCharBufferStart = lastChar
+ }
+
+ let mark = -numMarkers - 1
+ numMarkers += 1
+ return mark
+ }
+
+ /** Decrement number of markers, resetting buffer if we hit 0.
+ * @param marker
+ */
+ public func release(_ marker: Int) throws {
+ let expectedMark = -numMarkers
+ if marker != expectedMark {
+ preconditionFailure("release() called with an invalid marker.")
+ }
+
+ numMarkers -= 1
+ if numMarkers == 0 && p > 0 {
+ // release buffer when we can, but don't do unnecessary work
+
+ // Copy data[p]..data[n-1] to data[0]..data[(n-1)-p], reset ptrs
+ // p is last valid char; move nothing if p==n as we have no valid char
+ if p == n {
+ if data.count != bufferSize {
+ data = [Int](repeating: 0, count: bufferSize)
+ }
+ n = 0
+ }
+ else {
+ data = Array(data[p ..< n])
+ n -= p
+ }
+ p = 0
+ lastCharBufferStart = lastChar
+ }
+ }
+
+ public func index() -> Int {
+ return currentCharIndex
+ }
+
+ /** Seek to absolute character index, which might not be in the current
+ * sliding window. Move {@code p} to {@code index-bufferStartIndex}.
+ */
+ public func seek(_ index_: Int) throws {
+ var index = index_
+
+ if index == currentCharIndex {
+ return
+ }
+
+ if index > currentCharIndex {
+ sync(index - currentCharIndex)
+ index = min(index, getBufferStartIndex() + n - 1)
+ }
+
+ // index == to bufferStartIndex should set p to 0
+ let i = index - getBufferStartIndex()
+ if i < 0 {
+ throw ANTLRError.illegalArgument(msg: "cannot seek to negative index \(index)")
+ }
+ else if i >= n {
+ let si = getBufferStartIndex()
+ let ei = si + n
+ let msg = "seek to index outside buffer: \(index) not in \(si)..\(ei)"
+ throw ANTLRError.unsupportedOperation(msg: msg)
+ }
+
+ p = i
+ currentCharIndex = index
+ if p == 0 {
+ lastChar = lastCharBufferStart
+ }
+ else {
+ lastChar = data[p - 1]
+ }
+ }
+
+ public func size() -> Int {
+ preconditionFailure("Unbuffered stream cannot know its size")
+ }
+
+ public func getSourceName() -> String {
+ return name
+ }
+
+ public func getText(_ interval: Interval) throws -> String {
+ if interval.a < 0 || interval.b < interval.a - 1 {
+ throw ANTLRError.illegalArgument(msg: "invalid interval")
+ }
+
+ let bufferStartIndex = getBufferStartIndex()
+ if n > 0 &&
+ data[n - 1] == CommonToken.EOF &&
+ interval.a + interval.length() > bufferStartIndex + n {
+ throw ANTLRError.illegalArgument(msg: "the interval extends past the end of the stream")
+ }
+
+ if interval.a < bufferStartIndex || interval.b >= bufferStartIndex + n {
+ let msg = "interval \(interval) outside buffer: \(bufferStartIndex)...\(bufferStartIndex + n - 1)"
+ throw ANTLRError.unsupportedOperation(msg: msg)
+ }
+
+ if interval.b < interval.a {
+ // The EOF token.
+ return ""
+ }
+
+ // convert from absolute to local index
+ let i = interval.a - bufferStartIndex
+ let j = interval.b - bufferStartIndex
+
+ // Convert from Int codepoints to a String.
+ let codepoints = data[i ... j].map { Character(Unicode.Scalar($0)!) }
+ return String(codepoints)
+ }
+
+ internal func getBufferStartIndex() -> Int {
+ return currentCharIndex - p
+ }
+}
+
+
+fileprivate struct UInt8StreamIterator: IteratorProtocol {
+ private static let bufferSize = 1024
+
+ private let stream: InputStream
+ private var buffer = [UInt8](repeating: 0, count: UInt8StreamIterator.bufferSize)
+ private var buffGen: IndexingIterator>
+
+ var hasErrorOccurred = false
+
+
+ init(_ stream: InputStream) {
+ self.stream = stream
+ self.buffGen = buffer[0..<0].makeIterator()
+ }
+
+ mutating func next() -> UInt8? {
+ if let result = buffGen.next() {
+ return result
+ }
+
+ if hasErrorOccurred {
+ return nil
+ }
+
+ switch stream.streamStatus {
+ case .notOpen, .writing, .closed:
+ preconditionFailure()
+ case .atEnd:
+ return nil
+ case .error:
+ hasErrorOccurred = true
+ return nil
+ case .opening, .open, .reading:
+ break
+ }
+
+ let count = stream.read(&buffer, maxLength: buffer.count)
+ if count < 0 {
+ hasErrorOccurred = true
+ return nil
+ }
+ else if count == 0 {
+ return nil
+ }
+
+ buffGen = buffer.prefix(count).makeIterator()
+ return buffGen.next()
+ }
+}
+
+
+fileprivate struct UnicodeScalarStreamIterator: IteratorProtocol {
+ private var streamIterator: UInt8StreamIterator
+ private var codec = Unicode.UTF8()
+
+ var hasErrorOccurred = false
+
+ init(_ streamIterator: UInt8StreamIterator) {
+ self.streamIterator = streamIterator
+ }
+
+ mutating func next() -> Unicode.Scalar? {
+ if streamIterator.hasErrorOccurred {
+ hasErrorOccurred = true
+ return nil
+ }
+
+ switch codec.decode(&streamIterator) {
+ case .scalarValue(let scalar):
+ return scalar
+ case .emptyInput:
+ return nil
+ case .error:
+ hasErrorOccurred = true
+ return nil
+ }
+ }
+}
diff --git a/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift b/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift
index f9622e404..da1c8476a 100644
--- a/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift
+++ b/runtime/Swift/Sources/Antlr4/UnbufferedTokenStream.swift
@@ -4,7 +4,7 @@
*/
-public class UnbufferedTokenStream: TokenStream {
+public class UnbufferedTokenStream: TokenStream {
internal var tokenSource: TokenSource
///
@@ -274,10 +274,7 @@ public class UnbufferedTokenStream: TokenStream {
public func size() -> Int {
-
- RuntimeException("Unbuffered stream cannot know its size")
- fatalError()
-
+ fatalError("Unbuffered stream cannot know its size")
}
diff --git a/runtime/Swift/Sources/Antlr4/atn/ATN.swift b/runtime/Swift/Sources/Antlr4/atn/ATN.swift
index 0ed7971d5..bdfc938cd 100644
--- a/runtime/Swift/Sources/Antlr4/atn/ATN.swift
+++ b/runtime/Swift/Sources/Antlr4/atn/ATN.swift
@@ -73,9 +73,9 @@ public class ATN {
/// the rule surrounding `s`. In other words, the set will be
/// restricted to tokens reachable staying within `s`'s rule.
///
- public func nextTokens(_ s: ATNState, _ ctx: RuleContext?)throws -> IntervalSet {
- let anal: LL1Analyzer = LL1Analyzer(self)
- let next: IntervalSet = try anal.LOOK(s, ctx)
+ public func nextTokens(_ s: ATNState, _ ctx: RuleContext?) -> IntervalSet {
+ let anal = LL1Analyzer(self)
+ let next = anal.LOOK(s, ctx)
return next
}
@@ -84,14 +84,14 @@ public class ATN {
/// staying in same rule. _org.antlr.v4.runtime.Token#EPSILON_ is in set if we reach end of
/// rule.
///
- public func nextTokens(_ s: ATNState) throws -> IntervalSet {
+ public func nextTokens(_ s: ATNState) -> IntervalSet {
if let nextTokenWithinRule = s.nextTokenWithinRule
{
return nextTokenWithinRule
}
- let intervalSet = try nextTokens(s, nil)
+ let intervalSet = nextTokens(s, nil)
s.nextTokenWithinRule = intervalSet
- try intervalSet.setReadonly(true)
+ try! intervalSet.setReadonly(true)
return intervalSet
}
@@ -151,27 +151,27 @@ public class ATN {
}
var ctx: RuleContext? = context
- let s: ATNState = states[stateNumber]!
- var following: IntervalSet = try nextTokens(s)
+ let s = states[stateNumber]!
+ var following = nextTokens(s)
if !following.contains(CommonToken.EPSILON) {
return following
}
- let expected: IntervalSet = try IntervalSet()
- try expected.addAll(following)
- try expected.remove(CommonToken.EPSILON)
+ let expected = IntervalSet()
+ try! expected.addAll(following)
+ try! expected.remove(CommonToken.EPSILON)
- while let ctxWrap = ctx , ctxWrap.invokingState >= 0 && following.contains(CommonToken.EPSILON) {
- let invokingState: ATNState = states[ctxWrap.invokingState]!
- let rt: RuleTransition = invokingState.transition(0) as! RuleTransition
- following = try nextTokens(rt.followState)
- try expected.addAll(following)
- try expected.remove(CommonToken.EPSILON)
+ while let ctxWrap = ctx, ctxWrap.invokingState >= 0 && following.contains(CommonToken.EPSILON) {
+ let invokingState = states[ctxWrap.invokingState]!
+ let rt = invokingState.transition(0) as! RuleTransition
+ following = nextTokens(rt.followState)
+ try! expected.addAll(following)
+ try! expected.remove(CommonToken.EPSILON)
ctx = ctxWrap.parent
}
if following.contains(CommonToken.EPSILON) {
- try expected.add(CommonToken.EOF)
+ try! expected.add(CommonToken.EOF)
}
return expected
diff --git a/runtime/Swift/Sources/Antlr4/atn/ATNConfig.swift b/runtime/Swift/Sources/Antlr4/atn/ATNConfig.swift
index 75bff30e4..f91854531 100644
--- a/runtime/Swift/Sources/Antlr4/atn/ATNConfig.swift
+++ b/runtime/Swift/Sources/Antlr4/atn/ATNConfig.swift
@@ -150,13 +150,12 @@ public class ATNConfig: Hashable, CustomStringConvertible {
///
public var hashValue: Int {
- var hashCode: Int = MurmurHash.initialize(7)
+ var hashCode = MurmurHash.initialize(7)
hashCode = MurmurHash.update(hashCode, state.stateNumber)
hashCode = MurmurHash.update(hashCode, alt)
hashCode = MurmurHash.update(hashCode, context)
hashCode = MurmurHash.update(hashCode, semanticContext)
- hashCode = MurmurHash.finish(hashCode, 4)
- return hashCode
+ return MurmurHash.finish(hashCode, 4)
}
diff --git a/runtime/Swift/Sources/Antlr4/atn/ATNConfigSet.swift b/runtime/Swift/Sources/Antlr4/atn/ATNConfigSet.swift
index 803d9c369..3c52bcd14 100644
--- a/runtime/Swift/Sources/Antlr4/atn/ATNConfigSet.swift
+++ b/runtime/Swift/Sources/Antlr4/atn/ATNConfigSet.swift
@@ -27,7 +27,7 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
/// fields; in particular, conflictingAlts is set after
/// we've made this readonly.
///
- internal final var readonly: Bool = false
+ internal final var readonly = false
///
/// All configs but hashed by (s, i, _, pi) not including context. Wiped out
@@ -38,11 +38,11 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
///
/// Track the elements as they are added to the set; supports get(i)
///
- public final var configs: Array = Array()
+ public final 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 final var uniqueAlt: Int = 0
+ public final var uniqueAlt = 0
//TODO no default
///
/// Currently this is only used when we detect SLL conflict; this does
@@ -54,9 +54,9 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
// 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 final var hasSemanticContext: Bool = false
+ public final var hasSemanticContext = false
//TODO no default
- public final var dipsIntoOuterContext: Bool = false
+ public final var dipsIntoOuterContext = false
//TODO no default
///
@@ -66,7 +66,7 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
///
public final var fullCtx: Bool
- private var cachedHashCode: Int = -1
+ private var cachedHashCode = -1
public init(_ fullCtx: Bool) {
configLookup = LookupDictionary()
@@ -76,9 +76,9 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
self.init(true)
}
- public convenience init(_ old: ATNConfigSet) throws {
+ public convenience init(_ old: ATNConfigSet) {
self.init(old.fullCtx)
- try addAll(old)
+ try! addAll(old)
self.uniqueAlt = old.uniqueAlt
self.conflictingAlts = old.conflictingAlts
self.hasSemanticContext = old.hasSemanticContext
@@ -108,7 +108,6 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
_ mergeCache: inout DoubleKeyMap?) throws -> Bool {
if readonly {
throw ANTLRError.illegalState(msg: "This set is readonly")
-
}
if config.semanticContext != SemanticContext.NONE {
@@ -125,10 +124,9 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
return true
}
// a previous (s,i,pi,_), merge with it and save result
- let rootIsWildcard: Bool = !fullCtx
+ let rootIsWildcard = !fullCtx
- let merged: PredictionContext =
- PredictionContext.merge(existing.context!, config.context!, rootIsWildcard, &mergeCache)
+ 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
@@ -154,16 +152,14 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
///
/// Return a List holding list of configs
///
- public final func elements() -> Array {
+ public final func elements() -> [ATNConfig] {
return configs
}
public final func getStates() -> Set {
-
- let length = configs.count
- var states: Set = Set(minimumCapacity: length)
- for i in 0..(minimumCapacity: configs.count)
+ for config in configs {
+ states.insert(config.state)
}
return states
}
@@ -176,21 +172,19 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
///
/// - since: 4.3
///
- public final func getAlts() throws -> BitSet {
- let alts: BitSet = BitSet()
- let length = configs.count
- for i in 0.. BitSet {
+ let alts = BitSet()
+ for config in configs {
+ try! alts.set(config.alt)
}
return alts
}
- public final func getPredicates() -> Array {
- var preds: Array = Array()
- let length = configs.count
- for i in 0.. [SemanticContext] {
+ var preds = [SemanticContext]()
+ for config in configs {
+ if config.semanticContext != SemanticContext.NONE {
+ preds.append(config.semanticContext)
}
}
return preds
@@ -203,22 +197,20 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
public final func optimizeConfigs(_ interpreter: ATNSimulator) throws {
if readonly {
throw ANTLRError.illegalState(msg: "This set is readonly")
-
}
if configLookup.isEmpty {
return
}
- let length = configs.count
- for i in 0.. Bool {
- for c: ATNConfig in coll.configs {
- try add(c)
+ for c in coll.configs {
+ try add(c)
}
return false
}
@@ -266,7 +258,6 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
public final func clear() throws {
if readonly {
throw ANTLRError.illegalState(msg: "This set is readonly")
-
}
configs.removeAll()
cachedHashCode = -1
@@ -284,7 +275,7 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
}
public var description: String {
- let buf: StringBuilder = StringBuilder()
+ let buf = StringBuilder()
buf.append(elements().map({ $0.description }))
if hasSemanticContext {
buf.append(",hasSemanticContext=")
@@ -313,18 +304,15 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
/// return configLookup.toArray(a);
///
private final func configHash(_ stateNumber: Int,_ context: PredictionContext?) -> Int{
-
- var hashCode: Int = MurmurHash.initialize(7)
+ var hashCode = MurmurHash.initialize(7)
hashCode = MurmurHash.update(hashCode, stateNumber)
hashCode = MurmurHash.update(hashCode, context)
- hashCode = MurmurHash.finish(hashCode, 2)
-
- return hashCode
-
+ return MurmurHash.finish(hashCode, 2)
}
- public final func getConflictingAltSubsets() throws -> Array {
+
+ public final func getConflictingAltSubsets() -> [BitSet] {
let length = configs.count
- let configToAlts: HashMap = HashMap(count: length)
+ let configToAlts = HashMap(count: length)
for i in 0.. HashMap {
+
+ public final func getStateToAltMap() -> HashMap {
let length = configs.count
- let m: HashMap = HashMap(count: length) //minimumCapacity: length)
+ let m = HashMap(count: length)
for i in 0.. Set? {
- var alts: Set = Set()
- let length = configs.count
- for i in 0..()
+ for config in configs {
+ alts.insert(config.alt)
+ }
return alts
}
//for DiagnosticErrorListener
- public final func getAltBitSet() throws -> BitSet {
- let result: BitSet = BitSet()
- let length = configs.count
- for i in 0.. BitSet {
+ let result = BitSet()
+ for config in configs {
+ try! result.set(config.alt)
}
-
return result
}
//LexerATNSimulator
- public final var firstConfigWithRuleStopState: ATNConfig? {
- let length = configs.count
- for i in 0.. Int {
- var alt: Int = ATN.INVALID_ALT_NUMBER
- let length = configs.count
- for i in 0.. Int {
+ var alt = ATN.INVALID_ALT_NUMBER
+ for config in configs {
if alt == ATN.INVALID_ALT_NUMBER {
- alt = configs[i].alt // found first alt
- } else {
- if configs[i].alt != alt {
- return ATN.INVALID_ALT_NUMBER
- }
+ alt = config.alt // found first alt
+ } else if config.alt != alt {
+ return ATN.INVALID_ALT_NUMBER
}
}
return alt
}
- public final func removeAllConfigsNotInRuleStopState(_ mergeCache: inout DoubleKeyMap?,_ lookToEndOfRule: Bool,_ atn: ATN) throws -> ATNConfigSet {
+
+ public final func removeAllConfigsNotInRuleStopState(_ mergeCache: inout DoubleKeyMap?,_ lookToEndOfRule: Bool,_ atn: ATN) -> ATNConfigSet {
if PredictionMode.allConfigsInRuleStopStates(self) {
return self
}
- let result: ATNConfigSet = ATNConfigSet(fullCtx)
- let length = configs.count
- for i in 0..?,_ parser: Parser,_ _outerContext: ParserRuleContext!) throws -> ATNConfigSet {
- let configSet: ATNConfigSet = ATNConfigSet(fullCtx)
- let length = configs.count
- let statesFromAlt1: HashMap