Merge pull request #2032 from ewanmellor/swift-4

Migrate the Swift runtime to Swift 4.
This commit is contained in:
Terence Parr 2017-10-21 12:26:29 -07:00 committed by GitHub
commit c9c7561701
28 changed files with 293 additions and 414 deletions

View File

@ -2,6 +2,16 @@ sudo: true
language: java language: java
cache:
directories:
- $HOME/.m2
- $HOME/Library/Caches/Homebrew
stages:
- smoke-test
- main-test
- extended-test
matrix: matrix:
include: include:
- os: linux - os: linux
@ -10,22 +20,8 @@ matrix:
env: env:
- TARGET=cpp - TARGET=cpp
- CXX=g++-5 - CXX=g++-5
- GROUP=ALL
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- g++-5
- uuid-dev
- clang-3.7
- os: osx
compiler: clang
osx_image: xcode8.1
env:
- TARGET=cpp
- GROUP=LEXER - GROUP=LEXER
stage: main-test
addons: addons:
apt: apt:
sources: sources:
@ -35,104 +31,148 @@ matrix:
- g++-5 - g++-5
- uuid-dev - uuid-dev
- clang-3.7 - clang-3.7
- os: osx
compiler: clang
osx_image: xcode8.1
env:
- TARGET=cpp
- GROUP=PARSER
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- g++-5
- uuid-dev
- clang-3.7
- os: osx
compiler: clang
osx_image: xcode8.1
env:
- TARGET=cpp
- GROUP=RECURSION
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- g++-5
- uuid-dev
- clang-3.7
- os: osx
compiler: clang
osx_image: xcode8.1
env:
- TARGET=swift
- GROUP=LEXER
- os: osx
compiler: clang
osx_image: xcode8.1
env:
- TARGET=swift
- GROUP=PARSER
- os: osx
compiler: clang
osx_image: xcode8.1
env:
- TARGET=swift
- GROUP=RECURSION
- os: linux - os: linux
compiler: clang
jdk: openjdk7
env:
- TARGET=cpp
- CXX=g++-5
- GROUP=PARSER
stage: main-test
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- g++-5
- uuid-dev
- clang-3.7
- os: linux
compiler: clang
jdk: openjdk7
env:
- TARGET=cpp
- CXX=g++-5
- GROUP=RECURSION
stage: main-test
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- g++-5
- uuid-dev
- clang-3.7
- os: osx
compiler: clang
osx_image: xcode9
env:
- TARGET=cpp
- GROUP=LEXER
stage: extended-test
- os: osx
compiler: clang
osx_image: xcode9
env:
- TARGET=cpp
- GROUP=PARSER
stage: extended-test
- os: osx
compiler: clang
osx_image: xcode9
env:
- TARGET=cpp
- GROUP=RECURSION
stage: extended-test
- os: osx
compiler: clang
osx_image: xcode9
env:
- TARGET=swift
- GROUP=LEXER
stage: main-test
- os: osx
compiler: clang
osx_image: xcode9
env:
- TARGET=swift
- GROUP=PARSER
stage: main-test
- os: osx
compiler: clang
osx_image: xcode9
env:
- TARGET=swift
- GROUP=RECURSION
stage: main-test
- os: linux
dist: trusty
compiler: clang compiler: clang
env: env:
- TARGET=swift - TARGET=swift
- GROUP=ALL - GROUP=ALL
stage: extended-test
- os: osx - os: osx
osx_image: xcode8.2 osx_image: xcode9
env: env:
- TARGET=dotnet - TARGET=dotnet
- GROUP=LEXER - GROUP=LEXER
stage: extended-test
- os: osx - os: osx
osx_image: xcode8.2 osx_image: xcode9
env: env:
- TARGET=dotnet - TARGET=dotnet
- GROUP=PARSER - GROUP=PARSER
stage: extended-test
- os: osx - os: osx
osx_image: xcode8.2 osx_image: xcode9
env: env:
- TARGET=dotnet - TARGET=dotnet
- GROUP=RECURSION - GROUP=RECURSION
stage: extended-test
- os: linux - os: linux
jdk: openjdk7 jdk: openjdk7
env: TARGET=java env: TARGET=java
stage: extended-test
- os: linux
jdk: openjdk8
env: TARGET=java
stage: extended-test
- os: linux - os: linux
jdk: oraclejdk8 jdk: oraclejdk8
env: TARGET=java env: TARGET=java
stage: smoke-test
- os: linux - os: linux
jdk: openjdk7 jdk: openjdk7
env: TARGET=csharp env: TARGET=csharp
stage: extended-test
- os: linux - os: linux
jdk: oraclejdk8 jdk: oraclejdk8
dist: trusty dist: trusty
env: env:
- TARGET=dotnet - TARGET=dotnet
- GROUP=LEXER - GROUP=LEXER
stage: main-test
- os: linux - os: linux
jdk: oraclejdk8 jdk: openjdk8
dist: trusty dist: trusty
env: env:
- TARGET=dotnet - TARGET=dotnet
- GROUP=PARSER - GROUP=PARSER
stage: main-test
- os: linux - os: linux
jdk: oraclejdk8 jdk: oraclejdk8
dist: trusty dist: trusty
env: env:
- TARGET=dotnet - TARGET=dotnet
- GROUP=RECURSION - GROUP=RECURSION
stage: main-test
- os: linux - os: linux
jdk: openjdk7 jdk: openjdk7
env: TARGET=python2 env: TARGET=python2
stage: extended-test
- os: linux - os: linux
jdk: openjdk7 jdk: openjdk7
env: TARGET=python3 env: TARGET=python3
@ -142,15 +182,20 @@ matrix:
- deadsnakes # source required so it finds the package definition below - deadsnakes # source required so it finds the package definition below
packages: packages:
- python3.5 - python3.5
stage: main-test
- os: linux - os: linux
jdk: openjdk7 dist: trusty
jdk: openjdk8
env: TARGET=javascript env: TARGET=javascript
stage: main-test
- os: linux - os: linux
jdk: openjdk7 dist: trusty
jdk: openjdk8
env: TARGET=go env: TARGET=go
stage: main-test
before_install: before_install:
- ./.travis/before-install-$TRAVIS_OS_NAME-$TARGET.sh - f="./.travis/before-install-$TRAVIS_OS_NAME-$TARGET.sh"; ! [ -x "$f" ] || "$f"
script: script:
- cd runtime-testsuite; ../.travis/run-tests-$TARGET.sh - cd runtime-testsuite; travis_wait 40 ../.travis/run-tests-$TARGET.sh

