forked from jasder/antlr
Merge pull request #2032 from ewanmellor/swift-4
Migrate the Swift runtime to Swift 4.
This commit is contained in:
commit
c9c7561701
187
.travis.yml
187
.travis.yml
|
@ -2,6 +2,16 @@ sudo: true
|
|||
|
||||
language: java
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
|
||||
stages:
|
||||
- smoke-test
|
||||
- main-test
|
||||
- extended-test
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
|
@ -10,22 +20,8 @@ matrix:
|
|||
env:
|
||||
- TARGET=cpp
|
||||
- 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
|
||||
stage: main-test
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
|
@ -35,104 +31,148 @@ matrix:
|
|||
- g++-5
|
||||
- uuid-dev
|
||||
- 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
|
||||
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
|
||||
env:
|
||||
- TARGET=swift
|
||||
- GROUP=ALL
|
||||
stage: extended-test
|
||||
- os: osx
|
||||
osx_image: xcode8.2
|
||||
osx_image: xcode9
|
||||
env:
|
||||
- TARGET=dotnet
|
||||
- GROUP=LEXER
|
||||
stage: extended-test
|
||||
- os: osx
|
||||
osx_image: xcode8.2
|
||||
osx_image: xcode9
|
||||
env:
|
||||
- TARGET=dotnet
|
||||
- GROUP=PARSER
|
||||
stage: extended-test
|
||||
- os: osx
|
||||
osx_image: xcode8.2
|
||||
osx_image: xcode9
|
||||
env:
|
||||
- TARGET=dotnet
|
||||
- GROUP=RECURSION
|
||||
stage: extended-test
|
||||
- os: linux
|
||||
jdk: openjdk7
|
||||
env: TARGET=java
|
||||
stage: extended-test
|
||||
- os: linux
|
||||
jdk: openjdk8
|
||||
env: TARGET=java
|
||||
stage: extended-test
|
||||
- os: linux
|
||||
jdk: oraclejdk8
|
||||
env: TARGET=java
|
||||
stage: smoke-test
|
||||
- os: linux
|
||||
jdk: openjdk7
|
||||
env: TARGET=csharp
|
||||
stage: extended-test
|
||||
- os: linux
|
||||
jdk: oraclejdk8
|
||||
dist: trusty
|
||||
env:
|
||||
- TARGET=dotnet
|
||||
- GROUP=LEXER
|
||||
stage: main-test
|
||||
- os: linux
|
||||
jdk: oraclejdk8
|
||||
jdk: openjdk8
|
||||
dist: trusty
|
||||
env:
|
||||
- TARGET=dotnet
|
||||
- GROUP=PARSER
|
||||
stage: main-test
|
||||
- os: linux
|
||||
jdk: oraclejdk8
|
||||
dist: trusty
|
||||
env:
|
||||
- TARGET=dotnet
|
||||
- GROUP=RECURSION
|
||||
stage: main-test
|
||||
- os: linux
|
||||
jdk: openjdk7
|
||||
env: TARGET=python2
|
||||
stage: extended-test
|
||||
- os: linux
|
||||
jdk: openjdk7
|
||||
env: TARGET=python3
|
||||
|
@ -142,15 +182,20 @@ matrix:
|
|||
- deadsnakes # source required so it finds the package definition below
|
||||
packages:
|
||||
- python3.5
|
||||
stage: main-test
|
||||
- os: linux
|
||||
jdk: openjdk7
|
||||
dist: trusty
|
||||
jdk: openjdk8
|
||||
env: TARGET=javascript
|
||||
stage: main-test
|
||||
- os: linux
|
||||
jdk: openjdk7
|
||||
dist: trusty
|
||||
jdk: openjdk8
|
||||
env: TARGET=go
|
||||
stage: main-test
|
||||
|
||||
before_install:
|
||||
- ./.travis/before-install-$TRAVIS_OS_NAME-$TARGET.sh
|
||||
- f="./.travis/before-install-$TRAVIS_OS_NAME-$TARGET.sh"; ! [ -x "$f" ] || "$f"
|
||||
|
||||
script:
|
||||
- cd runtime-testsuite; ../.travis/run-tests-$TARGET.sh
|
||||
- cd runtime-testsuite; travis_wait 40 ../.travis/run-tests-$TARGET.sh
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
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
|
||||
# some packages below will be update, swift assumes newer versions
|
||||
# of, for example, sqlite3 and libicu, without the update some
|
||||
# tools will not work
|
||||
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:
|
||||
# https://bugs.swift.org/browse/SR-2299
|
||||
|
|
|
@ -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() { :; }
|
|
@ -4,9 +4,7 @@ set -euo pipefail
|
|||
|
||||
thisdir=$(dirname "$0")
|
||||
|
||||
# pre-requisites for dotnet core
|
||||
brew update
|
||||
brew install openssl
|
||||
# OpenSSL setup for dotnet core
|
||||
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/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
|
||||
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() { :; }
|
||||
|
||||
|
|
|
@ -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() { :; }
|
|
@ -4,7 +4,7 @@
|
|||
# here since environment variables doesn't pass
|
||||
# across scripts
|
||||
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 PATH=$SWIFT_HOME:$PATH
|
||||
|
||||
|
|
|
@ -23,60 +23,83 @@ $ antlr4 -Dlanguage=Swift MyGrammar.g4
|
|||
For a full list of antlr4 tool options, please visit the
|
||||
[tool documentation page](tool-options.md).
|
||||
|
||||
|
||||
## 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
|
||||
drag the generated files from Finder to the Xcode IDE. Remember to
|
||||
check __Copy items if needed__ to make sure the files are actually
|
||||
moved into the project folder instead of symbolic links (see the
|
||||
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
|
||||
see Xcode complaining the module "Antlr4" could not be found at the
|
||||
import statement. This is expected, since we still need the ANTLR
|
||||
Swift runtime for those missing symbols.
|
||||
the project navigator. Make sure that the Target Membership settings
|
||||
are correct for your project.
|
||||
|
||||
<img src=images/dragfile.png width="500">
|
||||
|
||||
* __Download ANTLR runtime__. Due to unstable ABI of Swift language,
|
||||
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__.
|
||||
### Add the ANTLR Swift runtime as a dependency
|
||||
|
||||
* __Import ANTLR Swift runtime into project__. Drag Antlr4.xcodeproj
|
||||
into your project, after this is done, your Xcode project navigator
|
||||
will be something like the screenshot below. In this case, your own
|
||||
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.
|
||||
Select your own project in Xcode and go to the Build Phases settings panel.
|
||||
Add the ANTLR runtime under __Target Dependencies__ and __Link Binary With
|
||||
Libraries__.
|
||||
|
||||
<img src=images/xcodenav.png width="300">
|
||||
<img src=images/xcodedep.png width="800">
|
||||
|
||||
* __Build ANTLR runtime__. By expanding the "Products" folder in the
|
||||
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.
|
||||
### Build your project
|
||||
|
||||
<img src=images/targetselection.png width="500">
|
||||
|
||||
* __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">
|
||||
The runtime and generated grammar should now build correctly.
|
||||
|
|
|
@ -145,7 +145,7 @@ public class BaseSwiftTest implements RuntimeTestSupport {
|
|||
|
||||
String projectName = "testcase-" + System.currentTimeMillis();
|
||||
String projectDir = getTmpDir() + "/" + projectName;
|
||||
buildProject(projectDir);
|
||||
buildProject(projectDir, projectName);
|
||||
return execTest(projectDir, projectName);
|
||||
}
|
||||
|
||||
|
@ -183,12 +183,12 @@ public class BaseSwiftTest implements RuntimeTestSupport {
|
|||
Collections.addAll(this.sourceFiles, files);
|
||||
}
|
||||
|
||||
private void buildProject(String projectDir) {
|
||||
private void buildProject(String projectDir, String projectName) {
|
||||
mkdir(projectDir);
|
||||
fastFailRunProcess(projectDir, SWIFT_CMD, "package", "init", "--type", "executable");
|
||||
for (String sourceFile: sourceFiles) {
|
||||
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);
|
||||
|
||||
|
@ -201,7 +201,7 @@ public class BaseSwiftTest implements RuntimeTestSupport {
|
|||
"-Xlinker", "-rpath",
|
||||
"-Xlinker", dylibPath);
|
||||
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) {
|
||||
e.printStackTrace();
|
||||
|
@ -251,7 +251,7 @@ public class BaseSwiftTest implements RuntimeTestSupport {
|
|||
addSourceFiles("main.swift");
|
||||
String projectName = "testcase-" + System.currentTimeMillis();
|
||||
String projectDir = getTmpDir() + "/" + projectName;
|
||||
buildProject(projectDir);
|
||||
buildProject(projectDir, projectName);
|
||||
return execTest(projectDir, projectName);
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
.build/
|
||||
Antlr4.xcodeproj/
|
||||
Tests/Antlr4Tests/gen/
|
||||
xcuserdata/
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// swift-tools-version:4.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.
|
||||
|
@ -5,15 +6,19 @@
|
|||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Antlr4"
|
||||
)
|
||||
|
||||
products.append(
|
||||
Product(
|
||||
name: "Antlr4",
|
||||
type: .Library(.Dynamic),
|
||||
modules: [
|
||||
"Antlr4"
|
||||
]
|
||||
)
|
||||
name: "Antlr4",
|
||||
products: [
|
||||
.library(
|
||||
name: "Antlr4",
|
||||
type: .dynamic,
|
||||
targets: ["Antlr4"]),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "Antlr4",
|
||||
dependencies: []),
|
||||
.testTarget(
|
||||
name: "Antlr4Tests",
|
||||
dependencies: ["Antlr4"]),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -39,12 +39,12 @@ public protocol ANTLRErrorListener: class {
|
|||
/// the parser was able to recover in line without exiting the
|
||||
/// surrounding rule.
|
||||
///
|
||||
func syntaxError<T:ATNSimulator>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int,
|
||||
_ charPositionInLine: Int,
|
||||
_ msg: String,
|
||||
_ e: AnyObject?
|
||||
func syntaxError<T>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int,
|
||||
_ charPositionInLine: Int,
|
||||
_ msg: String,
|
||||
_ e: AnyObject?
|
||||
)
|
||||
|
||||
///
|
||||
|
|
|
@ -17,12 +17,12 @@ open class BaseErrorListener: ANTLRErrorListener {
|
|||
public init() {
|
||||
}
|
||||
|
||||
open func syntaxError<T:ATNSimulator>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int,
|
||||
_ charPositionInLine: Int,
|
||||
_ msg: String,
|
||||
_ e: AnyObject?
|
||||
open func syntaxError<T>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int,
|
||||
_ charPositionInLine: Int,
|
||||
_ msg: String,
|
||||
_ e: AnyObject?
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
|
@ -25,12 +25,12 @@ public class ConsoleErrorListener: BaseErrorListener {
|
|||
/// line __line__:__charPositionInLine__ __msg__
|
||||
///
|
||||
///
|
||||
override public func syntaxError<T:ATNSimulator>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int,
|
||||
_ charPositionInLine: Int,
|
||||
_ msg: String,
|
||||
_ e: AnyObject?
|
||||
override public func syntaxError<T>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int,
|
||||
_ charPositionInLine: Int,
|
||||
_ msg: String,
|
||||
_ e: AnyObject?
|
||||
) {
|
||||
if Parser.ConsoleError {
|
||||
errPrint("line \(line):\(charPositionInLine) \(msg)")
|
||||
|
|
|
@ -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 msg: String = "token recognition error at: '\(getErrorDisplay(text))'"
|
||||
|
|
|
@ -20,13 +20,13 @@ public class ProxyErrorListener: ANTLRErrorListener {
|
|||
self.delegates = delegates
|
||||
}
|
||||
|
||||
public func syntaxError<T:ATNSimulator>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int,
|
||||
_ charPositionInLine: Int,
|
||||
_ msg: String,
|
||||
_ e: AnyObject?)
|
||||
{
|
||||
public func syntaxError<T>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int,
|
||||
_ charPositionInLine: Int,
|
||||
_ msg: String,
|
||||
_ e: AnyObject?)
|
||||
{
|
||||
for listener: ANTLRErrorListener in delegates {
|
||||
listener.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e)
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ open class RuleContext: RuleNode {
|
|||
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)
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ open class RuleContext: RuleNode {
|
|||
}
|
||||
|
||||
// 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 ruleNamesList: Array<String>? = ruleNames ?? nil
|
||||
return toString(ruleNamesList, stop)
|
||||
|
|
|
@ -167,7 +167,7 @@ public class ATNConfig: Hashable, CustomStringConvertible {
|
|||
//return "MyClass \(string)"
|
||||
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()
|
||||
buf.append("(")
|
||||
buf.append(state)
|
||||
|
|
|
@ -238,12 +238,9 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
private var configsHashValue: Int {
|
||||
var hashCode = 1
|
||||
for item in configs {
|
||||
hashCode = Int.multiplyWithOverflow(3, hashCode).0
|
||||
hashCode = Int.addWithOverflow(hashCode, item.hashValue).0
|
||||
|
||||
hashCode = hashCode &* 3 &+ item.hashValue
|
||||
}
|
||||
return hashCode
|
||||
|
||||
}
|
||||
|
||||
public final var count: Int {
|
||||
|
|
|
@ -175,7 +175,7 @@ public class ATNDeserializer {
|
|||
if let s = s as? BlockStartState {
|
||||
let endStateNumber: Int = toInt(data[p])
|
||||
p += 1
|
||||
endStateNumbers.append(s, endStateNumber)
|
||||
endStateNumbers.append((s, endStateNumber))
|
||||
}
|
||||
}
|
||||
atn.addState(s)
|
||||
|
|
|
@ -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 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)
|
||||
}
|
||||
|
||||
// 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 perm: Int = 0
|
||||
outer: while true {
|
||||
|
|
|
@ -37,7 +37,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
/// prediction, so we passed in the outer context here in case of context
|
||||
/// 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")
|
||||
return false
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
/// * A non-`null` _org.antlr.v4.runtime.atn.SemanticContext_: the new simplified
|
||||
/// 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
|
||||
}
|
||||
public var hashValue: Int {
|
||||
|
@ -90,7 +90,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
}
|
||||
|
||||
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
|
||||
return try parser.sempred(localctx, ruleIndex, predIndex)
|
||||
}
|
||||
|
@ -126,12 +126,12 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
return SemanticContext.NONE
|
||||
} else {
|
||||
|
@ -187,31 +187,28 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
|
||||
public init(_ a: SemanticContext, _ b: SemanticContext) {
|
||||
var operands: Set<SemanticContext> = Set<SemanticContext>()
|
||||
if a is AND {
|
||||
operands.formUnion((a as! AND).opnds)
|
||||
//operands.addAll(Arrays.asList((a as AND).opnds));
|
||||
if let aAnd = a as? AND {
|
||||
operands.formUnion(aAnd.opnds)
|
||||
} else {
|
||||
operands.insert(a)
|
||||
}
|
||||
if b is AND {
|
||||
operands.formUnion((b as! AND).opnds)
|
||||
//operands.addAll(Arrays.asList((b as AND).opnds));
|
||||
if let bAnd = b as? AND {
|
||||
operands.formUnion(bAnd.opnds)
|
||||
} else {
|
||||
operands.insert(b)
|
||||
}
|
||||
|
||||
let precedencePredicates: Array<PrecedencePredicate> =
|
||||
SemanticContext.filterPrecedencePredicates(&operands)
|
||||
let precedencePredicates = SemanticContext.filterPrecedencePredicates(&operands)
|
||||
if !precedencePredicates.isEmpty {
|
||||
// interested in the transition with the lowest precedence
|
||||
|
||||
let reduced: PrecedencePredicate = precedencePredicates.sorted {
|
||||
let reduced = precedencePredicates.sorted {
|
||||
$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
|
||||
|
@ -236,7 +233,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
/// unordered.
|
||||
///
|
||||
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 {
|
||||
if try !opnd.eval(parser, parserCallStack) {
|
||||
return false
|
||||
|
@ -246,7 +243,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
}
|
||||
|
||||
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 operands: Array<SemanticContext> = Array<SemanticContext>()
|
||||
for context: SemanticContext in opnds {
|
||||
|
@ -305,30 +302,28 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
|
||||
public init(_ a: SemanticContext, _ b: SemanticContext) {
|
||||
var operands: Set<SemanticContext> = Set<SemanticContext>()
|
||||
if a is OR {
|
||||
operands.formUnion((a as! OR).opnds)
|
||||
// operands.addAll(Arrays.asList((a as OR).opnds));
|
||||
if let aOr = a as? OR {
|
||||
operands.formUnion(aOr.opnds)
|
||||
} else {
|
||||
operands.insert(a)
|
||||
}
|
||||
if b is OR {
|
||||
operands.formUnion((b as! OR).opnds)
|
||||
//operands.addAll(Arrays.asList((b as OR).opnds));
|
||||
if let bOr = b as? OR {
|
||||
operands.formUnion(bOr.opnds)
|
||||
} else {
|
||||
operands.insert(b)
|
||||
}
|
||||
|
||||
let precedencePredicates: Array<PrecedencePredicate> = SemanticContext.filterPrecedencePredicates(&operands)
|
||||
let precedencePredicates = SemanticContext.filterPrecedencePredicates(&operands)
|
||||
if !precedencePredicates.isEmpty {
|
||||
// interested in the transition with the highest precedence
|
||||
let reduced: PrecedencePredicate = precedencePredicates.sorted {
|
||||
|
||||
let reduced = precedencePredicates.sorted {
|
||||
$0.precedence > $1.precedence
|
||||
}.first!
|
||||
//var reduced : PrecedencePredicate = Collections.max(precedencePredicates);
|
||||
operands.insert(reduced)
|
||||
}
|
||||
operands.insert(reduced[0])
|
||||
}
|
||||
|
||||
self.opnds = Array(operands) //operands.toArray(new, SemanticContext[operands.size()]);
|
||||
self.opnds = Array(operands)
|
||||
}
|
||||
|
||||
override
|
||||
|
@ -351,7 +346,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
/// unordered.
|
||||
///
|
||||
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 {
|
||||
if try opnd.eval(parser, parserCallStack) {
|
||||
return true
|
||||
|
@ -361,7 +356,7 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
}
|
||||
|
||||
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 operands: Array<SemanticContext> = Array<SemanticContext>()
|
||||
for context: SemanticContext in opnds {
|
||||
|
@ -447,21 +442,14 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
return result
|
||||
}
|
||||
|
||||
private static func filterPrecedencePredicates(
|
||||
_ collection: inout Set<SemanticContext>) ->
|
||||
Array<PrecedencePredicate> {
|
||||
|
||||
let result = collection.filter {
|
||||
$0 is PrecedencePredicate
|
||||
private static func filterPrecedencePredicates(_ collection: inout Set<SemanticContext>) -> [PrecedencePredicate] {
|
||||
let result = collection.flatMap {
|
||||
$0 as? PrecedencePredicate
|
||||
}
|
||||
collection = Set<SemanticContext>(collection.filter {
|
||||
!($0 is PrecedencePredicate)
|
||||
})
|
||||
//if (result == nil) {
|
||||
//return Array<PrecedencePredicate>();
|
||||
//}
|
||||
|
||||
return (result as! Array<PrecedencePredicate>)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -644,12 +644,12 @@ public class BitSet: Hashable, CustomStringConvertible {
|
|||
return 64
|
||||
}
|
||||
var n: Int32 = 63
|
||||
y = Int32(truncatingBitPattern: i)
|
||||
y = Int32(truncatingIfNeeded: i)
|
||||
if y != 0 {
|
||||
n = n - 32
|
||||
x = y
|
||||
} else {
|
||||
x = Int32(truncatingBitPattern: i >>> 32)
|
||||
x = Int32(truncatingIfNeeded: i >>> 32)
|
||||
}
|
||||
|
||||
y = x << 16
|
||||
|
|
|
@ -41,7 +41,7 @@ final class Entry<K: Hashable,V>: CustomStringConvertible {
|
|||
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 {
|
||||
return true
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ func == <K: Hashable, V: Equatable>(lhs: Entry<K,V>, rhs: Entry<K,V>) -> Bool {
|
|||
}
|
||||
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 {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -49,19 +49,19 @@ public final class MurmurHash {
|
|||
let m: Int32 = 5
|
||||
let n: Int32 = -430675100//0xE6546B64;
|
||||
|
||||
var k: Int32 = Int32(truncatingBitPattern: value)
|
||||
k = Int32.multiplyWithOverflow(k, c1).0
|
||||
var k: Int32 = Int32(truncatingIfNeeded: value)
|
||||
k = k.multipliedReportingOverflow(by: c1).partialValue
|
||||
// (k,_) = UInt32.multiplyWithOverflow(k, c1) ;//( k * c1);
|
||||
//TODO: CHECKE >>>
|
||||
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.multiplyWithOverflow(k, c2)
|
||||
k = Int32.multiplyWithOverflow(k, c2).0
|
||||
k = k.multipliedReportingOverflow(by: c2).partialValue
|
||||
var hash = Int32(hashIn)
|
||||
hash = hash ^ k
|
||||
hash = (hash << r2) | (hash >>> (Int32(32) - r2))//hash = (hash << r2) | (hash >>> (32 - r2));
|
||||
(hash, _) = Int32.multiplyWithOverflow(hash, m)
|
||||
(hash, _) = Int32.addWithOverflow(hash, n)
|
||||
hash = hash.multipliedReportingOverflow(by: m).partialValue
|
||||
hash = hash.addingReportingOverflow(n).partialValue
|
||||
//hash = hash * m + n;
|
||||
// print("murmur update2 : \(hash)")
|
||||
return Int(hash)
|
||||
|
@ -90,12 +90,12 @@ public final class MurmurHash {
|
|||
public static func finish(_ hashin: Int, _ numberOfWordsIn: Int) -> Int {
|
||||
var hash = Int32(hashin)
|
||||
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, _) = 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 = 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);
|
||||
//print("murmur finish : \(hash)")
|
||||
return Int(hash)
|
||||
|
|
|
@ -11,14 +11,6 @@ import Foundation
|
|||
|
||||
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 {
|
||||
return self.characters.count
|
||||
}
|
||||
|
@ -60,32 +52,6 @@ extension String {
|
|||
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 {
|
||||
let index = characters.index(startIndex, offsetBy: integerIndex)
|
||||
return self[index]
|
||||
|
@ -95,118 +61,7 @@ extension String {
|
|||
let start = characters.index(startIndex, offsetBy: integerRange.lowerBound)
|
||||
let end = characters.index(startIndex, offsetBy: integerRange.upperBound)
|
||||
let range = start ..< end
|
||||
return 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:
|
||||
""": "\"",
|
||||
"&": "&",
|
||||
"'": "'",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
|
||||
// HTML character entity references:
|
||||
" ": "\u{00a0}",
|
||||
// ...
|
||||
"♦": "♦",
|
||||
]
|
||||
|
||||
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("@") --> "@"
|
||||
// decode("€") --> "€"
|
||||
// decode("<") --> "<"
|
||||
// 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
|
||||
return String(self[range])
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
|
||||
static let htmlEscapedDictionary = [
|
||||
"&": "&",
|
||||
""": "\"",
|
||||
"'": "'",
|
||||
"9": "'",
|
||||
"’": "'",
|
||||
"–": "'",
|
||||
">": ">",
|
||||
"<": "<"
|
||||
]
|
||||
|
||||
public var escapedHtmlString: String {
|
||||
var newString = "\(self)"
|
||||
|
||||
for (key, value) in String.htmlEscapedDictionary {
|
||||
newString = newString.replacingOccurrences(of: value, with: key)
|
||||
}
|
||||
return newString
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -320,7 +320,6 @@ public class ParseTreePatternMatcher {
|
|||
// add special rule token or conjure up new token from name
|
||||
let firstStr = String(tagChunk.getTag()[0])
|
||||
if firstStr.lowercased() != firstStr {
|
||||
//if ( Character.isUpperCase(tagChunk.getTag().charAt(0)) ) {
|
||||
let ttype: Int = parser.getTokenType(tagChunk.getTag())
|
||||
if ttype == CommonToken.INVALID_TYPE {
|
||||
throw ANTLRError.illegalArgument(msg: "Unknown token " + tagChunk.getTag() + " in pattern: " + pattern)
|
||||
|
@ -329,7 +328,6 @@ public class ParseTreePatternMatcher {
|
|||
tokens.append(t)
|
||||
} else {
|
||||
if firstStr.uppercased() != firstStr {
|
||||
// if ( Character.isLowerCase(tagChunk.getTag().charAt(0)) ) {
|
||||
let ruleIndex: Int = parser.getRuleIndex(tagChunk.getTag())
|
||||
if ruleIndex == -1 {
|
||||
throw ANTLRError.illegalArgument(msg: "Unknown rule " + tagChunk.getTag() + " in pattern: " + pattern)
|
||||
|
|
|
@ -62,10 +62,10 @@ class VisitorTests: XCTestCase {
|
|||
|
||||
var errors = [String]()
|
||||
|
||||
override func syntaxError<T : ATNSimulator>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int, _ charPositionInLine: Int,
|
||||
_ msg: String, _ e: AnyObject?) {
|
||||
override func syntaxError<T>(_ recognizer: Recognizer<T>,
|
||||
_ offendingSymbol: AnyObject?,
|
||||
_ line: Int, _ charPositionInLine: Int,
|
||||
_ msg: String, _ e: AnyObject?) {
|
||||
errors.append("line \(line):\(charPositionInLine) \(msg)")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue