Skip to content

Commit

Permalink
gen parser plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
datYori committed May 7, 2024
1 parent c0ab520 commit 99d05c6
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 143 deletions.
134 changes: 18 additions & 116 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -104,75 +104,23 @@ lazy val sources = (project in file("sources"))
)
)

val generateSnapiParser = taskKey[Unit]("Generated antlr4 base SNAPI parser and lexer")

lazy val snapiParser = (project in file("snapi-parser"))
.enablePlugins(GenParserPlugin)
.settings(
commonSettings,
commonCompileSettings,
javaSrcBasePath := s"${baseDirectory.value}/src/main/java",
parserDefinitions := List(
(s"${javaSrcBasePath.value}/raw/compiler/rql2/generated",
"raw.compiler.rql2.generated",
s"${javaSrcBasePath.value}/raw/snapi/grammar",
"Snapi")
),
Compile / doc := { file("/dev/null") },
compileOrder := CompileOrder.JavaThenScala,
libraryDependencies ++= Seq(
antlr4Runtime
),
generateSnapiParser := {
// List of output paths
val basePath: String = s"${baseDirectory.value}/src/main/java"
val parsers = List(
(
s"$basePath/raw/compiler/rql2/generated",
"raw.compiler.rql2.generated",
s"$basePath/raw/snapi/grammar",
"Snapi"
)
)
def deleteRecursively(file: File): Unit = {
if (file.isDirectory) {
file.listFiles.foreach(deleteRecursively)
}
if (file.exists && !file.delete()) {
throw new IOException(s"Failed to delete ${file.getAbsolutePath}")
}
}
val s: TaskStreams = streams.value
parsers.foreach(parser => {
val outputPath = parser._1
val file = new File(outputPath)
if (file.exists()) {
deleteRecursively(file)
}
val packageName: String = parser._2
val jarName = "antlr-4.12.0-complete.jar"
val command: String = s"java -jar $basePath/antlr4/$jarName -visitor -package $packageName -o $outputPath"
val output = new StringBuilder
val logger = ProcessLogger(
(o: String) => output.append(o + "\n"), // for standard output
(e: String) => output.append(e + "\n") // for standard error
)
val grammarPath = parser._3
val grammarName = parser._4
val lexerResult = s"$command $grammarPath/${grammarName}Lexer.g4".!(logger)
if (lexerResult == 0) {
s.log.info("Lexer code generated successfully")
} else {
s.log.error("Lexer code generation failed with exit code " + lexerResult)
s.log.error("Output:\n" + output.toString)
}
val parserResult = s"$command $grammarPath/${grammarName}Parser.g4".!(logger)
if (parserResult == 0) {
s.log.info("Parser code generated successfully")
} else {
s.log.error("Parser code generation failed with exit code " + lexerResult)
s.log.error("Output:\n" + output.toString)
}
})
},
Compile / compile := (Compile / compile).dependsOn(generateSnapiParser).value,
Compile / doc := (Compile / doc).dependsOn(generateSnapiParser).value,
Test / compile := (Test / compile).dependsOn(generateSnapiParser).value,
publish := (publish dependsOn generateSnapiParser).value,
publishLocal := (publishLocal dependsOn generateSnapiParser).value,
publishSigned := (publishSigned dependsOn generateSnapiParser).value
)

lazy val snapiFrontend = (project in file("snapi-frontend"))
Expand Down Expand Up @@ -285,70 +233,24 @@ lazy val snapiClient = (project in file("snapi-client"))
testSettings
)

val generateSqlParser = taskKey[Unit]("Generated antlr4 base SQL parser and lexer")

lazy val sqlParser = (project in file("sql-parser"))
.enablePlugins(GenParserPlugin)
.settings(
commonSettings,
commonCompileSettings,
javaSrcBasePath := s"${baseDirectory.value}/src/main/java",
parserDefinitions := List(
(s"${javaSrcBasePath.value}/raw/client/sql/generated",
"raw.client.sql.generated",
s"${javaSrcBasePath.value}/raw/psql/grammar",
"Psql")
),
Compile / doc := { file("/dev/null") },
compileOrder := CompileOrder.JavaThenScala,
libraryDependencies ++= Seq(
antlr4Runtime
),
generateSqlParser := {
// List of output paths
val basePath: String = s"${baseDirectory.value}/src/main/java"
val parsers = List(
(s"$basePath/raw/client/sql/generated", "raw.client.sql.generated", s"$basePath/raw/psql/grammar", "Psql")
)
def deleteRecursively(file: File): Unit = {
if (file.isDirectory) {
file.listFiles.foreach(deleteRecursively)
}
if (file.exists && !file.delete()) {
throw new IOException(s"Failed to delete ${file.getAbsolutePath}")
}
}
val s: TaskStreams = streams.value
parsers.foreach(parser => {
val outputPath = parser._1
val file = new File(outputPath)
if (file.exists()) {
deleteRecursively(file)
}
val packageName: String = parser._2
val jarName = "antlr-4.12.0-complete.jar"
val command: String = s"java -jar $basePath/antlr4/$jarName -visitor -package $packageName -o $outputPath"
val output = new StringBuilder
val logger = ProcessLogger(
(o: String) => output.append(o + "\n"), // for standard output
(e: String) => output.append(e + "\n") // for standard error
)
val grammarPath = parser._3
val grammarName = parser._4
val lexerResult = s"$command $grammarPath/${grammarName}Lexer.g4".!(logger)
if (lexerResult == 0) {
s.log.info("Lexer code generated successfully")
} else {
s.log.error("Lexer code generation failed with exit code " + lexerResult)
s.log.error("Output:\n" + output.toString)
}
val parserResult = s"$command $grammarPath/${grammarName}Parser.g4".!(logger)
if (parserResult == 0) {
s.log.info("Parser code generated successfully")
} else {
s.log.error("Parser code generation failed with exit code " + lexerResult)
s.log.error("Output:\n" + output.toString)
}
})
},
Compile / compile := (Compile / compile).dependsOn(generateSqlParser).value,
Compile / doc := (Compile / doc).dependsOn(generateSqlParser).value,
Test / compile := (Test / compile).dependsOn(generateSqlParser).value,
publish := (publish dependsOn generateSqlParser).value,
publishLocal := (publishLocal dependsOn generateSqlParser).value,
publishSigned := (publishSigned dependsOn generateSqlParser).value
antlr4Runtime,
)
)

lazy val sqlClient = (project in file("sql-client"))
Expand Down
2 changes: 2 additions & 0 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ object Dependencies {
// from snapi-parser
val antlr4Runtime = "org.antlr" % "antlr4-runtime" % "4.12.0"

val antlr4 = "org.antlr" % "antlr4-maven-plugin" % "4.12.0"

// from snapi-frontend
val kiamaVersion = IO.read(new File("./deps/kiama/version")).trim
val kiama = "org.bitbucket.inkytonik.kiama" %% "kiama" % kiamaVersion
Expand Down
52 changes: 25 additions & 27 deletions project/GeneratePlugin.scala → project/GenParserPlugin.scala
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
package raw.build

import sbt._
import sbt.Keys._
import scala.sys.process._
import sbt.{ Def, _ }

import com.jsuereth.sbtpgp.PgpKeys.{publishSigned}
import sbt.plugins.JvmPlugin
import java.io.IOException
import scala.sys.process._

import com.jsuereth.sbtpgp.PgpKeys.{publishSigned}

object Generate extends AutoPlugin {
// Task keys
val generateParser = taskKey[Unit]("Generated antlr4 base parser and lexer")
object GenParserPlugin extends AutoPlugin {
override def requires = JvmPlugin
override def trigger: PluginTrigger = noTrigger

// Task keys
object autoImport {
val generateParser = taskKey[Unit]("Generated antlr4 base parser and lexer")
val parserDefinitions = settingKey[List[(String, String, String, String)]]("List of parser definitions with output path first followed by the name of the generated package")
val javaSrcBasePath = settingKey[String]("Java src relative path")
}

// Automatically enable this plugin (set to noTrigger if you want to enable it manually)
override def trigger = noTrigger
import autoImport._

// Provide default settings
override def projectSettings: Seq[Def.Setting[_]] = Seq(
generateParser := {

// List of output paths
val basePath: String = s"${baseDirectory.value}/src/main/java"
val parsers = List(
(s"${basePath}/raw/compiler/rql2/generated", "raw.compiler.rql2.generated", s"$basePath/raw/snapi/grammar", "Snapi"),
)

generateParser := {
val basePath: String = javaSrcBasePath.value
val parsers = parserDefinitions.value
def deleteRecursively(file: File): Unit = {
if (file.isDirectory) {
file.listFiles.foreach(deleteRecursively)
Expand All @@ -33,41 +36,30 @@ object Generate extends AutoPlugin {
throw new IOException(s"Failed to delete ${file.getAbsolutePath}")
}
}

val s: TaskStreams = streams.value

parsers.foreach(parser => {

val outputPath = parser._1

val file = new File(outputPath)
if (file.exists()) {
deleteRecursively(file)
}

val packageName: String = parser._2

val jarName = "antlr-4.12.0-complete.jar"

val command: String = s"java -jar $basePath/antlr4/$jarName -visitor -package $packageName -o $outputPath"

val output = new StringBuilder
val logger = ProcessLogger(
(o: String) => output.append(o + "\n"), // for standard output
(e: String) => output.append(e + "\n") // for standard error
)

val grammarPath = parser._3
val grammarName = parser._4

val lexerResult = s"$command $grammarPath/${grammarName}Lexer.g4".!(logger)
if (lexerResult == 0) {
s.log.info("Lexer code generated successfully")
} else {
s.log.error("Lexer code generation failed with exit code " + lexerResult)
s.log.error("Output:\n" + output.toString)
}

val parserResult = s"$command $grammarPath/${grammarName}Parser.g4".!(logger)
if (parserResult == 0) {
s.log.info("Parser code generated successfully")
Expand All @@ -76,6 +68,12 @@ object Generate extends AutoPlugin {
s.log.error("Output:\n" + output.toString)
}
})
}
},
parserDefinitions := List(),
javaSrcBasePath := "",
Compile / compile := (Compile / compile).dependsOn(generateParser).value,
Test / test := (Test / test).dependsOn(generateParser).value,
publish := publish.dependsOn(generateParser).value,
publishSigned := publishSigned.dependsOn(generateParser).value
)
}

0 comments on commit 99d05c6

Please sign in to comment.