swift build & swift test support Linux platform

This commit is contained in:
Hanzhou Shi 2017-05-07 20:50:54 -07:00
parent 3095de982e
commit a879297bb5
19 changed files with 188 additions and 122 deletions

View File

@ -236,9 +236,9 @@ public class CommonToken: WritableToken {
}
var txt: String
if let tokenText = getText() {
txt = tokenText.replaceAll("\n", replacement: "\\n")
txt = txt.replaceAll("\r", replacement: "\\r")
txt = txt.replaceAll("\t", replacement: "\\t")
txt = tokenText.replacingOccurrences(of: "\n", with: "\\n")
txt = txt.replacingOccurrences(of: "\r", with: "\\r")
txt = txt.replacingOccurrences(of: "\t", with: "\\t")
} else {
txt = "<no text>"
}

View File

@ -574,9 +574,9 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
internal func escapeWSAndQuote(_ s: String) -> String {
var s = s
s = s.replaceAll("\n", replacement: "\\n")
s = s.replaceAll("\r", replacement: "\\r")
s = s.replaceAll("\t", replacement: "\\t")
s = s.replacingOccurrences(of: "\n", with: "\\n")
s = s.replacingOccurrences(of: "\r", with: "\\r")
s = s.replacingOccurrences(of: "\t", with: "\\t")
return "'" + s + "'"
}

View File

@ -60,8 +60,7 @@ public class DiagnosticErrorListener: BaseErrorListener {
let decision: String = getDecisionDescription(recognizer, dfa)
let conflictingAlts: BitSet = try getConflictingAlts(ambigAlts, configs)
let text: String = try recognizer.getTokenStream()!.getText(Interval.of(startIndex, stopIndex))
let message: String = NSString(format: format as NSString, decision, conflictingAlts.description, text) as String
let message = makeString(fromFormat: format, decision, conflictingAlts.description, text)
try recognizer.notifyErrorListeners(message)
}
@ -75,7 +74,7 @@ public class DiagnosticErrorListener: BaseErrorListener {
let format: String = "reportAttemptingFullContext d=%@, input='%@'"
let decision: String = getDecisionDescription(recognizer, dfa)
let text: String = try recognizer.getTokenStream()!.getText(Interval.of(startIndex, stopIndex))
let message: String = NSString(format: format as NSString, decision, text) as String
let message = makeString(fromFormat: format, decision, text)
try recognizer.notifyErrorListeners(message)
}
@ -89,7 +88,7 @@ public class DiagnosticErrorListener: BaseErrorListener {
let format: String = "reportContextSensitivity d=%@, input='%@'"
let decision: String = getDecisionDescription(recognizer, dfa)
let text: String = try recognizer.getTokenStream()!.getText(Interval.of(startIndex, stopIndex))
let message: String = NSString(format: format as NSString, decision, text) as String
let message = makeString(fromFormat: format, decision, text)
try recognizer.notifyErrorListeners(message)
}
@ -107,8 +106,7 @@ public class DiagnosticErrorListener: BaseErrorListener {
if ruleName.isEmpty {
return String(decision)
}
return NSString(format: "%d (%@)", decision, ruleName) as String
return makeString(fromFormat: "%@ (%@)", decision.description, ruleName)
}
/// Computes the set of conflicting or ambiguous alternatives from a
@ -127,4 +125,5 @@ public class DiagnosticErrorListener: BaseErrorListener {
let result = try configs.getAltBitSet()
return result
}
}

View File