View File

@ -1,14 +1,12 @@
set -euo pipefail set -euo pipefail
# make sure we use trusty repositories (travis by default uses precise)
curl https://repogen.simplylinux.ch/txt/trusty/sources_c4aa56bd26c0f54f391d8fae3e687ef5f6e97c26.txt | sudo tee /etc/apt/sources.list
# install dependencies # install dependencies
# some packages below will be update, swift assumes newer versions # some packages below will be update, swift assumes newer versions
# of, for example, sqlite3 and libicu, without the update some # of, for example, sqlite3 and libicu, without the update some
# tools will not work # tools will not work
sudo apt-get update sudo apt-get update
sudo apt-get install clang libicu-dev libxml2 sqlite3 sudo apt-get install clang-3.6 libxml2
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100
# This would fix a know linker issue mentioned in: # This would fix a know linker issue mentioned in:
# https://bugs.swift.org/browse/SR-2299 # https://bugs.swift.org/browse/SR-2299

View File

@ -1,13 +0,0 @@
#!/bin/bash
set -euo pipefail
thisdir=$(dirname "$0")
brew update
brew install cmake
# Work around apparent rvm bug that is in Travis's Xcode image.
# https://github.com/direnv/direnv/issues/210
# https://github.com/travis-ci/travis-ci/issues/6307
shell_session_update() { :; }

View File

@ -4,9 +4,7 @@ set -euo pipefail
thisdir=$(dirname "$0") thisdir=$(dirname "$0")
# pre-requisites for dotnet core # OpenSSL setup for dotnet core
brew update
brew install openssl
mkdir -p /usr/local/lib mkdir -p /usr/local/lib
ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/ ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/
ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/ ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
@ -19,9 +17,3 @@ sudo installer -pkg /tmp/dotnet-dev-osx-x64.1.0.4.pkg -target /
# make the link # make the link
ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/ ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/
# Work around apparent rvm bug that is in Travis's Xcode image.
# https://github.com/direnv/direnv/issues/210
# https://github.com/travis-ci/travis-ci/issues/6307
shell_session_update() { :; }

View File

@ -1,12 +0,0 @@
#!/bin/bash
set -euo pipefail
thisdir=$(dirname "$0")
brew update
# Work around apparent rvm bug that is in Travis's Xcode image.
# https://github.com/direnv/direnv/issues/210
# https://github.com/travis-ci/travis-ci/issues/6307
shell_session_update() { :; }

View File

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

View File

@ -23,60 +23,83 @@ $ antlr4 -Dlanguage=Swift MyGrammar.g4
For a full list of antlr4 tool options, please visit the For a full list of antlr4 tool options, please visit the
[tool documentation page](tool-options.md). [tool documentation page](tool-options.md).
## Build your Swift project with ANTLR runtime ## Build your Swift project with ANTLR runtime
The following instructions are assuming Xcode as the IDE: The following instructions assume Xcode as the IDE.
* __Add parser/lexer to project__. Make sure the parsers/lexers Note that even if you are otherwise using ANTLR from a binary distribution,
you should compile the ANTLR Swift runtime from source, because the Swift
language does not yet have a stable ABI.
ANTLR uses Swift Package Manager to generate Xcode project files. Note that
Swift Package Manager does not currently support iOS, watchOS, or tvOS, so
if you wish to use those platforms, you will need to alter the project build
settings manually as appropriate.
### Download source code for ANTLR
```
git clone https://github.com/antlr/antlr4
```
### Generate Xcode project for ANTLR runtime
The `boot.py` script includes a wrapper around `swift package
generate-xcodeproj`. Use this to generate `Antlr4.xcodeproj` for the ANTLR
Swift runtime.
```
cd antlr4/runtime/Swift
python boot.py --gen-xcodeproj
```
### Import ANTLR Swift runtime into your project
Open your own project in Xcode.
Open Finder in the `runtime/Swift` directory:
```
# From antlr4/runtime/Swift
open .
```
Drag `Antlr4.xcodeproj` into your project.
After this is done, your Xcode project navigator will be something like the
screenshot below. In this example, your own project is "Smalltalk", and you
will be able to see `Antlr4.xcodeproj` shown as a contained project.
<img src=images/xcodenav.png width="300">
### Edit the build settings if necessary
Swift Package Manager currently does not support iOS, watchOS, or tvOS. If
you wish to build for those platforms, you will need to alter the project
build settings manually.
### Add generated parser and lexer to project
Make sure the parsers/lexers
generated in __step 2__ are added to the project. To do this, you can generated in __step 2__ are added to the project. To do this, you can
drag the generated files from Finder to the Xcode IDE. Remember to drag the generated files from Finder to the Xcode IDE. Remember to
check __Copy items if needed__ to make sure the files are actually check __Copy items if needed__ to make sure the files are actually
moved into the project folder instead of symbolic links (see the moved into the project folder instead of symbolic links (see the
screenshot below). After moving you will be able to see your files in screenshot below). After moving you will be able to see your files in
the project navigator. But when you open one of the files, you will the project navigator. Make sure that the Target Membership settings
see Xcode complaining the module "Antlr4" could not be found at the are correct for your project.
import statement. This is expected, since we still need the ANTLR
Swift runtime for those missing symbols.
<img src=images/dragfile.png width="500"> <img src=images/dragfile.png width="500">
* __Download ANTLR runtime__. Due to unstable ABI of Swift language, ### Add the ANTLR Swift runtime as a dependency
there will not be a single "library" for the Swift ANTLR runtime for
now. To get Swift ANTLR runtime, clone the ANTLR repository. Open it
in finder. From the root directory of the repo, go to runtime/Swift
folder. You will see the Xcode project manifest file:
__Antlr4.xcodeproj__.
* __Import ANTLR Swift runtime into project__. Drag Antlr4.xcodeproj Select your own project in Xcode and go to the Build Phases settings panel.
into your project, after this is done, your Xcode project navigator Add the ANTLR runtime under __Target Dependencies__ and __Link Binary With
will be something like the screenshot below. In this case, your own Libraries__.
project is "Smalltalk", and you will be able to see the
Antlr4.xcodeproj shown as a contained project. The error message will
still be there, that's because we still need to tell Xcode how to find
the runtime.
<img src=images/xcodenav.png width="300"> <img src=images/xcodedep.png width="800">
* __Build ANTLR runtime__. By expanding the "Products" folder in the ### Build your project
inner project (Antlr4.xcodeproj), you will see two Antlr4.framework
files. ".framework" file is the swift version of ".jar", ".a" as in
JAVA, C/C++ Initially those two files should be red, that's because
they are not built. To build, click the "target selection" button
right next to your Xcode run button. And in the drop down select the
target you want to build. And you will see the two Antlr4.framework
files are for iOS and OSX, as shown below. After target selection,
press "CMD+B", and Xcode will build the framework for you. Then you
will see one of the frameworks become black.
<img src=images/targetselection.png width="500"> The runtime and generated grammar should now build correctly.
* __Add dependencies__. Simply adding ANTLR Swift runtime and build
the artifact is not enough. You still need to specify
dependencies. Click your own project (Smalltalk), and you will see
project setting page. Go to "Build Phase", and inside it make sure
your ANTLR Swift runtime framework is added to both "__Target
Dependencies__" and "__Link Binary With Libraries__" sections, as
shown below. After correctly added dependencies, the error message for
importing library will be gone.
<img src=images/xcodedep.png width="800">

