[orx-expression-evaluator] Switch to antlr-kotlin for parser generation and make it a common kotlin module
This commit is contained in:
@@ -19,6 +19,7 @@ libfreenect = "0.5.7-1.5.9"
|
||||
librealsense = "2.53.1-1.5.9"
|
||||
gson = "2.10.1"
|
||||
antlr = "4.13.1"
|
||||
antlrKotlin = "0.1.0-RC14"
|
||||
tensorflow = "0.5.0"
|
||||
minim = "2.2.2"
|
||||
netty = "4.1.92.Final"
|
||||
@@ -76,6 +77,7 @@ javaosc-core = { group = "com.illposed.osc", name = "javaosc-core", version.ref
|
||||
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
|
||||
antlr-core = { group = "org.antlr", name = "antlr4", version.ref = "antlr" }
|
||||
antlr-runtime = { group = "org.antlr", name = "antlr4-runtime", version.ref = "antlr" }
|
||||
antlr-kotlin-runtime = { group = "com.strumenta", name = "antlr-kotlin-runtime", version.ref = "antlrKotlin" }
|
||||
|
||||
jupiter-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junitJupiter" }
|
||||
jupiter-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junitJupiter" }
|
||||
@@ -87,7 +89,7 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi
|
||||
nebula-release = { id = "nebula.release", version.ref = "nebulaRelease" }
|
||||
gradle-nexus-publish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "gradleNexusPublish" }
|
||||
kotest-multiplatform = { id = "io.kotest.multiplatform", version.ref = "kotest" }
|
||||
|
||||
antlr-kotlin = { id = "com.strumenta.antlr-kotlin", version.ref = "antlrKotlin" }
|
||||
|
||||
[bundles]
|
||||
jupiter = ["jupiter-api", "jupiter-engine"]
|
||||
|
||||
66
orx-expression-evaluator/build.gradle.kts
Normal file
66
orx-expression-evaluator/build.gradle.kts
Normal file
@@ -0,0 +1,66 @@
|
||||
import com.strumenta.antlrkotlin.gradle.AntlrKotlinTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
org.openrndr.extra.convention.`kotlin-multiplatform`
|
||||
alias(libs.plugins.antlr.kotlin)
|
||||
}
|
||||
|
||||
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("src/commonMain/antlr")) {
|
||||
include("**/*.g4")
|
||||
}
|
||||
|
||||
// We want the generated source files to have this package name
|
||||
val pkgName = "org.openrndr.expressions.parser"
|
||||
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
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(libs.antlr.kotlin.runtime)
|
||||
implementation(libs.openrndr.application)
|
||||
implementation(libs.openrndr.math)
|
||||
implementation(libs.kotlin.coroutines)
|
||||
implementation(project(":orx-property-watchers"))
|
||||
implementation(project(":orx-noise"))
|
||||
}
|
||||
kotlin {
|
||||
srcDir(layout.buildDirectory.dir("generatedAntlr"))
|
||||
}
|
||||
}
|
||||
val jvmDemo by getting {
|
||||
dependencies {
|
||||
implementation(project(":orx-jvm:orx-gui"))
|
||||
}
|
||||
}
|
||||
val jvmTest by getting {
|
||||
dependencies {
|
||||
implementation(libs.kluent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
dependsOn(generateKotlinGrammarSource)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.openrndr.extra.expressions
|
||||
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker
|
||||
import org.antlr.v4.kotlinruntime.tree.ParseTreeWalker
|
||||
|
||||
|
||||
/**
|
||||
* Compile a (Double)->Double function from an expression string
|
||||
@@ -1,11 +1,13 @@
|
||||
package org.openrndr.extra.expressions
|
||||
|
||||
import KeyLangLexer
|
||||
import KeyLangParser
|
||||
import KeyLangParserBaseListener
|
||||
import org.antlr.v4.runtime.*
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker
|
||||
import org.antlr.v4.runtime.tree.TerminalNode
|
||||
|
||||
|
||||
import org.antlr.v4.kotlinruntime.*
|
||||
import org.antlr.v4.kotlinruntime.tree.ParseTreeWalker
|
||||
import org.antlr.v4.kotlinruntime.tree.TerminalNode
|
||||
import org.openrndr.expressions.parser.KeyLangLexer
|
||||
import org.openrndr.expressions.parser.KeyLangParser
|
||||
import org.openrndr.expressions.parser.KeyLangParserBaseListener
|
||||
|
||||
import org.openrndr.extra.noise.uniform
|
||||
import org.openrndr.math.*
|
||||
@@ -84,11 +86,11 @@ internal class ExpressionListener(
|
||||
val right = doubleStack.pop()
|
||||
val left = doubleStack.pop()
|
||||
val result = when (val operator = ctx.operator?.type) {
|
||||
KeyLangParser.PLUS -> left + right
|
||||
KeyLangParser.MINUS -> left - right
|
||||
KeyLangParser.ASTERISK -> left * right
|
||||
KeyLangParser.DIVISION -> left / right
|
||||
KeyLangParser.PERCENTAGE -> mod(left, right)
|
||||
KeyLangLexer.Tokens.PLUS.id -> left + right
|
||||
KeyLangParser.Tokens.MINUS.id -> left - right
|
||||
KeyLangParser.Tokens.ASTERISK.id -> left * right
|
||||
KeyLangParser.Tokens.DIVISION.id -> left / right
|
||||
KeyLangParser.Tokens.PERCENTAGE.id -> mod(left, right)
|
||||
else -> error("operator '$operator' not implemented")
|
||||
}
|
||||
doubleStack.push(result)
|
||||
@@ -103,10 +105,10 @@ internal class ExpressionListener(
|
||||
val left = doubleStack.pop()
|
||||
val right = doubleStack.pop()
|
||||
val result = when (val operator = ctx.operator?.type) {
|
||||
KeyLangParser.PLUS -> left + right
|
||||
KeyLangParser.MINUS -> right - left
|
||||
KeyLangParser.ASTERISK -> left * right
|
||||
KeyLangParser.DIVISION -> left / right
|
||||
KeyLangParser.Tokens.PLUS.id -> left + right
|
||||
KeyLangParser.Tokens.MINUS.id -> right - left
|
||||
KeyLangParser.Tokens.ASTERISK.id -> left * right
|
||||
KeyLangParser.Tokens.DIVISION.id -> left / right
|
||||
else -> error("operator '$operator' not implemented")
|
||||
}
|
||||
doubleStack.push(result)
|
||||
@@ -245,13 +247,13 @@ internal class ExpressionListener(
|
||||
|
||||
override fun visitTerminal(node: TerminalNode) {
|
||||
val type = node.symbol?.type
|
||||
if (type == KeyLangParser.INTLIT) {
|
||||
if (type == KeyLangParser.Tokens.INTLIT.id) {
|
||||
doubleStack.push(node.text.toDouble())
|
||||
}
|
||||
if (type == KeyLangParser.DECLIT) {
|
||||
if (type == KeyLangParser.Tokens.DECLIT.id) {
|
||||
doubleStack.push(node.text.toDouble())
|
||||
}
|
||||
if (type == KeyLangParser.ID) {
|
||||
if (type == KeyLangParser.Tokens.ID.id) {
|
||||
val name = node.text.replace("`", "")
|
||||
@Suppress("DIVISION_BY_ZERO")
|
||||
when (val idType = idTypeStack.pop()) {
|
||||
@@ -409,11 +411,11 @@ fun evaluateExpression(
|
||||
parser.removeErrorListeners()
|
||||
parser.addErrorListener(object : BaseErrorListener() {
|
||||
override fun syntaxError(
|
||||
recognizer: Recognizer<*, *>?,
|
||||
recognizer: Recognizer<*, *>,
|
||||
offendingSymbol: Any?,
|
||||
line: Int,
|
||||
charPositionInLine: Int,
|
||||
msg: String?,
|
||||
msg: String,
|
||||
e: RecognitionException?
|
||||
) {
|
||||
throw ExpressionException("parser error in expression: '$expression'; [line: $line, character: $charPositionInLine ${offendingSymbol?.let { ", near: $it" } ?: ""} ]")
|
||||
@@ -440,11 +442,11 @@ fun compileExpression(
|
||||
parser.removeErrorListeners()
|
||||
parser.addErrorListener(object : BaseErrorListener() {
|
||||
override fun syntaxError(
|
||||
recognizer: Recognizer<*, *>?,
|
||||
recognizer: Recognizer<*, *>,
|
||||
offendingSymbol: Any?,
|
||||
line: Int,
|
||||
charPositionInLine: Int,
|
||||
msg: String?,
|
||||
msg: String,
|
||||
e: RecognitionException?
|
||||
) {
|
||||
throw ExpressionException("parser error in expression: '$expression'; [line: $line, character: $charPositionInLine ${offendingSymbol?.let { ", near: $it" } ?: ""} ]")
|
||||
@@ -470,11 +472,11 @@ internal fun expressionRoot(expression: String): KeyLangParser.KeyLangFileContex
|
||||
parser.removeErrorListeners()
|
||||
parser.addErrorListener(object : BaseErrorListener() {
|
||||
override fun syntaxError(
|
||||
recognizer: Recognizer<*, *>?,
|
||||
recognizer: Recognizer<*, *>,
|
||||
offendingSymbol: Any?,
|
||||
line: Int,
|
||||
charPositionInLine: Int,
|
||||
msg: String?,
|
||||
msg: String,
|
||||
e: RecognitionException?
|
||||
) {
|
||||
throw ExpressionException("parser error in expression: '$expression'; [line: $line, character: $charPositionInLine ${offendingSymbol?.let { ", near: $it" } ?: ""} ]")
|
||||
@@ -1,33 +0,0 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
org.openrndr.extra.convention.`kotlin-jvm`
|
||||
antlr
|
||||
}
|
||||
|
||||
tasks.generateGrammarSource {
|
||||
maxHeapSize = "64m"
|
||||
arguments.addAll(listOf("-visitor", "-long-messages"))
|
||||
}
|
||||
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
antlr(libs.antlr.core)
|
||||
implementation(libs.antlr.runtime)
|
||||
implementation(libs.openrndr.application)
|
||||
implementation(libs.openrndr.math)
|
||||
implementation(libs.kotlin.coroutines)
|
||||
implementation(project(":orx-property-watchers"))
|
||||
implementation(project(":orx-noise"))
|
||||
testImplementation(libs.kluent)
|
||||
demoImplementation(project(":orx-jvm:orx-gui"))
|
||||
}
|
||||
|
||||
tasks.getByName("compileKotlin").dependsOn("generateGrammarSource")
|
||||
tasks.getByName("compileDemoKotlin").dependsOn("generateDemoGrammarSource")
|
||||
tasks.getByName("compileTestKotlin").dependsOn("generateTestGrammarSource")
|
||||
tasks.getByName("sourcesJar").dependsOn("generateGrammarSource")
|
||||
@@ -15,7 +15,7 @@ dependencies {
|
||||
implementation(libs.kotlin.reflect)
|
||||
implementation(project(":orx-noise"))
|
||||
implementation(project(":orx-easing"))
|
||||
api(project(":orx-jvm:orx-expression-evaluator"))
|
||||
api(project(":orx-expression-evaluator"))
|
||||
demoImplementation(project(":orx-jvm:orx-panel"))
|
||||
testImplementation(libs.kluent)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ tasks.test {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":orx-jvm:orx-expression-evaluator"))
|
||||
implementation(project(":orx-expression-evaluator"))
|
||||
implementation(libs.openrndr.application)
|
||||
implementation(libs.openrndr.math)
|
||||
implementation(libs.kotlin.coroutines)
|
||||
|
||||
@@ -27,7 +27,7 @@ include(
|
||||
"orx-jvm:orx-dnk3",
|
||||
"orx-easing",
|
||||
"orx-envelopes",
|
||||
"orx-jvm:orx-expression-evaluator",
|
||||
"orx-expression-evaluator",
|
||||
"orx-jvm:orx-file-watcher",
|
||||
"orx-parameters",
|
||||
"orx-fx",
|
||||
|
||||
Reference in New Issue
Block a user