201 lines
7.1 KiB
Markdown
201 lines
7.1 KiB
Markdown
# ANTLR4 Language Target, Runtime for Swift
|
|
|
|
## Requirements
|
|
|
|
ANTLR 4.7.2 requires Swift 4.2. It works on Swift 4.2.1 also.
|
|
|
|
ANTLR 4.7.1 requires Swift 4.0, and does not work on Swift 4.2. (The status of
|
|
Swift 4.1 support is unknown.)
|
|
|
|
## Performance Note
|
|
|
|
To use ANTLR4 Swift target in production environment, make sure to turn on compiler optimizations by following [these instructions](https://github.com/apple/swift-package-manager/blob/master/Documentation/Usage.md#build-configurations) if you use SwiftPM to build your project. If you are using Xcode to build your project, it's unlikely you will not use `release` build for production build.
|
|
|
|
Conclusion is, you need to turn on `release` mode (which will have all the optimization pre configured for you) so the ANTLR4 Swift target can have reasonable parsing speed.
|
|
|
|
## Install ANTLR4
|
|
|
|
Make sure you have the ANTLR
|
|
installed. [The getting started guide](getting-started.md) should get
|
|
you started.
|
|
|
|
## Create a Swift lexer or parser
|
|
This is pretty much the same as creating a Java lexer or parser,
|
|
except you need to specify the language target, for example:
|
|
|
|
```
|
|
$ antlr4 -Dlanguage=Swift MyGrammar.g4
|
|
```
|
|
|
|
If you integrate this as a build step inside Xcode, then you should use the
|
|
"gnu" message format to have any error messages parsed by Xcode. You may
|
|
also want to use the `-o` option to put the autogenerated files in a
|
|
separate subdirectory.
|
|
|
|
```
|
|
antlr4 -Dlanguage=Swift -message-format gnu -o Autogen 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
|
|
|
|
### Note
|
|
|
|
We use __boot.py__ script located at the root of the Swift runtime folder
|
|
`antlr4/runtime/Swift` to provide additional support for both Xcode-based
|
|
projects and SPM-based projects. Below sections are organized for both of
|
|
the flavors. If you want to quickly get started, try:
|
|
|
|
```
|
|
python boot.py --help
|
|
```
|
|
|
|
for information about this script.
|
|
|
|
### Xcode Projects
|
|
|
|
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. (using _swift package generate-xcodeproj_ is not recommended)
|
|
since the project is dependent on some parser files generated by _boot.py_.
|
|
|
|
```
|
|
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. Make sure that the Target Membership settings
|
|
are correct for your project.
|
|
|
|
<img src=images/dragfile.png width="500">
|
|
|
|
#### Add the ANTLR Swift runtime as a dependency
|
|
|
|
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/xcodedep.png width="800">
|
|
|
|
#### Build your project
|
|
|
|
The runtime and generated grammar should now build correctly.
|
|
|
|
### Swift Package Manager Projects
|
|
|
|
Since we cannot have a separate repository for Swift target (see issue [#1774](https://github.com/antlr/antlr4/issues/1774)),
|
|
and Swift is currently not ABI stable. We currently support support SPM-based
|
|
projects by creating temporary local repository.
|
|
|
|
For people using [Swift Package Manager](https://swift.org/package-manager/),
|
|
the __boot.py__ script supports generating local repository that can be used
|
|
as a dependency to your project. Simply run:
|
|
|
|
```
|
|
python boot.py --gen-spm-module
|
|
```
|
|
|
|
The prompt will show something like below:
|
|
|
|
<img src=images/gen_spm_module.png width="800">
|
|
|
|
Put the SPM directive that contains the url to temporary repository to your
|
|
project's Package.swift. And run `swift build` in your project.
|
|
|
|
The project is generated in your system's `/tmp/` directory, if you find it
|
|
inconvenient, consider copy that generated ANTLR repository to some place
|
|
that won't be cleaned automatically and update `url` parameter in your
|
|
`Package.swift` file.
|
|
|
|
## Swift access levels
|
|
|
|
You may use the `accessLevel` option to control the access levels on generated
|
|
code. This option can either be specified with `-DaccessLevel=value` on
|
|
the `antlr4` command line, or inside your `.g4` file like this:
|
|
|
|
```
|
|
options {
|
|
accessLevel = 'value';
|
|
}
|
|
```
|
|
|
|
By default (with the `accessLevel` option unspecified) the generated code
|
|
uses the following access levels:
|
|
|
|
* `open` for anything that you can feasibly extend with subclassing:
|
|
the generated parser, lexer, and context classes, the the listener and
|
|
visitor base classes, and all their accessor and setter functions.
|
|
* `public` for anything that should not be subclassed, but otherwise is
|
|
useful to client code: protocols, initializers, and static definitions such
|
|
as the lexer tokens, symbol names, and so on.
|
|
* `internal` or `private` for anything that should not be accessed directly.
|
|
|
|
If you specify `accessLevel = 'public'` then all items that are `open` by
|
|
default will use `public` instead. Otherwise, the behavior is the same as
|
|
the default.
|
|
|
|
If you specify `accessLevel = ''` or `accessLevel='internal'` then all items
|
|
that are `open` or `public` by default will use Swift's default (internal)
|
|
access level instead.
|
|
|
|
Those are the only supported values for `accessLevel` when using the Swift
|
|
code-generator.
|
|
|
|
We recommend using `accessLevel = ''`. Even if you are creating a parser
|
|
as part of a library, you would usually want to wrap it in an API of your
|
|
own and keep the ANTLR-generated parser internal to your module. You
|
|
only need to use the less restrictive access levels if you need to expose
|
|
the parser directly as part of your own module's API.
|