Strumenta / antlr-kotlin

Support for Kotlin as a target for ANTLR 4
Apache License 2.0
221 stars 47 forks source link

ANTLR Kotlin

Build Status Maven Central License Apache-2.0 License

This project contains everything needed to support Kotlin as a target for ANTLR.

This being a fully multiplatform project, the code written using the Kotlin target for ANTLR will run on the JVM (including Android), in the browser, in Node.js, and natively on Mac, Windows, and Linux.

Want to start experimenting immediately? See Gradle Setup.

Status

The project should be considered experimental. Several parsers have been implemented and work so far using this target but not all the features are complete and well tested.

The runtime and target's template are up-to-date with mainstream commit: master/e9df464

Kotlin Target

The Kotlin target is a plugin for the ANTLR generator.

It should be added to the classpath used to run the ANTLR Tool.

You will need to specify the target language to be Kotlin (-Dlanguage=Kotlin), or use the com.strumenta.antlr-kotlin plugin, which instructs ANTLR automatically.

Kotlin Runtime

The Kotlin runtime for the Kotlin target is derived from the Java runtime, and is built as a multiplatform project running on JVM, JS, WebAssembly (including WASI), and Native.

[!WARNING]
The Native runtime is not thread safe

The supported Native platforms are:

Tier 1 Tier 2 Tier 3
macosX64 linuxX64 androidNativeArm32
macosArm64 linuxArm64 androidNativeArm64
iosSimulatorArm64 watchosSimulatorArm64 androidNativeX86
iosX64 watchosX64 androidNativeX64
watchosArm32 watchosDeviceArm64
watchosArm64 mingwX64
tvosSimulatorArm64 linuxArm32Hfp
tvosX64
tvosArm64
iosArm64

[!NOTE]
The linuxArm32Hfp platform is deprecated

Gradle Setup

To start using ANTLR Kotlin:

  1. Add the mavenCentral repository to the list of repositories in your build script. This is required as artifacts are pushed to Maven Central.

    repositories {
     mavenCentral()
    }
  2. Add the ANTLR Gradle plugin for the Kotlin target to the list of plugins in your build script.

    plugins {
     id("com.strumenta.antlr-kotlin") version "$antlrKotlinVersion"
    }
  3. Add the ANTLR Kotlin Runtime to the list of dependencies. If you are working in a multiplatform project, add it to the common source set.

    kotlin {
     sourceSets {
       commonMain {
         dependencies {
           implementation("com.strumenta:antlr-kotlin-runtime:$antlrKotlinVersion")
         }
       }
     }
    }
  4. Register the ANTLR Kotlin grammar generation task.

    val generateKotlinGrammarSource = tasks.register<AntlrKotlinTask>("generateKotlinGrammarSource") {
     dependsOn("cleanGenerateKotlinGrammarSource")
    
     // ANTLR .g4 files are under {example-project}/antlr
     // Only include *.g4 files. This allows tools (e.g., IDE plugins)
     // to generate temporary files inside the base path
     source = fileTree(layout.projectDirectory.dir("antlr")) {
       include("**/*.g4")
     }
    
     // We want the generated source files to have this package name
     val pkgName = "com.strumenta.antlrkotlin.parsers.generated"
     packageName = pkgName
    
     // We want visitors alongside listeners.
     // The Kotlin target language is implicit, as is the file encoding (UTF-8)
     arguments = listOf("-visitor")
    
     // Generated files are outputted inside build/generatedAntlr/{package-name}
     val outDir = "generatedAntlr/${pkgName.replace(".", "/")}"
     outputDirectory = layout.buildDirectory.dir(outDir).get().asFile
    }

    Depending on cleanGenerateKotlinGrammarSource ensures the .tokens files are always fresh, and we do not end up with out-of-sync lexers and parsers.

  5. Instruct the Kotlin compilation tasks to depend on the grammar generation.

    tasks.withType<KotlinCompile<*>> {
     dependsOn(generateKotlinGrammarSource)
    }
    
  6. Register the build/generatedAntlr directory as part of the common source set.

    kotlin {
     sourceSets {
       commonMain {
         kotlin {
           srcDir(layout.buildDirectory.dir("generatedAntlr"))
         }
       }
     }
    }

Benchmarks

The antlr-kotlin-benchmarks module contains benchmarking code targeting JVM, JS and WebAssembly.
The scenario has been adapted from antlr4ng.

Maven Central Publication

Publication can be performed running:

./gradlew publishAllPublicationsToMavenCentralRepository --no-configuration-cache

However, it is recommended to use the releases plugin and run:

./gradlew release

Contributors

You can see the complete list on GitHub, but here we list those who contributed ten commits or more.

License

Consumers of this project may choose the most appropriate license: either the Apache License 2.0, or the 3-Clause BSD License.