@ -440,7 +440,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
let serializedAtn: String = getSerializedATN()
var result: ATN? = bypassAltsAtnCache[serializedAtn]
synced(bypassAltsAtnCache) {
synchronized {
[unowned self] in
if result == nil {
let deserializationOptions: ATNDeserializationOptions = ATNDeserializationOptions()
@ -988,7 +988,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
guard let _interp = _interp else {
return s
}
synced(_interp.decisionToDFA as AnyObject) {
synchronized {
[unowned self] in
for d in 0..<_interp.decisionToDFA.count {
@ -1005,7 +1005,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
guard let _interp = _interp else {
return
}
synced(_interp.decisionToDFA as AnyObject) {
synchronized {
[unowned self] in
var seenOne: Bool = false

View File

@ -57,7 +57,7 @@ open class Recognizer<ATNInterpreter:ATNSimulator> {
public func getTokenTypeMap() -> Dictionary<String, Int> {
let vocabulary: Vocabulary = getVocabulary()
var result: Dictionary<String, Int>? = self.tokenTypeMapCache[vocabulary]
synced(tokenTypeMapCache) {
synchronized {
[unowned self] in
if result == nil {
result = Dictionary<String, Int>()
@ -96,7 +96,7 @@ open class Recognizer<ATNInterpreter:ATNSimulator> {
let ruleNames: [String] = getRuleNames()
let result: Dictionary<String, Int>? = self.ruleIndexMapCache[ArrayWrapper<String>(ruleNames)]
synced(ruleIndexMapCache) {
synchronized {
[unowned self] in
if result == nil {
self.ruleIndexMapCache[ArrayWrapper<String>(ruleNames)] = Utils.toMap(ruleNames)
@ -212,9 +212,9 @@ open class Recognizer<ATNInterpreter:ATNSimulator> {
s = "<\(t.getType())>"
}
}
s = s.replaceAll("\n", replacement: "\\n")
s = s.replaceAll("\r", replacement: "\\r")
s = s.replaceAll("\t", replacement: "\\t")
s = s.replacingOccurrences(of: "\n", with: "\\n")
s = s.replacingOccurrences(of: "\r", with: "\\r")
s = s.replacingOccurrences(of: "\t", with: "\\t")
return "\(s)"
}

View File

@ -554,22 +554,19 @@ public class ATNDeserializer {
}
public func deserializeFromJson(_ jsonStr: String) -> ATN {
// let jsonStr = Utils.readFile2String(jsonFileName)
guard !jsonStr.isEmpty else {
fatalError("ATN Serialization is empty,Please include *LexerATN.json and *ParserATN.json in TARGETS-Build Phases-Copy Bundle Resources")
}
if let JSONData = jsonStr.data(using: String.Encoding.utf8) {
do {
let JSON = try JSONSerialization.jsonObject(with: JSONData, options: JSONSerialization.ReadingOptions(rawValue: 0))
guard let JSONDictionary: NSDictionary = JSON as? NSDictionary else {
print("Not a Dictionary")
// put in function
guard let JSONDictionary = JSON as? Dictionary<String, Any> else {
fatalError("deserializeFromJson Not a Dictionary")
}
return try dictToJson(JSONDictionary)
} catch let JSONError as NSError {
} catch let JSONError {
print("\(JSONError)")
}
}
@ -577,10 +574,10 @@ public class ATNDeserializer {
fatalError("Could not deserialize ATN ")
}
public func dictToJson(_ dict: NSDictionary) throws -> ATN {
public func dictToJson(_ dict: Dictionary<String, Any>) throws -> ATN {
let version: Int = dict.object(forKey: "version") as! Int
let version: Int = dict["version"] as! Int
if version != ATNDeserializer.SERIALIZED_VERSION {
let reason: String = "Could not deserialize ATN with version \(version) (expected \(ATNDeserializer.SERIALIZED_VERSION))."
@ -588,7 +585,7 @@ public class ATNDeserializer {
throw ANTLRError.unsupportedOperation(msg: reason)
}
let uuid: UUID = UUID(uuidString: dict.object(forKey: "uuid") as! String)!
let uuid: UUID = UUID(uuidString: dict["uuid"] as! String)!
if !ATNDeserializer.SUPPORTED_UUIDS.contains(uuid) {
let reason: String = "Could not deserialize ATN with UUID \(uuid) (expected \(ATNDeserializer.SERIALIZED_UUID) or a legacy UUID)."
@ -599,8 +596,8 @@ public class ATNDeserializer {
let supportsPrecedencePredicates: Bool = isFeatureSupported(ATNDeserializer.ADDED_PRECEDENCE_TRANSITIONS, uuid)
let supportsLexerActions: Bool = isFeatureSupported(ATNDeserializer.ADDED_LEXER_ACTIONS, uuid)
let grammarType: ATNType = ATNType(rawValue: dict.object(forKey: "grammarType") as! Int)!
let maxTokenType: Int = dict.object(forKey: "maxTokenType") as! Int
let grammarType: ATNType = ATNType(rawValue: dict["grammarType"] as! Int)!
let maxTokenType: Int = dict["maxTokenType"] as! Int
let atn: ATN = ATN(grammarType, maxTokenType)
//
@ -609,22 +606,22 @@ public class ATNDeserializer {
var loopBackStateNumbers: Array<(LoopEndState, Int)> = Array<(LoopEndState, Int)>()
var endStateNumbers: Array<(BlockStartState, Int)> = Array<(BlockStartState, Int)>()
let states = dict.object(forKey: "states") as! [NSDictionary]
let states = dict["states"] as! [Dictionary<String, Any>]
for state in states {
let ruleIndex: Int = state.object(forKey: "ruleIndex") as! Int
let ruleIndex: Int = state["ruleIndex"] as! Int
let stype: Int = state.object(forKey: "stateType") as! Int
let stype: Int = state["stateType"] as! Int
let s: ATNState = try stateFactory(stype, ruleIndex)!
if stype == ATNState.LOOP_END {
// special case
let loopBackStateNumber: Int = state.object(forKey: "detailStateNumber") as! Int
let loopBackStateNumber: Int = state["detailStateNumber"] as! Int
loopBackStateNumbers.append((s as! LoopEndState, loopBackStateNumber))
} else {
if s is BlockStartState {
let endStateNumber: Int = state.object(forKey: "detailStateNumber") as! Int
let endStateNumber: Int = state["detailStateNumber"] as! Int
endStateNumbers.append((s as! BlockStartState, endStateNumber))
}
}
@ -642,13 +639,13 @@ public class ATNDeserializer {
pair.0.endState = atn.states[pair.1] as? BlockEndState
}
let numNonGreedyStates = dict.object(forKey: "nonGreedyStates") as! [Int]
let numNonGreedyStates = dict["nonGreedyStates"] as! [Int]
for numNonGreedyState in numNonGreedyStates {
(atn.states[numNonGreedyState] as! DecisionState).nonGreedy = true
}
if supportsPrecedencePredicates {
let numPrecedenceStates = dict.object(forKey: "precedenceStates") as! [Int]
let numPrecedenceStates = dict["precedenceStates"] as! [Int]
for numPrecedenceState in numPrecedenceStates {
(atn.states[numPrecedenceState] as! RuleStartState).isPrecedenceRule = true
}
@ -658,7 +655,7 @@ public class ATNDeserializer {
//
// RULES
//
let ruleToStartState = dict.object(forKey: "ruleToStartState") as! [NSDictionary]
let ruleToStartState = dict["ruleToStartState"] as! [Dictionary<String, Any>]
let nrules: Int = ruleToStartState.count
if atn.grammarType == ATNType.lexer {
@ -668,11 +665,11 @@ public class ATNDeserializer {
atn.ruleToStartState = [RuleStartState](repeating: RuleStartState(), count: nrules) // [nrules];
for i in 0..<nrules {
let currentRuleToStartState = ruleToStartState[i]
let s: Int = currentRuleToStartState.object(forKey: "stateNumber") as! Int
let s: Int = currentRuleToStartState["stateNumber"] as! Int
let startState: RuleStartState = atn.states[s] as! RuleStartState
atn.ruleToStartState[i] = startState
if atn.grammarType == ATNType.lexer {
var tokenType: Int = currentRuleToStartState.object(forKey: "ruleToTokenType") as! Int
var tokenType: Int = currentRuleToStartState["ruleToTokenType"] as! Int
if tokenType == -1 {
tokenType = CommonToken.EOF
}
@ -699,7 +696,7 @@ public class ATNDeserializer {
//
// MODES
//
let modeToStartState = dict.object(forKey: "modeToStartState") as! [Int]
let modeToStartState = dict["modeToStartState"] as! [Int]
//let nmodes : Int = toInt(data[p++]);
//for var i : Int=0; i<nmodes; i++ {
for stateNumber in modeToStartState {
@ -708,33 +705,30 @@ public class ATNDeserializer {
//atn.modeToStartState.append(atn.states[s] as! TokensStartState)
}
//
// SETS
//
var sets: Array<IntervalSet> = Array<IntervalSet>()
let nsets: Int = dict.object(forKey: "nsets") as! Int
let intervalSet = dict.object(forKey: "IntervalSet") as! [NSDictionary]
let nsets: Int = dict["nsets"] as! Int
let intervalSet = dict["IntervalSet"] as! [Dictionary<String, Any>]
for i in 0..<nsets {
let setBuilder = intervalSet[i]
let nintervals: Int = setBuilder.object(forKey: "size") as! Int
let nintervals: Int = setBuilder["size"] as! Int
let set: IntervalSet = try IntervalSet()
sets.append(set)
let containsEof: Bool = (setBuilder.object(forKey: "containsEof") as! Int) != 0
let containsEof: Bool = (setBuilder["containsEof"] as! Int) != 0
if containsEof {
try set.add(-1)
}
let intervalsBuilder = setBuilder.object(forKey: "Intervals") as! [NSDictionary]
let intervalsBuilder = setBuilder["Intervals"] as! [Dictionary<String, Any>]
for j in 0..<nintervals {
let vals = intervalsBuilder[j]
try set.add((vals.object(forKey: "a") as! Int), (vals.object(forKey: "b") as! Int))
try set.add((vals["a"] as! Int), (vals["b"] as! Int))
}
}
@ -744,17 +738,17 @@ public class ATNDeserializer {
// EDGES
//
// let nedges : Int = dict.objectForKey("nedges") as! Int
let allTransitions = dict.object(forKey: "allTransitionsBuilder") as! [[NSDictionary]]
let allTransitions = dict["allTransitionsBuilder"] as! [[Dictionary<String, Any>]]
for transitionsBuilder in allTransitions {
for transition in transitionsBuilder {
let src: Int = transition.object(forKey: "src") as! Int
let trg: Int = transition.object(forKey: "trg") as! Int
let ttype: Int = transition.object(forKey: "edgeType") as! Int
let arg1: Int = transition.object(forKey: "arg1") as! Int
let arg2: Int = transition.object(forKey: "arg2") as! Int
let arg3: Int = transition.object(forKey: "arg3") as! Int
let src: Int = transition["src"] as! Int
let trg: Int = transition["trg"] as! Int
let ttype: Int = transition["edgeType"] as! Int
let arg1: Int = transition["arg1"] as! Int
let arg2: Int = transition["arg2"] as! Int
let arg3: Int = transition["arg3"] as! Int
let trans: Transition = try edgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets)
let srcState: ATNState = atn.states[src]!
@ -830,7 +824,7 @@ public class ATNDeserializer {
//
// DECISIONS
//
let ndecisions: [Int] = dict.object(forKey: "decisionToState") as! [Int]
let ndecisions: [Int] = dict["decisionToState"] as! [Int]
let length = ndecisions.count
for i in 0..<length {
let s: Int = ndecisions[i]
@ -844,17 +838,17 @@ public class ATNDeserializer {
// LEXER ACTIONS
//
if atn.grammarType == ATNType.lexer {
let lexerActionsBuilder = dict.object(forKey: "lexerActions") as! [NSDictionary]
let lexerActionsBuilder = dict["lexerActions"] as! [Dictionary<String, Any>]
if supportsLexerActions {
atn.lexerActions = [LexerAction](repeating: LexerAction(), count: lexerActionsBuilder.count) //[toInt(data[p++])];
let length = atn.lexerActions.count
for i in 0..<length {
let actionTypeValue = lexerActionsBuilder[i].object(forKey: "actionType") as! Int
let actionTypeValue = lexerActionsBuilder[i]["actionType"] as! Int
let actionType: LexerActionType = LexerActionType(rawValue: actionTypeValue)! //LexerActionType.values()[toInt(data[p++])];
let data1: Int = lexerActionsBuilder[i].object(forKey: "a") as! Int
let data1: Int = lexerActionsBuilder[i]["a"] as! Int
let data2: Int = lexerActionsBuilder[i].object(forKey: "b") as! Int
let data2: Int = lexerActionsBuilder[i]["b"] as! Int
let lexerAction: LexerAction = lexerActionFactory(actionType, data1, data2)

View File

@ -23,14 +23,12 @@ public class LL1Analyzer {
/// - parameter s: the ATN state
/// - returns: the expected symbols for each outgoing transition of {@code s}.
public func getDecisionLookahead(_ s: ATNState?) throws -> [IntervalSet?]? {
// print("LOOK("+s.stateNumber+")");
guard let s = s else {
return nil
}
let length = s.getNumberOfTransitions()
var look: [IntervalSet?] = [IntervalSet?](repeating: nil, count: length)
//new IntervalSet[s.getNumberOfTransitions()];
for alt in 0..<length {
look[alt] = try IntervalSet()
var lookBusy: Set<ATNConfig> = Set<ATNConfig>()
@ -138,10 +136,6 @@ public class LL1Analyzer {
lookBusy.insert(c)
}
// if ( !lookBusy.insert (c) ) {
// return;
// }
if s == stopState {
guard let ctx = ctx else {
try look.add(CommonToken.EPSILON)
@ -175,11 +169,8 @@ public class LL1Analyzer {
var removed: Bool = try calledRuleStack.get(returnState.ruleIndex!)
//TODO try
//try {
try calledRuleStack.clear(returnState.ruleIndex!)
try self._LOOK(returnState, stopState, ctx.getParent(i), look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
//}
defer {
if removed {
try! calledRuleStack.set(returnState.ruleIndex!)
@ -193,18 +184,15 @@ public class LL1Analyzer {
var n: Int = s.getNumberOfTransitions()
for i in 0..<n {
var t: Transition = s.transition(i)
if type(of: t) === RuleTransition.self {
if type(of: t) == RuleTransition.self {
if try calledRuleStack.get((t as! RuleTransition).target.ruleIndex!) {
continue
}
var newContext: PredictionContext =
SingletonPredictionContext.create(ctx, (t as! RuleTransition).followState.stateNumber)
//TODO try
//try {
try calledRuleStack.set((t as! RuleTransition).target.ruleIndex!)
try _LOOK(t.target, stopState, newContext, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
//}
defer {
try! calledRuleStack.clear((t as! RuleTransition).target.ruleIndex!)
}
@ -219,7 +207,7 @@ public class LL1Analyzer {
if t.isEpsilon() {
try _LOOK(t.target, stopState, ctx, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
} else {
if type(of: t) === WildcardTransition.self {
if type(of: t) == WildcardTransition.self {
try look.addAll(IntervalSet.of(CommonToken.MIN_USER_TOKEN_TYPE, atn.maxTokenType))
} else {

View File

@ -648,7 +648,7 @@ open class LexerATNSimulator: ATNSimulator {
print("EDGE \(p) -> \(q) upon \(t)")
}
synced(p) {
synchronized {
if p.edges == nil {
// make room for tokens 1..n and -1 masquerading as index 0
//TODO ARRAY COUNT

View File

@ -1972,7 +1972,7 @@ open class ParserATNSimulator: ATNSimulator {
guard let from = from else {
return to
}
synced(from) {
synchronized {
[unowned self] in
if from.edges == nil {
from.edges = [DFAState?](repeating: nil, count: self.atn.maxTokenType + 1 + 1) //new DFAState[atn.maxTokenType+1+1];

View File

@ -102,7 +102,7 @@ public class DFA: CustomStringConvertible {
}
// synchronization on s0 here is ok. when the DFA is turned into a
// precedence DFA, s0 will be initialized once and not updated again
synced(s0) {
synchronized {
// s0.edges is never null for a precedence DFA
if precedence >= edges.count {
let increase = [DFAState?](repeating: nil, count: (precedence + 1 - edges.count))

View File

@ -52,7 +52,7 @@ public class Utils {
do {
fileContents = try String(contentsOfFile: path, encoding: encoding)
} catch _ as NSError {
} catch {
return [Character]()
}
@ -68,22 +68,20 @@ public class Utils {
var fileContents: String? = nil
do {
fileContents = try String(contentsOfFile: path!, encoding: encoding)
} catch _ as NSError {
} catch {
return ""
}
return fileContents ?? ""
}
public static func readFile2StringByPath(_ path: String, _ encoding: String.Encoding = String.Encoding.utf8) -> String {
//let path = fileName.stringByExpandingTildeInPath
var fileContents: String? = nil
do {
fileContents = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) as String //try String(contentsOfFile: path!, encoding: encoding)
} catch _ as NSError {
fileContents = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
} catch {
return ""
}

View File

@ -2,36 +2,17 @@
/// 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 Cocoa
#if os(OSX)
import Cocoa
#elseif os(iOS)
import UIKit
#endif
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 {
func trim() -> String {
return self.trimmingCharacters(in: CharacterSet.whitespaces)
}
func split(_ separator: String) -> [String] {
return self.components(separatedBy: separator)
}
func replaceAll(_ from: String, replacement: String) -> String {
return self.replacingOccurrences(of: from, with: replacement, options: NSString.CompareOptions.literal, range: nil)
}
func containsIgnoreCase(_ find: String) -> Bool {
return self.lowercased().range(of: find.lowercased()) != nil
}
@ -53,7 +34,7 @@ extension String {
func indexOf(_ target: String, startIndex: Int) -> Int {
let startRange = self.characters.index(self.startIndex, offsetBy: startIndex)
let range = self.range(of: target, options: NSString.CompareOptions.literal, range: startRange..<self.endIndex)
let range = self.range(of: target, options: .literal, range: startRange..<self.endIndex)
if let range = range {
@ -171,7 +152,6 @@ extension String {
}
}
var result = ""
var position = startIndex
@ -204,8 +184,8 @@ extension String {
}
extension String {
static let htmlEscapedDictionary = [
"&amp;": "&",
"&quot;": "\"",
"&#x27;": "'",
@ -213,13 +193,14 @@ extension String {
"&#x92;": "'",
"&#x96;": "'",
"&gt;": ">",
"&lt;": "<"]
"&lt;": "<"
]
public var escapedHtmlString: String {
var newString = "\(self)"
for (key, value) in String.htmlEscapedDictionary {
newString = newString.replaceAll(value, replacement: key)
newString = newString.replacingOccurrences(of: value, with: key)
}
return newString
}

View File

@ -13,7 +13,7 @@
import Foundation
func errPrint(_ msg: String) {
fputs(msg + "\n", __stderrp)
fputs(msg + "\n", stderr)
}
public func +(lhs: String, rhs: Int) -> String {
@ -57,12 +57,6 @@ func >>>(lhs: Int, rhs: Int) -> Int {
return Int(bitPattern: left >> right)
}
func synced(_ lock: AnyObject, closure: () -> ()) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}
func intChar2String(_ i: Int) -> String {
return String(Character(integerLiteral: i))
}

View File

@ -0,0 +1,41 @@
import Foundation
// MARK: - String
/// Cross-platform String formatting method.
/// We make this method because on Linux String is not conforming to
/// CVarArg, thus cannot be mapped to "%@" in format string.
/// This method implements a work-around that maps "%@" to "%s" in
/// our format string and then convert NSString to CString.
///
/// - Parameters:
/// - format: printf-like format string
/// - args: argument strings
/// - Returns: formatted string
func makeString(fromFormat format: String, _ args: String...) -> String {
#if os(Linux)
let linuxFormat = format.replacingOccurrences(of: "%@", with: "%s")
let cStrings = args.map { $0.withCString { $0 } }
return String(format: linuxFormat, arguments: cStrings)
#else
return String(format: format, args)
#endif
}
// MARK: - Multithread
fileprivate var _GLOBAL_MUTEX = pthread_mutex_t()
/// Cross-platform synchronized execution of a closure.
/// Using naive locking that uses a global mutex lock.
///
/// - Parameter closure: closure needs to be executed.
func synchronized<R>(closure: () -> R) {
pthread_mutex_lock(&_GLOBAL_MUTEX)
defer {
pthread_mutex_unlock(&_GLOBAL_MUTEX)
}
_ = closure()
}

View File

@ -482,7 +482,7 @@ public class ParseTreePatternMatcher {
let c: Chunk = chunks[i]
if c is TextChunk {
let tc: TextChunk = c as! TextChunk
let unescaped: String = tc.getText().replaceAll(escape, replacement: "")
let unescaped = tc.getText().replacingOccurrences(of: escape, with: "")
if unescaped.length < tc.getText().length {
chunks[i] = TextChunk(unescaped)
}

View File

@ -6,7 +6,53 @@ import XCTest
import Antlr4
class TokenStreamRewriterTests: XCTestCase {
static let allTests = [
("testPreservesOrderOfContiguousInserts", testPreservesOrderOfContiguousInserts),
("testDistinguishBetweenInsertAfterAndInsertBeforeToPreserverOrder2", testDistinguishBetweenInsertAfterAndInsertBeforeToPreserverOrder2),
("testDistinguishBetweenInsertAfterAndInsertBeforeToPreserverOrder", testDistinguishBetweenInsertAfterAndInsertBeforeToPreserverOrder),
("testInsertBeforeTokenThenDeleteThatToken", testInsertBeforeTokenThenDeleteThatToken),
("testLeaveAloneDisjointInsert2", testLeaveAloneDisjointInsert2),
("testLeaveAloneDisjointInsert", testLeaveAloneDisjointInsert),
("testDropPrevCoveredInsert", testDropPrevCoveredInsert),
("testDropIdenticalReplace", testDropIdenticalReplace),
("testOverlappingReplace4", testOverlappingReplace4),
("testOverlappingReplace3", testOverlappingReplace3),
("testOverlappingReplace2", testOverlappingReplace2),
("testOverlappingReplace", testOverlappingReplace),
("testDisjointInserts", testDisjointInserts),
("testCombineInsertOnLeftWithDelete", testCombineInsertOnLeftWithDelete),
("testCombineInsertOnLeftWithReplace", testCombineInsertOnLeftWithReplace),
("testCombine3Inserts", testCombine3Inserts),
("testCombineInserts", testCombineInserts),
("testReplaceSingleMiddleThenOverlappingSuperset", testReplaceSingleMiddleThenOverlappingSuperset),
("testReplaceThenReplaceLowerIndexedSuperset", testReplaceThenReplaceLowerIndexedSuperset),
("testReplaceThenReplaceSuperset", testReplaceThenReplaceSuperset),
("testReplaceSubsetThenFetch", testReplaceSubsetThenFetch),
("testReplaceAll", testReplaceAll),
("testReplaceRangeThenInsertAfterRightEdge", testReplaceRangeThenInsertAfterRightEdge),
("testReplaceRangeThenInsertAtRightEdge", testReplaceRangeThenInsertAtRightEdge),
("testReplaceThenInsertAtLeftEdge", testReplaceThenInsertAtLeftEdge),
("testReplaceThenInsertAfterLastIndex", testReplaceThenInsertAfterLastIndex),
("testInsertThenReplaceLastIndex", testInsertThenReplaceLastIndex),
("testReplaceThenInsertBeforeLastIndex", testReplaceThenInsertBeforeLastIndex),
("test2InsertThenReplaceIndex0", test2InsertThenReplaceIndex0),
("test2InsertMiddleIndex", test2InsertMiddleIndex),
("testInsertThenReplaceSameIndex", testInsertThenReplaceSameIndex),
("testInsertInPriorReplace", testInsertInPriorReplace),
("testReplaceThenDeleteMiddleIndex", testReplaceThenDeleteMiddleIndex),
("test2ReplaceMiddleIndex1InsertBefore", test2ReplaceMiddleIndex1InsertBefore),
("test2ReplaceMiddleIndex", test2ReplaceMiddleIndex),
("testToStringStartStop2", testToStringStartStop2),
("testToStringStartStop", testToStringStartStop),
("testReplaceMiddleIndex", testReplaceMiddleIndex),
("testReplaceLastIndex", testReplaceLastIndex),
("testReplaceIndex0", testReplaceIndex0),
("test2InsertBeforeAfterMiddleIndex", test2InsertBeforeAfterMiddleIndex),
("testInsertAfterLastIndex", testInsertAfterLastIndex),
("testInsertBeforeIndex0", testInsertBeforeIndex0)
]
func testInsertBeforeIndex0() throws {
let input = ANTLRInputStream("abc")
let lexer = LexerA(input)

View File

@ -6,6 +6,10 @@ import XCTest
import Antlr4
class TokenStreamTests: XCTestCase {
static let allTests = [
("testBufferedTokenStreamClearFetchEOFWithNewSource", testBufferedTokenStreamClearFetchEOFWithNewSource)
]
/// Test fetchEOF reset after setTokenSource
func testBufferedTokenStreamClearFetchEOFWithNewSource() throws {

View File

@ -6,6 +6,14 @@ import XCTest
import Antlr4
class VisitorTests: XCTestCase {
static let allTests = [
("testCalculatorVisitor", testCalculatorVisitor),
("testShouldNotVisitTerminal", testShouldNotVisitTerminal),
("testShouldNotVisitEOF", testShouldNotVisitEOF),
("testVisitErrorNode", testVisitErrorNode),
("testVisitTerminalNode", testVisitTerminalNode)
]
///
/// This test verifies the basic behavior of visitors, with an emphasis on
/// {@link AbstractParseTreeVisitor#visitTerminal}.

View File

@ -0,0 +1,13 @@
#if os(Linux)
import XCTest
@testable import Antlr4Tests
XCTMain([
// Antlr4Tests
testCase(TokenStreamTests.allTests),
testCase(TokenStreamRewriterTests.allTests),
testCase(VisitorTests.allTests)
])
#endif