Merge pull request #2107 from ewanmellor/swift-fix-deprecated-string-methods

Remove use of deprecated String functions
This commit is contained in:
Terence Parr 2017-11-29 09:52:27 -08:00 committed by GitHub
commit 84e9a46932
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 450 additions and 596 deletions

View File

@ -6,7 +6,7 @@ set -euo pipefail
# here since environment variables doesn't pass
# across scripts
if [ $TRAVIS_OS_NAME == "linux" ]; then
export SWIFT_VERSION=swift-4.0
export SWIFT_VERSION=swift-4.0.2
export SWIFT_HOME=$(pwd)/swift/$SWIFT_VERSION-RELEASE-ubuntu14.04/usr/bin/
export PATH=$SWIFT_HOME:$PATH

View File

@ -42,8 +42,8 @@ public class ANTLRInputStream: CharStream {
/// Copy data in string to a local char array
///
public init(_ input: String) {
self.data = Array(input.characters) // input.toCharArray();
self.n = input.length
self.data = Array(input)
self.n = data.count
}
///

View File

@ -441,14 +441,13 @@ public class BufferedTokenStream: TokenStream {
/// Collect all hidden tokens (any off-default channel) to the left of
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
///
public func getHiddenTokensToLeft(_ tokenIndex: Int) throws -> Array<Token>? {
public func getHiddenTokensToLeft(_ tokenIndex: Int) throws -> [Token]? {
return try getHiddenTokensToLeft(tokenIndex, -1)
}
internal func filterForChannel(_ from: Int, _ to: Int, _ channel: Int) -> Array<Token>? {
var hidden: Array<Token> = Array<Token>()
for i in from...to {
let t: Token = tokens[i]
internal func filterForChannel(_ from: Int, _ to: Int, _ channel: Int) -> [Token]? {
var hidden = [Token]()
for t in tokens[from...to] {
if channel == -1 {
if t.getChannel() != Lexer.DEFAULT_TOKEN_CHANNEL {
hidden.append(t)
@ -478,8 +477,8 @@ public class BufferedTokenStream: TokenStream {
}
public func getText(_ interval: Interval) throws -> String {
let start: Int = interval.a
var stop: Int = interval.b
let start = interval.a
var stop = interval.b
if start < 0 || stop < 0 {
return ""
}
@ -488,15 +487,14 @@ public class BufferedTokenStream: TokenStream {
stop = tokens.count - 1
}
let buf: StringBuilder = StringBuilder()
for i in start...stop {
let t: Token = tokens[i]
var buf = ""
for t in tokens[start...stop] {
if t.getType() == BufferedTokenStream.EOF {
break
}
buf.append(t.getText()!)
buf += t.getText()!
}
return buf.toString()
return buf
}
@ -518,9 +516,9 @@ public class BufferedTokenStream: TokenStream {
///
public func fill() throws {
try lazyInit()
let blockSize: Int = 1000
let blockSize = 1000
while true {
let fetched: Int = try fetch(blockSize)
let fetched = try fetch(blockSize)
if fetched < blockSize {
return
}

View File

@ -413,29 +413,27 @@ open class Lexer: Recognizer<LexerATNSimulator>, TokenSource {
}
open func getErrorDisplay(_ s: String) -> String {
let buf = StringBuilder()
for c in s.characters {
buf.append(getErrorDisplay(c))
var buf = ""
for c in s {
buf += getErrorDisplay(c)
}
return buf.toString()
return buf
}
open func getErrorDisplay(_ c: Character) -> String {
var s = String(c)
if c.integerValue == CommonToken.EOF {
s = "<EOF>"
return "<EOF>"
}
switch s {
switch c {
case "\n":
s = "\\n"
return "\\n"
case "\t":
s = "\\t"
return "\\t"
case "\r":
s = "\\r"
return "\\r"
default:
break
return String(c)
}
return s
}
open func getCharErrorDisplay(_ c: Character) -> String {

View File

@ -85,9 +85,8 @@ public class ListTokenSource: TokenSource {
let lastToken = tokens[tokens.count - 1]
if let tokenText = lastToken.getText() {
let lastNewLine = tokenText.lastIndexOf("\n")
if lastNewLine >= 0 {
return tokenText.length - lastNewLine - 1
if let lastNewLine = tokenText.lastIndex(of: "\n") {
return tokenText.distance(from: lastNewLine, to: tokenText.endIndex) - 1
}
}
return (lastToken.getCharPositionInLine() +
@ -142,9 +141,8 @@ public class ListTokenSource: TokenSource {
var line = lastToken.getLine()
if let tokenText = lastToken.getText() {
let length = tokenText.length
for j in 0..<length {
if String(tokenText[j]) == "\n" {
for c in tokenText {
if c == "\n" {
line += 1
}
}

View File

@ -429,7 +429,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
if result == nil {
let deserializationOptions = ATNDeserializationOptions()
try! deserializationOptions.setGenerateRuleBypassTransitions(true)
result = try! ATNDeserializer(deserializationOptions).deserialize(Array(serializedAtn.characters))
result = try! ATNDeserializer(deserializationOptions).deserialize(Array(serializedAtn))
self.bypassAltsAtnCache[serializedAtn] = result!
}
}

View File

@ -132,12 +132,12 @@ open class RuleContext: RuleNode {
return ""
}
let builder = StringBuilder()
var builder = ""
for i in 0..<length {
builder.append((getChild(i) as! ParseTree).getText())
builder += (getChild(i) as! ParseTree).getText()
}
return builder.toString()
return builder
}
open func getRuleIndex() -> Int {
@ -202,31 +202,31 @@ open class RuleContext: RuleNode {
}
open func toString(_ ruleNames: [String]?, _ stop: RuleContext?) -> String {
let buf = StringBuilder()
var buf = ""
var p: RuleContext? = self
buf.append("[")
buf += "["
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)
buf += ruleName
}
else {
if !pWrap.isEmpty() {
buf.append(pWrap.invokingState)
buf += String(pWrap.invokingState)
}
}
if pWrap.parent != nil && (ruleNames != nil || !pWrap.parent!.isEmpty()) {
buf.append(" ")
buf += " "
}
p = pWrap.parent
}
buf.append("]")
return buf.toString()
buf += "]"
return buf
}
open func castdown<T>(_ subType: T.Type) -> T {

View File

@ -163,18 +163,14 @@ public class RuntimeMetaData {
/// only the major and minor components of the version string.
///
public static func getMajorMinorVersion(_ version: String) -> String {
let firstDot: Int = version.indexOf(".")
let secondDot: Int = firstDot >= 0 ? version.indexOf(".", startIndex: firstDot + 1) : -1
let firstDash: Int = version.indexOf("-")
var referenceLength: Int = version.length
if secondDot >= 0 {
referenceLength = min(referenceLength, secondDot)
var result = version
let dotBits = version.split(separator: ".", maxSplits: 2, omittingEmptySubsequences: false)
if dotBits.count >= 2 {
result = dotBits[0..<2].joined(separator: ".")
}
if firstDash >= 0 {
referenceLength = min(referenceLength, firstDash)
}
return version[0 ..< referenceLength] // version.substring(0, referenceLength);
let dashBits = result.split(separator: "-", maxSplits: 1, omittingEmptySubsequences: false)
return String(dashBits[0])
}
}

View File

@ -84,19 +84,19 @@
import Foundation
public class TokenStreamRewriter {
public let DEFAULT_PROGRAM_NAME: String = "default"
public static let PROGRAM_INIT_SIZE: Int = 100
public static let MIN_TOKEN_INDEX: Int = 0
public let DEFAULT_PROGRAM_NAME = "default"
public static let PROGRAM_INIT_SIZE = 100
public static let MIN_TOKEN_INDEX = 0
// Define the rewrite operation hierarchy
public class RewriteOperation: CustomStringConvertible {
/// What index into rewrites List are we?
internal var instructionIndex: Int = 0
internal var instructionIndex = 0
/// Token buffer index.
internal var index: Int
internal var text: String?
internal var lastIndex: Int = 0
internal weak var tokens: TokenStream!
internal var lastIndex = 0
internal weak var tokens: TokenStream!
init(_ index: Int, _ tokens: TokenStream) {
self.index = index
@ -112,7 +112,7 @@ public class TokenStreamRewriter {
/// Execute the rewrite operation by possibly adding to the buffer.
/// Return the index of the next token to operate on.
///
public func execute(_ buf: StringBuilder) throws -> Int {
public func execute(_ buf: inout String) throws -> Int {
return index
}
@ -123,16 +123,13 @@ public class TokenStreamRewriter {
}
public class InsertBeforeOp: RewriteOperation {
public override init(_ index: Int, _ text: String?, _ tokens: TokenStream) {
super.init(index, text, tokens)
}
override public func execute(_ buf: StringBuilder) throws -> Int {
if text != nil {
buf.append(text!)
override public func execute(_ buf: inout String) throws -> Int {
if let text = text {
buf.append(text)
}
if try tokens.get(index).getType() != CommonToken.EOF {
buf.append(try tokens.get(index).getText()!)
let token = try tokens.get(index)
if token.getType() != CommonToken.EOF {
buf.append(token.getText()!)
}
return index + 1
}
@ -146,7 +143,7 @@ public class TokenStreamRewriter {
/// I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp
/// instructions.
///
///
public class ReplaceOp: RewriteOperation {
@ -156,27 +153,32 @@ public class TokenStreamRewriter {
}
override
public func execute(_ buf: StringBuilder) -> Int {
if text != nil {
buf.append(text!)
public func execute(_ buf: inout String) -> Int {
if let text = text {
buf += text
}
return lastIndex + 1
}
override
public var description: String {
if text == nil {
return "<DeleteOp@\(try! tokens.get(index))..\(try! tokens.get(lastIndex))>"
let token = try! tokens.get(index)
let lastToken = try! tokens.get(lastIndex)
if let text = text {
return "<ReplaceOp@\(token)..\(lastToken):\"\(text)\">"
}
return "<ReplaceOp@\(try! tokens.get(index))..\(try! tokens.get(lastIndex)):\"\(text!)\">"
return "<DeleteOp@\(token)..\(lastToken)>"
}
}
public class RewriteOperationArray{
private final var rewrites: Array<RewriteOperation?> = Array<RewriteOperation?>()
public init(){
private final var rewrites = [RewriteOperation?]()
public init() {
rewrites.reserveCapacity(TokenStreamRewriter.PROGRAM_INIT_SIZE)
}
final func append(_ op: RewriteOperation){
final func append(_ op: RewriteOperation) {
op.instructionIndex = rewrites.count
rewrites.append(op)
}
@ -184,12 +186,15 @@ public class TokenStreamRewriter {
final func rollback(_ instructionIndex: Int) {
rewrites = Array(rewrites[TokenStreamRewriter.MIN_TOKEN_INDEX ..< instructionIndex])
}
final var count: Int{
final var count: Int {
return rewrites.count
}
final var isEmpty: Bool{
final var isEmpty: Bool {
return rewrites.isEmpty
}
/// We need to combine operations and report invalid operations (like
/// overlapping replaces that are not completed nested). Inserts to
/// same index need to be combined etc... Here are the cases:
@ -239,37 +244,34 @@ public class TokenStreamRewriter {
///
/// Return a map from token index to operation.
///
final func reduceToSingleOperationPerIndex() throws -> Dictionary<Int, RewriteOperation> {
final func reduceToSingleOperationPerIndex() throws -> [Int: RewriteOperation] {
let rewritesCount = rewrites.count
// WALK REPLACES
for i in 0..<rewritesCount {
guard let rop = rewrites[i] else {
continue
}
if !(rop is ReplaceOp) {
guard let rop = rewrites[i] as? ReplaceOp else {
continue
}
// Wipe prior inserts within range
let inserts = getKindOfOps(&rewrites, InsertBeforeOp.self, i)
for j in inserts {
let inserts = getKindOfOps(&rewrites, InsertBeforeOp.self, i)
for j in inserts {
if let iop = rewrites[j] {
if iop.index == rop.index {
// E.g., insert before 2, delete 2..2; update replace
// text to include insert before, kill insert
rewrites[iop.instructionIndex] = nil
rop.text = catOpText(iop.text, rop.text)
} else if iop.index > rop.index && iop.index <= rop.lastIndex {
}
else if iop.index > rop.index && iop.index <= rop.lastIndex {
// delete insert as it's a no-op.
rewrites[iop.instructionIndex] = nil
}
}
}
// Drop any prior replaces contained within
let prevRopIndexList = getKindOfOps(&rewrites, ReplaceOp.self, i)
for j in prevRopIndexList {
let prevRopIndexList = getKindOfOps(&rewrites, ReplaceOp.self, i)
for j in prevRopIndexList {
if let prevRop = rewrites[j] {
if prevRop.index >= rop.index && prevRop.lastIndex <= rop.lastIndex {
// delete replace as it's a no-op.
@ -285,7 +287,6 @@ public class TokenStreamRewriter {
rewrites[prevRop.instructionIndex] = nil // kill first delete
rop.index = min(prevRop.index, rop.index)
rop.lastIndex = max(prevRop.lastIndex, rop.lastIndex)
print("new rop \(rop)")
} else if !disjoint {
throw ANTLRError.illegalArgument(msg: "replace op boundaries of \(rop.description) " +
"overlap with previous \(prevRop.description)")
@ -341,9 +342,9 @@ public class TokenStreamRewriter {
}
}
var m: Dictionary<Int, RewriteOperation> = Dictionary<Int, RewriteOperation>()
var m = [Int: RewriteOperation]()
for i in 0..<rewritesCount {
if let op: RewriteOperation = rewrites[i] {
if let op = rewrites[i] {
if m[op.index] != nil {
throw ANTLRError.illegalArgument(msg: "should only be one op per index")
}
@ -355,17 +356,16 @@ public class TokenStreamRewriter {
}
final func catOpText(_ a: String?, _ b: String?) -> String {
let x: String = a ?? ""
let y: String = b ?? ""
let x = a ?? ""
let y = b ?? ""
return x + y
}
/// Get all operations before an index of a particular kind
final func getKindOfOps<T: RewriteOperation>(_ rewrites: inout [RewriteOperation?], _ kind: T.Type, _ before: Int ) -> [Int] {
final func getKindOfOps<T: RewriteOperation>(_ rewrites: inout [RewriteOperation?], _ kind: T.Type, _ before: Int ) -> [Int] {
let length = min(before,rewrites.count)
let length = min(before, rewrites.count)
var op = [Int]()
op.reserveCapacity(length)
for i in 0..<length {
@ -375,7 +375,6 @@ public class TokenStreamRewriter {
}
return op
}
}
/// Our source stream
@ -385,14 +384,13 @@ public class TokenStreamRewriter {
/// I'm calling these things "programs."
/// Maps String (name) &rarr; rewrite (List)
///
internal var programs: Dictionary<String, RewriteOperationArray> //Array<RewriteOperation>
internal var programs = [String: RewriteOperationArray]()
/// Map String (program name) &rarr; Integer index
internal final var lastRewriteTokenIndexes: Dictionary<String, Int>
internal final var lastRewriteTokenIndexes: [String: Int]
public init(_ tokens: TokenStream) {
self.tokens = tokens
programs = Dictionary<String, RewriteOperationArray>()
programs[DEFAULT_PROGRAM_NAME] = RewriteOperationArray()
lastRewriteTokenIndexes = Dictionary<String, Int>()
}
@ -439,7 +437,7 @@ public class TokenStreamRewriter {
public func insertAfter(_ programName: String, _ index: Int, _ text: String) {
// to insert after, just insert before next index (even if past end)
let op = InsertAfterOp(index, text, tokens)
let rewrites = getProgram(programName)
let rewrites = getProgram(programName)
rewrites.append(op)
}
@ -456,8 +454,8 @@ public class TokenStreamRewriter {
}
public func insertBefore(_ programName: String, _ index: Int, _ text: String) {
let op: RewriteOperation = InsertBeforeOp(index, text, tokens)
let rewrites: RewriteOperationArray = getProgram(programName)
let op = InsertBeforeOp(index, text, tokens)
let rewrites = getProgram(programName)
rewrites.append(op)
}
@ -481,10 +479,9 @@ public class TokenStreamRewriter {
if from > to || from < 0 || to < 0 || to >= tokens.size() {
throw ANTLRError.illegalArgument(msg: "replace: range invalid: \(from)..\(to)(size=\(tokens.size()))")
}
let op: RewriteOperation = ReplaceOp(from, to, text, tokens)
let rewritesArray: RewriteOperationArray = getProgram(programName)
let op = ReplaceOp(from, to, text, tokens)
let rewritesArray = getProgram(programName)
rewritesArray.append(op)
}
public func replace(_ programName: String, _ from: Token, _ to: Token, _ text: String?) throws {
@ -523,30 +520,24 @@ public class TokenStreamRewriter {
}
internal func getLastRewriteTokenIndex(_ programName: String) -> Int {
let I: Int? = lastRewriteTokenIndexes[programName]
if I == nil {
return -1
}
return I!
return lastRewriteTokenIndexes[programName] ?? -1
}
internal func setLastRewriteTokenIndex(_ programName: String, _ i: Int) {
lastRewriteTokenIndexes[programName] = i
}
internal func getProgram(_ name: String) -> RewriteOperationArray
{
var program: RewriteOperationArray? = programs[name]
if program == nil {
program = initializeProgram(name)
internal func getProgram(_ name: String) -> RewriteOperationArray {
if let program = programs[name] {
return program
}
else {
return initializeProgram(name)
}
return program!
}
private func initializeProgram(_ name: String) -> RewriteOperationArray
{
let program: RewriteOperationArray = RewriteOperationArray()
private func initializeProgram(_ name: String) -> RewriteOperationArray {
let program = RewriteOperationArray()
programs[name] = program
return program
}
@ -579,8 +570,8 @@ public class TokenStreamRewriter {
}
public func getText(_ programName: String, _ interval: Interval) throws -> String {
var start: Int = interval.a
var stop: Int = interval.b
var start = interval.a
var stop = interval.b
// ensure start/end are in range
if stop > tokens.size() - 1 {
@ -589,32 +580,31 @@ public class TokenStreamRewriter {
if start < 0 {
start = 0
}
guard let rewrites = programs[programName] , !rewrites.isEmpty else {
guard let rewrites = programs[programName], !rewrites.isEmpty else {
return try tokens.getText(interval) // no instructions to execute
}
let buf: StringBuilder = StringBuilder()
var buf = ""
// First, optimize instruction stream
var indexToOp: Dictionary<Int, RewriteOperation> = try rewrites.reduceToSingleOperationPerIndex()
var indexToOp = try rewrites.reduceToSingleOperationPerIndex()
// Walk buffer, executing instructions and emitting tokens
var i: Int = start
var i = start
while i <= stop && i < tokens.size() {
let op: RewriteOperation? = indexToOp[i]
indexToOp.removeValue(forKey: i)
//indexToOp.remove(i); // remove so any left have index size-1
let t: Token = try tokens.get(i)
if op == nil {
let op = indexToOp[i]
indexToOp.removeValue(forKey: i) // remove so any left have index size-1
let t = try tokens.get(i)
if let op = op {
i = try op.execute(&buf) // execute operation and skip
}
else {
// no operation at that index, just dump token
if t.getType() != CommonToken.EOF {
buf.append(t.getText()!)
}
i += 1 // move to next token
} else {
i = try op!.execute(buf) // execute operation and skip
}
}
// include stuff after end if it's last index in buffer
@ -623,14 +613,13 @@ public class TokenStreamRewriter {
if stop == tokens.size() - 1 {
// Scan any remaining operations after last token
// should be included (they will be inserts).
for op: RewriteOperation in indexToOp.values {
for op in indexToOp.values {
if op.index >= tokens.size() - 1 {
buf.append(op.text!)
buf += op.text!
}
}
}
return buf.toString()
return buf
}
}

View File

@ -284,27 +284,23 @@ public class UnbufferedTokenStream: TokenStream {
public func getText(_ interval: Interval) throws -> String {
let bufferStartIndex: Int = getBufferStartIndex()
let bufferStopIndex: Int = bufferStartIndex + tokens.count - 1
let bufferStartIndex = getBufferStartIndex()
let bufferStopIndex = bufferStartIndex + tokens.count - 1
let start: Int = interval.a
let stop: Int = interval.b
let start = interval.a
let stop = interval.b
if start < bufferStartIndex || stop > bufferStopIndex {
throw ANTLRError.unsupportedOperation(msg: "interval \(interval) not in token buffer window: \(bufferStartIndex)..bufferStopIndex)")
}
let a: Int = start - bufferStartIndex
let b: Int = stop - bufferStartIndex
let a = start - bufferStartIndex
let b = stop - bufferStartIndex
let buf: StringBuilder = StringBuilder()
for i in a...b {
let t: Token = tokens[i]
buf.append(t.getText()!)
var buf = ""
for t in tokens[a...b] {
buf += t.getText()!
}
return buf.toString()
return buf
}
internal final func getBufferStartIndex() -> Int {

View File

@ -85,27 +85,25 @@ public class Vocabulary: Hashable {
/// the display names of tokens.
///
public static func fromTokenNames(_ tokenNames: [String?]?) -> Vocabulary {
guard let tokenNames = tokenNames , tokenNames.count > 0 else {
guard let tokenNames = tokenNames, tokenNames.count > 0 else {
return EMPTY_VOCABULARY
}
var literalNames: [String?] = tokenNames// Arrays.copyOf(tokenNames, tokenNames.length);
var symbolicNames: [String?] = tokenNames
var literalNames = tokenNames
var symbolicNames = tokenNames
let length = tokenNames.count
for i in 0..<length {
guard let tokenName = tokenNames[i] else {
continue
}
if !tokenName.isEmpty {
let firstChar: Character = tokenName[0]
if let firstChar = tokenName.first {
if firstChar == "\'" {
symbolicNames[i] = nil
continue
} else {
if String(firstChar).uppercased() != String(firstChar) {
literalNames[i] = nil
continue
}
}
else if String(firstChar).uppercased() != String(firstChar) {
literalNames[i] = nil
continue
}
}
@ -141,20 +139,17 @@ public class Vocabulary: Hashable {
public func getDisplayName(_ tokenType: Int) -> String {
if tokenType >= 0 && tokenType < displayNames.count {
let displayName: String? = displayNames[tokenType]
if displayName != nil {
return displayName!
if let displayName = displayNames[tokenType] {
return displayName
}
}
let literalName: String? = getLiteralName(tokenType)
if literalName != nil {
return literalName!
if let literalName = getLiteralName(tokenType) {
return literalName
}
let symbolicName: String? = getSymbolicName(tokenType)
if symbolicName != nil {
return symbolicName!
if let symbolicName = getSymbolicName(tokenType) {
return symbolicName
}
return String(tokenType)

View File

@ -159,37 +159,27 @@ public class ATNConfig: Hashable, CustomStringConvertible {
}
public func toString() -> String {
return description
}
public var description: String {
//return "MyClass \(string)"
return toString(nil, true)
}
public func toString<T>(_ recog: Recognizer<T>?, _ showAlt: Bool) -> String {
let buf: StringBuilder = StringBuilder()
buf.append("(")
buf.append(state)
var buf = "(\(state)"
if showAlt {
buf.append(",")
buf.append(alt)
buf += ",\(alt)"
}
if context != nil {
buf.append(",[")
buf.append(context!)
buf.append("]")
if let context = context {
buf += ",[\(context)]"
}
if semanticContext != SemanticContext.NONE {
buf.append(",")
buf.append(semanticContext)
buf += ",\(semanticContext)"
}
if getOuterContextDepth() > 0 {
buf.append(",up=").append(getOuterContextDepth())
let outerDepth = getOuterContextDepth()
if outerDepth > 0 {
buf += ",up=\(outerDepth)"
}
buf.append(")")
return buf.toString()
buf += ")"
return buf
}
}

View File

@ -275,27 +275,21 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
}
public var description: String {
let buf = StringBuilder()
buf.append(elements().map({ $0.description }))
var buf = ""
buf += String(describing: elements())
if hasSemanticContext {
buf.append(",hasSemanticContext=")
buf.append(hasSemanticContext)
buf += ",hasSemanticContext=true"
}
if uniqueAlt != ATN.INVALID_ALT_NUMBER {
buf.append(",uniqueAlt=")
buf.append(uniqueAlt)
buf += ",uniqueAlt=\(uniqueAlt)"
}
if let conflictingAlts = conflictingAlts {
buf.append(",conflictingAlts=")
buf.append(conflictingAlts.description)
buf += ",conflictingAlts=\(conflictingAlts)"
}
if dipsIntoOuterContext {
buf.append(",dipsIntoOuterContext")
buf += ",dipsIntoOuterContext"
}
return buf.toString()
}
public func toString() -> String {
return description
return buf
}
///

View File

@ -136,9 +136,6 @@ public class ATNState: Hashable, CustomStringConvertible {
}
public func toString() -> String {
return description
}
public var description: String {
//return "MyClass \(string)"
return String(stateNumber)

View File

@ -58,28 +58,25 @@ public class ArrayPredictionContext: PredictionContext {
if isEmpty() {
return "[]"
}
let buf: StringBuilder = StringBuilder()
buf.append("[")
let length = returnStates.count
for i in 0..<length {
var buf = "["
for (i, returnState) in returnStates.enumerated() {
if i > 0 {
buf.append(", ")
buf += ", "
}
if returnStates[i] == PredictionContext.EMPTY_RETURN_STATE {
buf.append("$")
if returnState == PredictionContext.EMPTY_RETURN_STATE {
buf += "$"
continue
}
buf.append(returnStates[i])
if parents[i] != nil {
buf.append(" ")
buf.append(parents[i].debugDescription)
} else {
buf.append("null")
buf += "\(returnState)"
if let parent = parents[i] {
buf += " \(parent)"
}
else {
buf += "null"
}
}
buf.append("]")
return buf.toString()
buf += "]"
return buf
}
internal final func combineCommonParents() {

View File

@ -225,21 +225,22 @@ public class DecisionInfo: CustomStringConvertible {
public var description: String {
let desc: StringBuilder = StringBuilder()
desc.append("{")
desc.append("decision=\(decision)")
desc.append(", contextSensitivities=\(contextSensitivities.count)")
desc.append(", errors=\(errors.count)")
desc.append(", ambiguities=\(ambiguities.count)")
desc.append(", SLL_lookahead=\(SLL_TotalLook)")
desc.append(", SLL_ATNTransitions=\(SLL_ATNTransitions)")
desc.append(", SLL_DFATransitions=\(SLL_DFATransitions)")
desc.append(", LL_Fallback=\(LL_Fallback)")
desc.append(", LL_lookahead=\(LL_TotalLook)")
desc.append(", LL_ATNTransitions=\(LL_ATNTransitions)")
desc.append("}")
var desc = ""
return desc.toString()
desc += "{"
desc += "decision=\(decision)"
desc += ", contextSensitivities=\(contextSensitivities.count)"
desc += ", errors=\(errors.count)"
desc += ", ambiguities=\(ambiguities.count)"
desc += ", SLL_lookahead=\(SLL_TotalLook)"
desc += ", SLL_ATNTransitions=\(SLL_ATNTransitions)"
desc += ", SLL_DFATransitions=\(SLL_DFATransitions)"
desc += ", LL_Fallback=\(LL_Fallback)"
desc += ", LL_lookahead=\(LL_TotalLook)"
desc += ", LL_ATNTransitions=\(LL_ATNTransitions)"
desc += "}"
return desc
}
}

View File

@ -1907,7 +1907,7 @@ open class ParserATNSimulator: ATNSimulator {
}
else if let st = t as? SetTransition {
let not = st is NotSetTransition
trans = (not ? "~" : "") + "Set " + st.set.toString()
trans = (not ? "~" : "") + "Set " + st.set.description
}
}
errPrint("\(c.toString(parser, true)):\(trans)")

View File

@ -42,9 +42,4 @@ public final class PrecedencePredicateTransition: AbstractPredicateTransition, C
public var description: String {
return "\(precedence) >= _p"
}
public func toString() -> String {
return description
}
}

View File

@ -14,7 +14,7 @@
/// multiple ATN configurations into a single DFA state.
///
public final class PredicateTransition: AbstractPredicateTransition {
public final class PredicateTransition: AbstractPredicateTransition, CustomStringConvertible {
public let ruleIndex: Int
public let predIndex: Int
public let isCtxDependent: Bool
@ -47,9 +47,7 @@ public final class PredicateTransition: AbstractPredicateTransition {
return SemanticContext.Predicate(ruleIndex, predIndex, isCtxDependent)
}
public func toString() -> String {
public var description: String {
return "pred_\(ruleIndex):\(predIndex)"
}
}

View File

@ -518,47 +518,40 @@ public class PredictionContext: Hashable, CustomStringConvertible {
if context == nil {
return ""
}
let buf = StringBuilder()
buf.append("digraph G {\n")
buf.append("rankdir=LR;\n")
var buf = ""
buf += "digraph G {\n"
buf += "rankdir=LR;\n"
var nodes = getAllContextNodes(context!)
nodes.sort { $0.id > $1.id }
for current in nodes {
if current is SingletonPredictionContext {
let s = String(current.id)
buf.append(" s").append(s)
buf += " s\(current.id)"
var returnState = String(current.getReturnState(0))
if current is EmptyPredictionContext {
returnState = "$"
}
buf.append(" [label=\"")
buf.append(returnState)
buf.append("\"];\n")
buf += " [label=\"\(returnState)\"];\n"
continue
}
let arr = current as! ArrayPredictionContext
buf.append(" s").append(arr.id)
buf.append(" [shape=box, label=\"")
buf.append("[")
buf += " s\(arr.id) [shape=box, label=\"["
var first = true
let returnStates = arr.returnStates
for inv in returnStates {
if !first {
buf.append(", ")
buf += ", "
}
if inv == EMPTY_RETURN_STATE {
buf.append("$")
buf += "$"
} else {
buf.append(inv)
buf += String(inv)
}
first = false
}
buf.append("]")
buf.append("\"];\n")
buf += "]\"];\n"
}
for current in nodes {
@ -570,21 +563,17 @@ public class PredictionContext: Hashable, CustomStringConvertible {
guard let currentParent = current.getParent(i) else {
continue
}
let s = String(current.id)
buf.append(" s").append(s)
buf.append("->")
buf.append("s")
buf.append(currentParent.id)
buf += " s\(current.id) -> s\(currentParent.id)"
if current.size() > 1 {
buf.append(" [label=\"parent[\(i)]\"];\n")
buf += " [label=\"parent[\(i)]\"];\n"
} else {
buf.append(";\n")
buf += ";\n"
}
}
}
buf.append("}\n")
return buf.toString()
return buf
}
// From Sam
@ -700,8 +689,7 @@ public class PredictionContext: Hashable, CustomStringConvertible {
var last = true
var p = self
var stateNumber = currentState
let localBuffer = StringBuilder()
localBuffer.append("[")
var localBuffer = "["
while !p.isEmpty() && p !== stop {
var index = 0
if p.size() > 0 {
@ -724,9 +712,9 @@ public class PredictionContext: Hashable, CustomStringConvertible {
}
if let recognizer = recognizer {
if localBuffer.length > 1 {
if localBuffer.count > 1 {
// first char is '[', if more than that this isn't the first rule
localBuffer.append(" ")
localBuffer += " "
}
let atn = recognizer.getATN()
@ -736,19 +724,19 @@ public class PredictionContext: Hashable, CustomStringConvertible {
}
else if p.getReturnState(index) != PredictionContext.EMPTY_RETURN_STATE {
if !p.isEmpty() {
if localBuffer.length > 1 {
if localBuffer.count > 1 {
// first char is '[', if more than that this isn't the first rule
localBuffer.append(" ")
localBuffer += " "
}
localBuffer.append(p.getReturnState(index))
localBuffer += String(p.getReturnState(index))
}
}
stateNumber = p.getReturnState(index)
p = p.getParent(index)!
}
localBuffer.append("]")
result.append(localBuffer.toString())
localBuffer += "]"
result.append(localBuffer)
if last {
break

View File

@ -31,11 +31,6 @@ public final class RangeTransition: Transition, CustomStringConvertible {
return symbol >= from && symbol <= to
}
public func toString() -> String {
return description
}
public var description: String {
return "'" + String(from) + "'..'" + String(to) + "'"

View File

@ -277,10 +277,6 @@ public class SemanticContext: Hashable, CustomStringConvertible {
return result
}
public func toString() -> String {
return description
}
override
public var description: String {
return opnds.map({ $0.description }).joined(separator: "&&")
@ -386,11 +382,6 @@ public class SemanticContext: Hashable, CustomStringConvertible {
return result
}
public func toString() -> String {
return description
}
override
public var description: String {
return opnds.map({ $0.description }).joined(separator: "||")

View File

@ -49,8 +49,8 @@ public class SingletonPredictionContext: PredictionContext {
override
public var description: String {
let up: String = parent != nil ? parent!.description : ""
if up.length == 0 {
let up = parent?.description ?? ""
if up.isEmpty {
if returnState == PredictionContext.EMPTY_RETURN_STATE {
return "$"
}

View File

@ -165,18 +165,13 @@ public class DFA: CustomStringConvertible {
return toString(Vocabulary.EMPTY_VOCABULARY)
}
public func toString() -> String {
return description
}
public func toString(_ vocabulary: Vocabulary) -> String {
if s0 == nil {
return ""
}
let serializer = DFASerializer(self, vocabulary)
return serializer.toString()
return serializer.description
}
public func toLexerString() -> String {
@ -184,7 +179,7 @@ public class DFA: CustomStringConvertible {
return ""
}
let serializer = LexerDFASerializer(self)
return serializer.toString()
return serializer.description
}
}

View File

@ -22,37 +22,25 @@ public class DFASerializer: CustomStringConvertible {
if dfa.s0 == nil {
return ""
}
let buf = StringBuilder()
var buf = ""
let states = dfa.getStates()
for s in states {
guard let edges = s.edges else {
continue
}
let n = edges.count
for i in 0..<n {
if let t = s.edges![i], t.stateNumber != Int.max {
buf.append(getStateString(s))
let label = getEdgeLabel(i)
buf.append("-")
buf.append(label)
buf.append("->")
buf.append(getStateString(t))
buf.append("\n")
for (i, t) in edges.enumerated() {
guard let t = t, t.stateNumber != Int.max else {
continue
}
let edgeLabel = getEdgeLabel(i)
buf += getStateString(s)
buf += "-\(edgeLabel)->"
buf += getStateString(t)
buf += "\n"
}
}
let output = buf.toString()
if output.length == 0 {
return ""
}
//return Utils.sortLinesInString(output);
return output
}
public func toString() -> String {
return description
return buf
}
internal func getEdgeLabel(_ i: Int) -> String {

View File

@ -136,17 +136,17 @@ public class DFAState: Hashable, CustomStringConvertible {
/// _#stateNumber_ is irrelevant.
///
public var description: String {
let buf = StringBuilder()
buf.append(stateNumber).append(":").append(configs)
var buf = "\(stateNumber):\(configs)"
if isAcceptState {
buf.append("=>")
buf += "=>"
if let predicates = predicates {
buf.append(predicates.map({ $0.description }))
} else {
buf.append(prediction)
buf += String(describing: predicates)
}
else {
buf += String(prediction)
}
}
return buf.toString()
return buf
}
}

View File

@ -1104,15 +1104,15 @@ public class BitSet: Hashable, CustomStringConvertible {
///
/// Example:
///
/// BitSet drPepper = new BitSet();
/// Now `drPepper.toString()` returns "`{`}".
/// `BitSet drPepper = new BitSet();`
/// Now `drPepper.description` returns `"{}"`.
///
/// drPepper.set(2);
/// Now `drPepper.toString()` returns "`{2`}".
/// `drPepper.set(2);`
/// Now `drPepper.description` returns `"{2}"`.
///
/// drPepper.set(4);
/// drPepper.set(10);
/// Now `drPepper.toString()` returns "`{2, 4, 10`}".
/// `drPepper.set(4);`
/// `drPepper.set(10);`
/// Now `drPepper.description` returns `"{2, 4, 10}"`.
///
/// - returns: a string representation of this bit set
///
@ -1121,29 +1121,24 @@ public class BitSet: Hashable, CustomStringConvertible {
//let numBits: Int = (wordsInUse > 128) ?
// cardinality() : wordsInUse * BitSet.BITS_PER_WORD
let b = StringBuilder()
b.append("{")
var b = "{"
var i = firstSetBit()
if i != -1 {
b.append(i)
b += String(i)
i = try! nextSetBit(i + 1)
while i >= 0 {
let endOfRun = try! nextClearBit(i)
repeat {
b.append(", ").append(i)
b += ", \(i)"
i += 1
} while i < endOfRun
i = try! nextSetBit(i + 1)
}
}
b.append("}")
return b.toString()
b += "}"
return b
}
public func toString() -> String {
return description
}
}
public func ==(lhs: BitSet, rhs: BitSet) -> Bool {

View File

@ -146,6 +146,4 @@ public protocol IntSet {
/// in ascending numerical order.
///
func toList() -> [Int]
func toString() -> String
}

View File

@ -159,12 +159,6 @@ public class Interval: Hashable {
}
public func toString() -> String {
return "\(a)..\(b)"
}
public var description: String {
return "\(a)..\(b)"
}

View File

@ -105,7 +105,6 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
if readonly {
throw ANTLRError.illegalState(msg: "can't alter readonly IntervalSet")
}
//System.out.println("add "+addition+" to "+intervals.toString());
if addition.b < addition.a {
return
}
@ -509,109 +508,112 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
public var description: String {
return toString(false)
}
public func toString() -> String {
return description
}
public func toString(_ elemAreChar: Bool) -> String {
let buf = StringBuilder()
if self.intervals.isEmpty {
if intervals.isEmpty {
return "{}"
}
if self.size() > 1 {
buf.append("{")
let selfSize = size()
var buf = ""
if selfSize > 1 {
buf += "{"
}
var first = true
for interval in intervals {
if !first {
buf.append(", ")
buf += ", "
}
first = false
let a = interval.a
let b = interval.b
if a == b {
if a == CommonToken.EOF {
buf.append("<EOF>")
} else {
if elemAreChar {
buf.append("'").append(String(a)).append("'")
} else {
buf.append(a)
}
buf += "<EOF>"
}
} else {
if elemAreChar {
buf.append("'").append(String(a)).append("'..'").append(String(b)).append("'")
} else {
buf.append(a).append("..").append(b)
else if elemAreChar {
buf += "'\(a)'"
}
else {
buf += "\(a)"
}
}
else if elemAreChar {
buf += "'\(a)'..'\(b)'"
}
else {
buf += "\(a)..\(b)"
}
}
if self.size() > 1 {
buf.append("}")
if selfSize > 1 {
buf += "}"
}
return buf.toString()
return buf
}
public func toString(_ vocabulary: Vocabulary) -> String {
let buf = StringBuilder()
if self.intervals.isEmpty {
if intervals.isEmpty {
return "{}"
}
if self.size() > 1 {
buf.append("{")
let selfSize = size()
var buf = ""
if selfSize > 1 {
buf += "{"
}
var first = true
for interval in intervals {
if !first {
buf.append(", ")
buf += ", "
}
first = false
let a = interval.a
let b = interval.b
if a == b {
buf.append(elementName(vocabulary, a))
} else {
buf += elementName(vocabulary, a)
}
else {
for i in a...b {
if i > a {
buf.append(", ")
buf += ", "
}
buf.append(elementName(vocabulary, i))
buf += elementName(vocabulary, i)
}
}
}
if selfSize > 1 {
buf += "}"
}
if self.size() > 1 {
buf.append("}")
}
return buf.toString()
return buf
}
internal func elementName(_ vocabulary: Vocabulary, _ a: Int) -> String {
if a == CommonToken.EOF {
return "<EOF>"
} else {
if a == CommonToken.EPSILON {
return "<EPSILON>"
} else {
return vocabulary.getDisplayName(a)
}
}
else if a == CommonToken.EPSILON {
return "<EPSILON>"
}
else {
return vocabulary.getDisplayName(a)
}
}
public func size() -> Int {
var n = 0
let numIntervals = intervals.count
if numIntervals == 1 {
let firstInterval = intervals[0]
return firstInterval.b - firstInterval.a + 1
}
for i in 0..<numIntervals {
let interval = intervals[i]
for interval in intervals {
n += (interval.b - interval.a + 1)
}
return n

View File

@ -10,27 +10,25 @@ import Foundation
public class Utils {
public static func escapeWhitespace(_ s: String, _ escapeSpaces: Bool) -> String {
let buf: StringBuilder = StringBuilder()
for c: Character in s.characters {
var buf = ""
for c in s {
if c == " " && escapeSpaces {
buf.append("\u{00B7}")
} else {
if c == "\t" {
buf.append("\\t")
} else {
if c == "\n" {
buf.append("\\n")
} else {
if c == "\r" {
buf.append("\\r")
} else {
buf.append(String(c))
}
}
}
buf += "\u{00B7}"
}
else if c == "\t" {
buf += "\\t"
}
else if c == "\n" {
buf += "\\n"
}
else if c == "\r" {
buf += "\\r"
}
else {
buf.append(c)
}
}
return buf.toString()
return buf
}

View File

@ -6,62 +6,38 @@
import Foundation
//http://stackoverflow.com/questions/28182441/swift-how-to-get-substring-from-start-to-last-index-of-character
//https://github.com/williamFalcon/Bolt_Swift/blob/master/Bolt/BoltLibrary/String/String.swift
extension String {
var length: Int {
return self.characters.count
}
func indexOf(_ target: String) -> Int {
let range = self.range(of: target)
if let range = range {
return self.characters.distance(from: self.startIndex, to: range.lowerBound)
} else {
return -1
func lastIndex(of target: String) -> String.Index? {
if target.isEmpty {
return nil
}
}
func indexOf(_ target: String, startIndex: Int) -> Int {
let startRange = self.characters.index(self.startIndex, offsetBy: startIndex)
let range = self.range(of: target, options: .literal, range: startRange..<self.endIndex)
if let range = range {
return self.characters.distance(from: self.startIndex, to: range.lowerBound)
} else {
return -1
}
}
func lastIndexOf(_ target: String) -> Int {
var index = -1
var stepIndex = self.indexOf(target)
while stepIndex > -1 {
index = stepIndex
if stepIndex + target.length < self.length {
stepIndex = indexOf(target, startIndex: stepIndex + target.length)
} else {
stepIndex = -1
var result: String.Index? = nil
var substring = self[...]
while true {
guard let targetRange = substring.range(of: target) else {
return result
}
result = targetRange.lowerBound
let nextChar = substring.index(after: targetRange.lowerBound)
substring = self[nextChar...]
}
return index
}
subscript(integerIndex: Int) -> Character {
let index = characters.index(startIndex, offsetBy: integerIndex)
return self[index]
}
subscript(integerRange: Range<Int>) -> String {
let start = characters.index(startIndex, offsetBy: integerRange.lowerBound)
let end = characters.index(startIndex, offsetBy: integerRange.upperBound)
let start = index(startIndex, offsetBy: integerRange.lowerBound)
let end = index(startIndex, offsetBy: integerRange.upperBound)
let range = start ..< end
return String(self[range])
}
}
// Implement Substring.hasPrefix, which is not currently in the Linux stdlib.
// https://bugs.swift.org/browse/SR-5627
#if os(Linux)
extension Substring {
func hasPrefix(_ prefix: String) -> Bool {
return String(self).hasPrefix(prefix)
}
}
#endif

View File

@ -1,67 +0,0 @@
/* 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.
*/
//
// StringBuilder.swift
// antlr.swift
//
// Created by janyou on 15/9/4.
//
import Foundation
public class StringBuilder {
private var stringValue: String
public init(string: String = "") {
self.stringValue = string
}
public func toString() -> String {
return stringValue
}
public var length: Int {
return stringValue.length
}
@discardableResult
public func append(_ string: String) -> StringBuilder {
stringValue += string
return self
}
@discardableResult
public func append<T:CustomStringConvertible>(_ value: T) -> StringBuilder {
stringValue += value.description
return self
}
@discardableResult
public func appendLine(_ string: String) -> StringBuilder {
stringValue += string + "\n"
return self
}
@discardableResult
public func appendLine<T:CustomStringConvertible>(_ value: T) -> StringBuilder {
stringValue += value.description + "\n"
return self
}
@discardableResult
public func clear() -> StringBuilder {
stringValue = ""
return self
}
}
public func +=(lhs: StringBuilder, rhs: String) {
lhs.append(rhs)
}
public func +=<T:CustomStringConvertible>(lhs: StringBuilder, rhs: T) {
lhs.append(rhs.description)
}
public func +(lhs: StringBuilder, rhs: StringBuilder) -> StringBuilder {
return StringBuilder(string: lhs.toString() + rhs.toString())
}

View File

@ -64,24 +64,20 @@ public class Trees {
/// parse trees and extract data appropriately.
///
public static func toStringTree(_ t: Tree, _ ruleNames: Array<String>?) -> String {
var s: String = Utils.escapeWhitespace(getNodeText(t, ruleNames), false)
let s = Utils.escapeWhitespace(getNodeText(t, ruleNames), false)
if t.getChildCount() == 0 {
return s
}
let buf: StringBuilder = StringBuilder()
buf.append("(")
s = Utils.escapeWhitespace(getNodeText(t, ruleNames), false)
buf.append(s)
buf.append(" ")
var buf = "(\(s) "
let length = t.getChildCount()
for i in 0..<length {
if i > 0 {
buf.append(" ")
buf += " "
}
buf.append(toStringTree(t.getChild(i)!, ruleNames))
buf += toStringTree(t.getChild(i)!, ruleNames)
}
buf.append(")")
return buf.toString()
buf += ")"
return buf
}
public static func getNodeText(_ t: Tree, _ recog: Parser?) -> String {

View File

@ -160,9 +160,6 @@ public class ParseTreeMatch: CustomStringConvertible {
return tree
}
public func toString() -> String {
return description
}
public var description: String {
let info = succeeded() ? "succeeded" : "failed"
return "Match \(info); found \(getLabels().size()) labels"

View File

@ -311,7 +311,7 @@ public class ParseTreePatternMatcher {
for chunk in chunks {
if let tagChunk = chunk as? TagChunk {
// add special rule token or conjure up new token from name
let firstStr = String(tagChunk.getTag()[0])
let firstStr = String(tagChunk.getTag().first!)
if firstStr.lowercased() != firstStr {
let ttype = parser.getTokenType(tagChunk.getTag())
if ttype == CommonToken.INVALID_TYPE {
@ -351,29 +351,34 @@ public class ParseTreePatternMatcher {
/// Split `<ID> = <e:expr> ;` into 4 chunks for tokenizing by _#tokenize_.
///
public func split(_ pattern: String) throws -> [Chunk] {
var p = 0
let n = pattern.length
var p = pattern.startIndex
let n = pattern.endIndex
var chunks = [Chunk]()
// find all start and stop indexes first, then collect
var starts = [Int]()
var stops = [Int]()
var starts = [Range<String.Index>]()
var stops = [Range<String.Index>]()
let escapedStart = escape + start
let escapedStop = escape + stop
while p < n {
if p == pattern.indexOf(escape + start, startIndex: p) {
p += escape.length + start.length
let slice = pattern[p...]
if slice.hasPrefix(escapedStart) {
p = pattern.index(p, offsetBy: escapedStart.count)
}
else if p == pattern.indexOf(escape + stop, startIndex: p) {
p += escape.length + stop.length
else if slice.hasPrefix(escapedStop) {
p = pattern.index(p, offsetBy: escapedStop.count)
}
else if p == pattern.indexOf(start, startIndex: p) {
starts.append(p)
p += start.length
else if slice.hasPrefix(start) {
let upperBound = pattern.index(p, offsetBy: start.count)
starts.append(p ..< upperBound)
p = upperBound
}
else if p == pattern.indexOf(stop, startIndex: p) {
stops.append(p)
p += stop.length
else if slice.hasPrefix(stop) {
let upperBound = pattern.index(p, offsetBy: stop.count)
stops.append(p ..< upperBound)
p = upperBound
}
else {
p += 1
p = pattern.index(after: p)
}
}
@ -387,46 +392,50 @@ public class ParseTreePatternMatcher {
let ntags = starts.count
for i in 0..<ntags {
if starts[i] >= stops[i] {
if starts[i].lowerBound >= stops[i].lowerBound {
throw ANTLRError.illegalArgument(msg: "tag delimiters out of order in pattern: " + pattern)
}
}
// collect into chunks now
if ntags == 0 {
let text = pattern[0 ..< n]
let text = String(pattern[..<n])
chunks.append(TextChunk(text))
}
if ntags > 0 && starts[0] > 0 {
if ntags > 0 && starts[0].lowerBound > pattern.startIndex {
// copy text up to first tag into chunks
let text = pattern[0 ..< starts[0]]
chunks.append(TextChunk(text))
let text = pattern[pattern.startIndex ..< starts[0].lowerBound]
chunks.append(TextChunk(String(text)))
}
for i in 0 ..< ntags {
// copy inside of <tag>
let tag = pattern[starts[i] + start.length ..< stops[i]]
var ruleOrToken = tag
var label: String?
let colon = tag.indexOf(":")
if colon >= 0 {
label = tag[0 ..< colon]
ruleOrToken = tag[colon + 1 ..< tag.length]
let tag = pattern[starts[i].upperBound ..< stops[i].lowerBound]
let ruleOrToken: String
let label: String?
let bits = tag.split(separator: ":", maxSplits: 1)
if bits.count == 2 {
label = String(bits[0])
ruleOrToken = String(bits[1])
}
else {
label = nil
ruleOrToken = String(tag)
}
chunks.append(try TagChunk(label, ruleOrToken))
if i + 1 < ntags {
// copy from end of <tag> to start of next
let text = pattern[stops[i] + stop.length ..< starts[i + 1]]
chunks.append(TextChunk(text))
let text = pattern[stops[i].upperBound ..< starts[i + 1].lowerBound]
chunks.append(TextChunk(String(text)))
}
}
if ntags > 0 {
let afterLastTag = stops[ntags - 1] + stop.length
let afterLastTag = stops[ntags - 1].upperBound
if afterLastTag < n {
// copy text from end of last tag to end
let text = pattern[afterLastTag ..< n]
chunks.append(TextChunk(text))
chunks.append(TextChunk(String(text)))
}
}
@ -435,7 +444,7 @@ public class ParseTreePatternMatcher {
let c = chunks[i]
if let tc = c as? TextChunk {
let unescaped = tc.getText().replacingOccurrences(of: escape, with: "")
if unescaped.length < tc.getText().length {
if unescaped.count < tc.getText().count {
chunks[i] = TextChunk(unescaped)
}
}

View File

@ -0,0 +1,26 @@
/// 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
import XCTest
import Antlr4
class RuntimeMetaDataTests: XCTestCase {
func testGetMajorMinorVersion() {
doGetMajorMinorVersionTest("", "")
doGetMajorMinorVersionTest("4", "4")
doGetMajorMinorVersionTest("4.", "4.")
doGetMajorMinorVersionTest("4.7", "4.7")
doGetMajorMinorVersionTest("4.7.1", "4.7")
doGetMajorMinorVersionTest("4-SNAPSHOT", "4")
doGetMajorMinorVersionTest("4.-SNAPSHOT", "4.")
doGetMajorMinorVersionTest("4.7-SNAPSHOT", "4.7")
doGetMajorMinorVersionTest("4.7.1-SNAPSHOT", "4.7")
}
}
private func doGetMajorMinorVersionTest(_ input: String, _ expected: String) {
XCTAssertEqual(RuntimeMetaData.getMajorMinorVersion(input), expected)
}

View File

@ -0,0 +1,31 @@
/// 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
import XCTest
@testable import Antlr4
class StringExtensionTests: XCTestCase {
func testLastIndex() {
doLastIndexTest("", "", nil)
doLastIndexTest("a", "", nil)
doLastIndexTest("a", "a", 0)
doLastIndexTest("aba", "a", 2)
doLastIndexTest("aba", "b", 1)
doLastIndexTest("abc", "d", nil)
}
}
private func doLastIndexTest(_ str: String, _ target: String, _ expectedOffset: Int?) {
let expectedIdx: String.Index?
if let expectedOffset = expectedOffset {
expectedIdx = str.index(str.startIndex, offsetBy: expectedOffset)
}
else {
expectedIdx = nil
}
XCTAssertEqual(str.lastIndex(of: target), expectedIdx)
}