View File

@ -145,7 +145,7 @@ public class BaseSwiftTest implements RuntimeTestSupport {
String projectName = "testcase-" + System.currentTimeMillis(); String projectName = "testcase-" + System.currentTimeMillis();
String projectDir = getTmpDir() + "/" + projectName; String projectDir = getTmpDir() + "/" + projectName;
buildProject(projectDir); buildProject(projectDir, projectName);
return execTest(projectDir, projectName); return execTest(projectDir, projectName);
} }
@ -183,12 +183,12 @@ public class BaseSwiftTest implements RuntimeTestSupport {
Collections.addAll(this.sourceFiles, files); Collections.addAll(this.sourceFiles, files);
} }
private void buildProject(String projectDir) { private void buildProject(String projectDir, String projectName) {
mkdir(projectDir); mkdir(projectDir);
fastFailRunProcess(projectDir, SWIFT_CMD, "package", "init", "--type", "executable"); fastFailRunProcess(projectDir, SWIFT_CMD, "package", "init", "--type", "executable");
for (String sourceFile: sourceFiles) { for (String sourceFile: sourceFiles) {
String absPath = getTmpDir() + "/" + sourceFile; String absPath = getTmpDir() + "/" + sourceFile;
fastFailRunProcess(getTmpDir(), "mv", "-f", absPath, projectDir + "/Sources/"); fastFailRunProcess(getTmpDir(), "mv", "-f", absPath, projectDir + "/Sources/" + projectName);
} }
fastFailRunProcess(getTmpDir(), "mv", "-f", "input", projectDir); fastFailRunProcess(getTmpDir(), "mv", "-f", "input", projectDir);
@ -201,7 +201,7 @@ public class BaseSwiftTest implements RuntimeTestSupport {
"-Xlinker", "-rpath", "-Xlinker", "-rpath",
"-Xlinker", dylibPath); "-Xlinker", dylibPath);
if (buildResult.b.length() > 0) { if (buildResult.b.length() > 0) {
throw new RuntimeException("unit test build failed: " + buildResult.b); throw new RuntimeException("unit test build failed: " + buildResult.a + "\n" + buildResult.b);
} }
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
@ -251,7 +251,7 @@ public class BaseSwiftTest implements RuntimeTestSupport {
addSourceFiles("main.swift"); addSourceFiles("main.swift");
String projectName = "testcase-" + System.currentTimeMillis(); String projectName = "testcase-" + System.currentTimeMillis();
String projectDir = getTmpDir() + "/" + projectName; String projectDir = getTmpDir() + "/" + projectName;
buildProject(projectDir); buildProject(projectDir, projectName);
return execTest(projectDir, projectName); return execTest(projectDir, projectName);
} }

View File

@ -1 +1,4 @@
.build/
Antlr4.xcodeproj/
Tests/Antlr4Tests/gen/
xcuserdata/ xcuserdata/

View File

@ -1,3 +1,4 @@
// swift-tools-version:4.0
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. // Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
// Use of this file is governed by the BSD 3-clause license that // 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. // can be found in the LICENSE.txt file in the project root.
@ -5,15 +6,19 @@
import PackageDescription import PackageDescription
let package = Package( let package = Package(
name: "Antlr4" name: "Antlr4",
) products: [
.library(
products.append( name: "Antlr4",
Product( type: .dynamic,
name: "Antlr4", targets: ["Antlr4"]),
type: .Library(.Dynamic), ],
modules: [ targets: [
"Antlr4" .target(
] name: "Antlr4",
) dependencies: []),
.testTarget(
name: "Antlr4Tests",
dependencies: ["Antlr4"]),
]
) )

View File

@ -39,12 +39,12 @@ public protocol ANTLRErrorListener: class {
/// the parser was able to recover in line without exiting the /// the parser was able to recover in line without exiting the
/// surrounding rule. /// surrounding rule.
/// ///
func syntaxError<T:ATNSimulator>(_ recognizer: Recognizer<T>, func syntaxError<T>(_ recognizer: Recognizer<T>,
_ offendingSymbol: AnyObject?, _ offendingSymbol: AnyObject?,
_ line: Int, _ line: Int,
_ charPositionInLine: Int, _ charPositionInLine: Int,
_ msg: String, _ msg: String,
_ e: AnyObject? _ e: AnyObject?
) )
/// ///

View File

@ -17,12 +17,12 @@ open class BaseErrorListener: ANTLRErrorListener {
public init() { public init() {
} }
open func syntaxError<T:ATNSimulator>(_ recognizer: Recognizer<T>, open func syntaxError<T>(_ recognizer: Recognizer<T>,
_ offendingSymbol: AnyObject?, _ offendingSymbol: AnyObject?,
_ line: Int, _ line: Int,
_ charPositionInLine: Int, _ charPositionInLine: Int,
_ msg: String, _ msg: String,
_ e: AnyObject? _ e: AnyObject?
) { ) {
} }

View File

@ -25,12 +25,12 @@ public class ConsoleErrorListener: BaseErrorListener {
/// line __line__:__charPositionInLine__ __msg__ /// line __line__:__charPositionInLine__ __msg__
/// ///
/// ///
override public func syntaxError<T:ATNSimulator>(_ recognizer: Recognizer<T>, override public func syntaxError<T>(_ recognizer: Recognizer<T>,
_ offendingSymbol: AnyObject?, _ offendingSymbol: AnyObject?,
_ line: Int, _ line: Int,
_ charPositionInLine: Int, _ charPositionInLine: Int,
_ msg: String, _ msg: String,
_ e: AnyObject? _ e: AnyObject?
) { ) {
if Parser.ConsoleError { if Parser.ConsoleError {
errPrint("line \(line):\(charPositionInLine) \(msg)") errPrint("line \(line):\(charPositionInLine) \(msg)")

View File

@ -405,7 +405,7 @@ open class Lexer: Recognizer<LexerATNSimulator>
} }
} }
open func notifyListeners<T:ATNSimulator>(_ e: LexerNoViableAltException, recognizer: Recognizer<T>) { open func notifyListeners<T>(_ e: LexerNoViableAltException, recognizer: Recognizer<T>) {
let text: String = _input!.getText(Interval.of(_tokenStartCharIndex, _input!.index())) let text: String = _input!.getText(Interval.of(_tokenStartCharIndex, _input!.index()))
let msg: String = "token recognition error at: '\(getErrorDisplay(text))'" let msg: String = "token recognition error at: '\(getErrorDisplay(text))'"

View File

@ -20,13 +20,13 @@ public class ProxyErrorListener: ANTLRErrorListener {
self.delegates = delegates self.delegates = delegates
} }
public func syntaxError<T:ATNSimulator>(_ recognizer: Recognizer<T>, public func syntaxError<T>(_ recognizer: Recognizer<T>,
_ offendingSymbol: AnyObject?, _ offendingSymbol: AnyObject?,
_ line: Int, _ line: Int,
_ charPositionInLine: Int, _ charPositionInLine: Int,
_ msg: String, _ msg: String,
_ e: AnyObject?) _ e: AnyObject?)
{ {
for listener: ANTLRErrorListener in delegates { for listener: ANTLRErrorListener in delegates {
listener.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e) listener.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e)
} }

View File

@ -233,7 +233,7 @@ open class RuleContext: RuleNode {
return description return description
} }
public final func toString<T:ATNSimulator>(_ recog: Recognizer<T>) -> String { public final func toString<T>(_ recog: Recognizer<T>) -> String {
return toString(recog, ParserRuleContext.EMPTY) return toString(recog, ParserRuleContext.EMPTY)
} }
@ -242,7 +242,7 @@ open class RuleContext: RuleNode {
} }
// recog null unless ParserRuleContext, in which case we use subclass toString(...) // recog null unless ParserRuleContext, in which case we use subclass toString(...)
open func toString<T:ATNSimulator>(_ recog: Recognizer<T>?, _ stop: RuleContext) -> String { open func toString<T>(_ recog: Recognizer<T>?, _ stop: RuleContext) -> String {
let ruleNames: [String]? = recog != nil ? recog!.getRuleNames() : nil let ruleNames: [String]? = recog != nil ? recog!.getRuleNames() : nil
let ruleNamesList: Array<String>? = ruleNames ?? nil let ruleNamesList: Array<String>? = ruleNames ?? nil
return toString(ruleNamesList, stop) return toString(ruleNamesList, stop)

View File

@ -167,7 +167,7 @@ public class ATNConfig: Hashable, CustomStringConvertible {
//return "MyClass \(string)" //return "MyClass \(string)"
return toString(nil, true) return toString(nil, true)
} }
public func toString<T:ATNSimulator>(_ recog: Recognizer<T>?, _ showAlt: Bool) -> String { public func toString<T>(_ recog: Recognizer<T>?, _ showAlt: Bool) -> String {
let buf: StringBuilder = StringBuilder() let buf: StringBuilder = StringBuilder()
buf.append("(") buf.append("(")
buf.append(state) buf.append(state)

View File

@ -238,12 +238,9 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
private var configsHashValue: Int { private var configsHashValue: Int {
var hashCode = 1 var hashCode = 1
for item in configs { for item in configs {
hashCode = Int.multiplyWithOverflow(3, hashCode).0 hashCode = hashCode &* 3 &+ item.hashValue
hashCode = Int.addWithOverflow(hashCode, item.hashValue).0
} }
return hashCode return hashCode
} }
public final var count: Int { public final var count: Int {

View File

@ -175,7 +175,7 @@ public class ATNDeserializer {
if let s = s as? BlockStartState { if let s = s as? BlockStartState {
let endStateNumber: Int = toInt(data[p]) let endStateNumber: Int = toInt(data[p])
p += 1 p += 1
endStateNumbers.append(s, endStateNumber) endStateNumbers.append((s, endStateNumber))
} }
} }
atn.addState(s) atn.addState(s)

View File

@ -712,17 +712,17 @@ public class PredictionContext: Hashable, CustomStringConvertible {
} }
} }
public func toString<T:ATNSimulator>(_ recog: Recognizer<T>) -> String { public func toString<T>(_ recog: Recognizer<T>) -> String {
return NSStringFromClass(PredictionContext.self) return NSStringFromClass(PredictionContext.self)
// return toString(recog, ParserRuleContext.EMPTY); // return toString(recog, ParserRuleContext.EMPTY);
} }
public func toStrings<T:ATNSimulator>(_ recognizer: Recognizer<T>, _ currentState: Int) -> [String] { public func toStrings<T>(_ recognizer: Recognizer<T>, _ currentState: Int) -> [String] {
return toStrings(recognizer, PredictionContext.EMPTY, currentState) return toStrings(recognizer, PredictionContext.EMPTY, currentState)
} }
// FROM SAM // FROM SAM
public func toStrings<T:ATNSimulator>(_ recognizer: Recognizer<T>?, _ stop: PredictionContext, _ currentState: Int) -> [String] { public func toStrings<T>(_ recognizer: Recognizer<T>?, _ stop: PredictionContext, _ currentState: Int) -> [String] {
var result: Array<String> = Array<String>() var result: Array<String> = Array<String>()
var perm: Int = 0 var perm: Int = 0
outer: while true { outer: while true {

View File

@ -37,7 +37,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
/// prediction, so we passed in the outer context here in case of context /// prediction, so we passed in the outer context here in case of context
/// dependent predicate evaluation. /// dependent predicate evaluation.
/// ///
public func eval<T:ATNSimulator>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool { public func eval<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool {
RuntimeException(#function + " must be overridden") RuntimeException(#function + " must be overridden")
return false return false
} }
@ -58,7 +58,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
/// * A non-`null` _org.antlr.v4.runtime.atn.SemanticContext_: the new simplified /// * A non-`null` _org.antlr.v4.runtime.atn.SemanticContext_: the new simplified
/// semantic context after precedence predicates are evaluated. /// semantic context after precedence predicates are evaluated.
/// ///
public func evalPrecedence<T:ATNSimulator>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> SemanticContext? { public func evalPrecedence<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> SemanticContext? {
return self return self
} }
public var hashValue: Int { public var hashValue: Int {
@ -90,7 +90,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
} }
override override
public func eval<T:ATNSimulator>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool { public func eval<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool {
let localctx: RuleContext? = isCtxDependent ? parserCallStack : nil let localctx: RuleContext? = isCtxDependent ? parserCallStack : nil
return try parser.sempred(localctx, ruleIndex, predIndex) return try parser.sempred(localctx, ruleIndex, predIndex)
} }
@ -126,12 +126,12 @@ public class SemanticContext: Hashable, CustomStringConvertible {
} }
override override
public func eval<T:ATNSimulator>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool { public func eval<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool {
return try parser.precpred(parserCallStack, precedence) return try parser.precpred(parserCallStack, precedence)
} }
override override
public func evalPrecedence<T:ATNSimulator>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> SemanticContext? { public func evalPrecedence<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> SemanticContext? {
if try parser.precpred(parserCallStack, precedence) { if try parser.precpred(parserCallStack, precedence) {
return SemanticContext.NONE return SemanticContext.NONE
} else { } else {
@ -187,31 +187,28 @@ public class SemanticContext: Hashable, CustomStringConvertible {
public init(_ a: SemanticContext, _ b: SemanticContext) { public init(_ a: SemanticContext, _ b: SemanticContext) {
var operands: Set<SemanticContext> = Set<SemanticContext>() var operands: Set<SemanticContext> = Set<SemanticContext>()
if a is AND { if let aAnd = a as? AND {
operands.formUnion((a as! AND).opnds) operands.formUnion(aAnd.opnds)
//operands.addAll(Arrays.asList((a as AND).opnds));
} else { } else {
operands.insert(a) operands.insert(a)
} }
if b is AND { if let bAnd = b as? AND {
operands.formUnion((b as! AND).opnds) operands.formUnion(bAnd.opnds)
//operands.addAll(Arrays.asList((b as AND).opnds));
} else { } else {
operands.insert(b) operands.insert(b)
} }
let precedencePredicates: Array<PrecedencePredicate> = let precedencePredicates = SemanticContext.filterPrecedencePredicates(&operands)
SemanticContext.filterPrecedencePredicates(&operands)
if !precedencePredicates.isEmpty { if !precedencePredicates.isEmpty {
// interested in the transition with the lowest precedence // interested in the transition with the lowest precedence
let reduced: PrecedencePredicate = precedencePredicates.sorted { let reduced = precedencePredicates.sorted {
$0.precedence < $1.precedence $0.precedence < $1.precedence
}.first! //Collections.min(precedencePredicates); }
operands.insert(reduced) operands.insert(reduced[0])
} }
opnds = Array(operands) //.toArray(new, SemanticContext[operands.size()]); opnds = Array(operands)
} }
override override
@ -236,7 +233,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
/// unordered. /// unordered.
/// ///
override override
public func eval<T:ATNSimulator>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool { public func eval<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool {
for opnd: SemanticContext in opnds { for opnd: SemanticContext in opnds {
if try !opnd.eval(parser, parserCallStack) { if try !opnd.eval(parser, parserCallStack) {
return false return false
@ -246,7 +243,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
} }
override override
public func evalPrecedence<T:ATNSimulator>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> SemanticContext? { public func evalPrecedence<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> SemanticContext? {
var differs: Bool = false var differs: Bool = false
var operands: Array<SemanticContext> = Array<SemanticContext>() var operands: Array<SemanticContext> = Array<SemanticContext>()
for context: SemanticContext in opnds { for context: SemanticContext in opnds {
@ -305,30 +302,28 @@ public class SemanticContext: Hashable, CustomStringConvertible {
public init(_ a: SemanticContext, _ b: SemanticContext) { public init(_ a: SemanticContext, _ b: SemanticContext) {
var operands: Set<SemanticContext> = Set<SemanticContext>() var operands: Set<SemanticContext> = Set<SemanticContext>()
if a is OR { if let aOr = a as? OR {
operands.formUnion((a as! OR).opnds) operands.formUnion(aOr.opnds)
// operands.addAll(Arrays.asList((a as OR).opnds));
} else { } else {
operands.insert(a) operands.insert(a)
} }
if b is OR { if let bOr = b as? OR {
operands.formUnion((b as! OR).opnds) operands.formUnion(bOr.opnds)
//operands.addAll(Arrays.asList((b as OR).opnds));
} else { } else {
operands.insert(b) operands.insert(b)
} }
let precedencePredicates: Array<PrecedencePredicate> = SemanticContext.filterPrecedencePredicates(&operands) let precedencePredicates = SemanticContext.filterPrecedencePredicates(&operands)
if !precedencePredicates.isEmpty { if !precedencePredicates.isEmpty {
// interested in the transition with the highest precedence // interested in the transition with the highest precedence
let reduced: PrecedencePredicate = precedencePredicates.sorted {
let reduced = precedencePredicates.sorted {
$0.precedence > $1.precedence $0.precedence > $1.precedence
}.first! }
//var reduced : PrecedencePredicate = Collections.max(precedencePredicates); operands.insert(reduced[0])
operands.insert(reduced)
} }
self.opnds = Array(operands) //operands.toArray(new, SemanticContext[operands.size()]); self.opnds = Array(operands)
} }
override override
@ -351,7 +346,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
/// unordered. /// unordered.
/// ///
override override
public func eval<T:ATNSimulator>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool { public func eval<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool {
for opnd: SemanticContext in opnds { for opnd: SemanticContext in opnds {
if try opnd.eval(parser, parserCallStack) { if try opnd.eval(parser, parserCallStack) {
return true return true
@ -361,7 +356,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
} }
override override
public func evalPrecedence<T:ATNSimulator>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> SemanticContext? { public func evalPrecedence<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> SemanticContext? {
var differs: Bool = false var differs: Bool = false
var operands: Array<SemanticContext> = Array<SemanticContext>() var operands: Array<SemanticContext> = Array<SemanticContext>()
for context: SemanticContext in opnds { for context: SemanticContext in opnds {
@ -447,21 +442,14 @@ public class SemanticContext: Hashable, CustomStringConvertible {
return result return result
} }
private static func filterPrecedencePredicates( private static func filterPrecedencePredicates(_ collection: inout Set<SemanticContext>) -> [PrecedencePredicate] {
_ collection: inout Set<SemanticContext>) -> let result = collection.flatMap {
Array<PrecedencePredicate> { $0 as? PrecedencePredicate
let result = collection.filter {
$0 is PrecedencePredicate
} }
collection = Set<SemanticContext>(collection.filter { collection = Set<SemanticContext>(collection.filter {
!($0 is PrecedencePredicate) !($0 is PrecedencePredicate)
}) })
//if (result == nil) { return result
//return Array<PrecedencePredicate>();
//}
return (result as! Array<PrecedencePredicate>)
} }
} }

View File

@ -69,7 +69,7 @@ public final class ArrayWrapper<T: Hashable>: ExpressibleByArrayLiteral, Hashabl
} }
public func == <Element: Equatable>(lhs: ArrayWrapper<Element>, rhs: ArrayWrapper<Element>) -> Bool { public func == <Element>(lhs: ArrayWrapper<Element>, rhs: ArrayWrapper<Element>) -> Bool {
if lhs === rhs { if lhs === rhs {
return true return true
} }

View File

@ -644,12 +644,12 @@ public class BitSet: Hashable, CustomStringConvertible {
return 64 return 64
} }
var n: Int32 = 63 var n: Int32 = 63
y = Int32(truncatingBitPattern: i) y = Int32(truncatingIfNeeded: i)
if y != 0 { if y != 0 {
n = n - 32 n = n - 32
x = y x = y
} else { } else {
x = Int32(truncatingBitPattern: i >>> 32) x = Int32(truncatingIfNeeded: i >>> 32)
} }
y = x << 16 y = x << 16

View File

@ -41,7 +41,7 @@ final class Entry<K: Hashable,V>: CustomStringConvertible {
var description: String { return "\(getKey())=\(getValue())" } var description: String { return "\(getKey())=\(getValue())" }
} }
func == <K: Hashable, V: Equatable>(lhs: Entry<K,V>, rhs: Entry<K,V>) -> Bool { func == <K, V: Equatable>(lhs: Entry<K,V>, rhs: Entry<K,V>) -> Bool {
if lhs === rhs { if lhs === rhs {
return true return true
} }
@ -52,7 +52,7 @@ func == <K: Hashable, V: Equatable>(lhs: Entry<K,V>, rhs: Entry<K,V>) -> Bool {
} }
return false return false
} }
func == <K: Hashable, V: Equatable>(lhs: Entry<K,V?>, rhs: Entry<K,V?>) -> Bool { func == <K, V: Equatable>(lhs: Entry<K,V?>, rhs: Entry<K,V?>) -> Bool {
if lhs === rhs { if lhs === rhs {
return true return true
} }

View File

@ -49,19 +49,19 @@ public final class MurmurHash {
let m: Int32 = 5 let m: Int32 = 5
let n: Int32 = -430675100//0xE6546B64; let n: Int32 = -430675100//0xE6546B64;
var k: Int32 = Int32(truncatingBitPattern: value) var k: Int32 = Int32(truncatingIfNeeded: value)
k = Int32.multiplyWithOverflow(k, c1).0 k = k.multipliedReportingOverflow(by: c1).partialValue
// (k,_) = UInt32.multiplyWithOverflow(k, c1) ;//( k * c1); // (k,_) = UInt32.multiplyWithOverflow(k, c1) ;//( k * c1);
//TODO: CHECKE >>> //TODO: CHECKE >>>
k = (k << r1) | (k >>> (Int32(32) - r1)) //k = (k << r1) | (k >>> (32 - r1)); k = (k << r1) | (k >>> (Int32(32) - r1)) //k = (k << r1) | (k >>> (32 - r1));
//k = UInt32 (truncatingBitPattern:Int64(Int64(k) * Int64(c2)));//( k * c2); //k = UInt32 (truncatingBitPattern:Int64(Int64(k) * Int64(c2)));//( k * c2);
//(k,_) = UInt32.multiplyWithOverflow(k, c2) //(k,_) = UInt32.multiplyWithOverflow(k, c2)
k = Int32.multiplyWithOverflow(k, c2).0 k = k.multipliedReportingOverflow(by: c2).partialValue
var hash = Int32(hashIn) var hash = Int32(hashIn)
hash = hash ^ k hash = hash ^ k
hash = (hash << r2) | (hash >>> (Int32(32) - r2))//hash = (hash << r2) | (hash >>> (32 - r2)); hash = (hash << r2) | (hash >>> (Int32(32) - r2))//hash = (hash << r2) | (hash >>> (32 - r2));
(hash, _) = Int32.multiplyWithOverflow(hash, m) hash = hash.multipliedReportingOverflow(by: m).partialValue
(hash, _) = Int32.addWithOverflow(hash, n) hash = hash.addingReportingOverflow(n).partialValue
//hash = hash * m + n; //hash = hash * m + n;
// print("murmur update2 : \(hash)") // print("murmur update2 : \(hash)")
return Int(hash) return Int(hash)
@ -90,12 +90,12 @@ public final class MurmurHash {
public static func finish(_ hashin: Int, _ numberOfWordsIn: Int) -> Int { public static func finish(_ hashin: Int, _ numberOfWordsIn: Int) -> Int {
var hash = Int32(hashin) var hash = Int32(hashin)
let numberOfWords = Int32(numberOfWordsIn) let numberOfWords = Int32(numberOfWordsIn)
hash = hash ^ Int32.multiplyWithOverflow(numberOfWords, Int32(4)).0 //(numberOfWords * UInt32(4)); hash = hash ^ numberOfWords.multipliedReportingOverflow(by: 4).partialValue //(numberOfWords * UInt32(4));
hash = hash ^ (hash >>> Int32(16)) //hash = hash ^ (hash >>> 16); hash = hash ^ (hash >>> Int32(16)) //hash = hash ^ (hash >>> 16);
(hash, _) = Int32.multiplyWithOverflow(hash, Int32(-2048144789))//hash * UInt32(0x85EBCA6B); hash = hash.multipliedReportingOverflow(by: -2048144789).partialValue //hash * UInt32(0x85EBCA6B);
hash = hash ^ (hash >>> Int32(13))//hash = hash ^ (hash >>> 13); hash = hash ^ (hash >>> Int32(13))//hash = hash ^ (hash >>> 13);
//hash = UInt32(truncatingBitPattern: UInt64(hash) * UInt64(0xC2B2AE35)) ; //hash = UInt32(truncatingBitPattern: UInt64(hash) * UInt64(0xC2B2AE35)) ;
(hash, _) = Int32.multiplyWithOverflow(hash, Int32(-1028477387)) hash = hash.multipliedReportingOverflow(by: -1028477387).partialValue
hash = hash ^ (hash >>> Int32(16))// hash = hash ^ (hash >>> 16); hash = hash ^ (hash >>> Int32(16))// hash = hash ^ (hash >>> 16);
//print("murmur finish : \(hash)") //print("murmur finish : \(hash)")
return Int(hash) return Int(hash)

View File

@ -11,14 +11,6 @@ import Foundation
extension String { extension String {
func split(_ separator: String) -> [String] {
return self.components(separatedBy: separator)
}
func containsIgnoreCase(_ find: String) -> Bool {
return self.lowercased().range(of: find.lowercased()) != nil
}
var length: Int { var length: Int {
return self.characters.count return self.characters.count
} }
@ -60,32 +52,6 @@ extension String {
return index return index
} }
func substringAfter(_ string: String) -> String {
if let range = self.range(of: string) {
let intIndex: Int = self.characters.distance(from: self.startIndex, to: range.upperBound)
return self.substring(from: self.characters.index(self.startIndex, offsetBy: intIndex))
}
return self
}
var lowercaseFirstChar: String {
var result = self
if self.length > 0 {
let startIndex = self.startIndex
result.replaceSubrange(startIndex ... startIndex, with: String(self[startIndex]).lowercased())
}
return result
}
func substringWithRange(_ range: Range<Int>) -> String {
let start = self.characters.index(self.startIndex, offsetBy: range.lowerBound)
let end = self.characters.index(self.startIndex, offsetBy: range.upperBound)
return self.substring(with: start ..< end)
}
subscript(integerIndex: Int) -> Character { subscript(integerIndex: Int) -> Character {
let index = characters.index(startIndex, offsetBy: integerIndex) let index = characters.index(startIndex, offsetBy: integerIndex)
return self[index] return self[index]
@ -95,118 +61,7 @@ extension String {
let start = characters.index(startIndex, offsetBy: integerRange.lowerBound) let start = characters.index(startIndex, offsetBy: integerRange.lowerBound)
let end = characters.index(startIndex, offsetBy: integerRange.upperBound) let end = characters.index(startIndex, offsetBy: integerRange.upperBound)
let range = start ..< end let range = start ..< end
return self[range] return String(self[range])
}
func charAt(_ index: Int) -> Character {
return self[self.characters.index(self.startIndex, offsetBy: index)]
}
}
// Mapping from XML/HTML character entity reference to character
// From http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
private let characterEntities: [String:Character] = [
// XML predefined entities:
"&quot;": "\"",
"&amp;": "&",
"&apos;": "'",
"&lt;": "<",
"&gt;": ">",
// HTML character entity references:
"&nbsp;": "\u{00a0}",
// ...
"&diams;": "",
]
extension String {
///
/// Returns a new string made by replacing in the `String`
/// all HTML character entity references with the corresponding
/// character.
///
var stringByDecodingHTMLEntities: String {
// Convert the number in the string to the corresponding
// Unicode character, e.g.
// decodeNumeric("64", 10) --> "@"
// decodeNumeric("20ac", 16) --> ""
func decodeNumeric(_ string: String, base: Int32) -> Character? {
let code = UInt32(strtoul(string, nil, base))
return Character(UnicodeScalar(code)!)
}
// Decode the HTML character entity to the corresponding
// Unicode character, return `nil` for invalid input.
// decode("&#64;") --> "@"
// decode("&#x20ac;") --> ""
// decode("&lt;") --> "<"
// decode("&foo;") --> nil
func decode(_ entity: String) -> Character? {
if entity.hasPrefix("&#x") || entity.hasPrefix("&#X") {
return decodeNumeric(entity.substring(from: entity.characters.index(entity.startIndex, offsetBy: 3)), base: 16)
} else if entity.hasPrefix("&#") {
return decodeNumeric(entity.substring(from: entity.characters.index(entity.startIndex, offsetBy: 2)), base: 10)
} else {
return characterEntities[entity]
}
}
var result = ""
var position = startIndex
// Find the next '&' and copy the characters preceding it to `result`:
while let ampRange = self.range(of: "&", range: position ..< endIndex) {
result.append(self[position ..< ampRange.lowerBound])
position = ampRange.lowerBound
// Find the next ';' and copy everything from '&' to ';' into `entity`
if let semiRange = self.range(of: ";", range: position ..< endIndex) {
let entity = self[position ..< semiRange.upperBound]
position = semiRange.upperBound
if let decoded = decode(entity) {
// Replace by decoded character:
result.append(decoded)
} else {
// Invalid entity, copy verbatim:
result.append(entity)
}
} else {
// No matching ';'.
break
}
}
// Copy remaining characters to `result`:
result.append(self[position ..< endIndex])
return result
} }
} }
extension String {
static let htmlEscapedDictionary = [
"&amp;": "&",
"&quot;": "\"",
"&#x27;": "'",
"&#x39;": "'",
"&#x92;": "'",
"&#x96;": "'",
"&gt;": ">",
"&lt;": "<"
]
public var escapedHtmlString: String {
var newString = "\(self)"
for (key, value) in String.htmlEscapedDictionary {
newString = newString.replacingOccurrences(of: value, with: key)
}
return newString
}
}

View File

@ -320,7 +320,6 @@ public class ParseTreePatternMatcher {
// add special rule token or conjure up new token from name // add special rule token or conjure up new token from name
let firstStr = String(tagChunk.getTag()[0]) let firstStr = String(tagChunk.getTag()[0])
if firstStr.lowercased() != firstStr { if firstStr.lowercased() != firstStr {
//if ( Character.isUpperCase(tagChunk.getTag().charAt(0)) ) {
let ttype: Int = parser.getTokenType(tagChunk.getTag()) let ttype: Int = parser.getTokenType(tagChunk.getTag())
if ttype == CommonToken.INVALID_TYPE { if ttype == CommonToken.INVALID_TYPE {
throw ANTLRError.illegalArgument(msg: "Unknown token " + tagChunk.getTag() + " in pattern: " + pattern) throw ANTLRError.illegalArgument(msg: "Unknown token " + tagChunk.getTag() + " in pattern: " + pattern)
@ -329,7 +328,6 @@ public class ParseTreePatternMatcher {
tokens.append(t) tokens.append(t)
} else { } else {
if firstStr.uppercased() != firstStr { if firstStr.uppercased() != firstStr {
// if ( Character.isLowerCase(tagChunk.getTag().charAt(0)) ) {
let ruleIndex: Int = parser.getRuleIndex(tagChunk.getTag()) let ruleIndex: Int = parser.getRuleIndex(tagChunk.getTag())
if ruleIndex == -1 { if ruleIndex == -1 {
throw ANTLRError.illegalArgument(msg: "Unknown rule " + tagChunk.getTag() + " in pattern: " + pattern) throw ANTLRError.illegalArgument(msg: "Unknown rule " + tagChunk.getTag() + " in pattern: " + pattern)

View File

@ -62,10 +62,10 @@ class VisitorTests: XCTestCase {
var errors = [String]() var errors = [String]()
override func syntaxError<T : ATNSimulator>(_ recognizer: Recognizer<T>, override func syntaxError<T>(_ recognizer: Recognizer<T>,
_ offendingSymbol: AnyObject?, _ offendingSymbol: AnyObject?,
_ line: Int, _ charPositionInLine: Int, _ line: Int, _ charPositionInLine: Int,
_ msg: String, _ e: AnyObject?) { _ msg: String, _ e: AnyObject?) {
errors.append("line \(line):\(charPositionInLine) \(msg)") errors.append("line \(line):\(charPositionInLine) \(msg)")
} }
} }