forked from jasder/antlr
Merge pull request #2107 from ewanmellor/swift-fix-deprecated-string-methods
Remove use of deprecated String functions
This commit is contained in:
commit
84e9a46932
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
///
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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!
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) → rewrite (List)
|
||||
///
|
||||
internal var programs: Dictionary<String, RewriteOperationArray> //Array<RewriteOperation>
|
||||
internal var programs = [String: RewriteOperationArray]()
|
||||
|
||||
/// Map String (program name) → 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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
///
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)")
|
||||
|
|
|
@ -42,9 +42,4 @@ public final class PrecedencePredicateTransition: AbstractPredicateTransition, C
|
|||
public var description: String {
|
||||
return "\(precedence) >= _p"
|
||||
}
|
||||
|
||||
public func toString() -> String {
|
||||
return description
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) + "'"
|
||||
|
||||
|
|
|
@ -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: "||")
|
||||
|
|
|
@ -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 "$"
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -146,6 +146,4 @@ public protocol IntSet {
|
|||
/// in ascending numerical order.
|
||||
///
|
||||
func toList() -> [Int]
|
||||
|
||||
func toString() -> String
|
||||
}
|
||||
|
|
|
@ -159,12 +159,6 @@ public class Interval: Hashable {
|
|||
}
|
||||
|
||||
|
||||
public func toString() -> String {
|
||||
return "\(a)..\(b)"
|
||||
|
||||
}
|
||||
|
||||
|
||||
public var description: String {
|
||||
return "\(a)..\(b)"
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue