();
+ for (var dir : sourceDirectories_) {
+ if (dir.exists() && dir.isDirectory()) {
+ var files = dir.listFiles((dir1, name) -> name.endsWith(".g") || name.endsWith(".g4"));
+ if (files != null) {
+ for (var file : files) {
+ sources.add(file.getAbsolutePath());
+ }
+ }
+ }
+ }
+ for (var file : sourceFiles_) {
+ if (file.exists()) {
+ sources.add(file.getAbsolutePath());
+ }
+ }
+
+ if (sources.isEmpty()) {
+ throw new IllegalArgumentException("ERROR: no ANTLR grammars found");
+ }
+
+ var arguments = new ArrayList<>(arguments_);
+
+ if (libDirectory_ != null) {
+ arguments.add("-lib");
+ arguments.add(libDirectory_.getAbsolutePath());
+ }
+ if (outputDirectory_ != null) {
+ arguments.add("-o");
+ arguments.add(outputDirectory_.getAbsolutePath());
+ }
+ if (listener_ != null) {
+ if (listener_) {
+ arguments.add("-listener");
+ } else {
+ arguments.add("-no-listener");
+ }
+ }
+
+ if (visitor_ != null) {
+ if (visitor_) {
+ arguments.add("-visitor");
+ } else {
+ arguments.add("-no-visitor");
+ }
+ }
+ arguments.addAll(sources);
+
+ var argument_array = new String[arguments.size()];
+ arguments.toArray(argument_array);
+ new Tool(argument_array).processGrammarsOnCommandLine();
+ }
+
+ /**
+ * Provides additional arguments for the antlr operation.
+ *
+ * The following additional arguments are supported:
+ *
+ * -atn | generate rule augmented transition network diagrams |
+ * -D<option>=value | set/override a grammar-level option |
+ * -Werror | treat warnings as errors" |
+ * -XdbgST | launch StringTemplate visualizer on generated code |
+ * -XdbgSTWait | wait for STViz to close before continuing |
+ * -Xforce-atn | use the ATN simulator for all predictions |
+ * -Xlog | dump lots of logging info to antlr-timestamp.log |
+ * -Xexact-output-dir | all output goes into -o dir regardless of paths/package |
+ *
+ *
+ * @param arguments the additional arguments
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation arguments(String... arguments) {
+ arguments_.addAll(Arrays.asList(arguments));
+ return this;
+ }
+
+ /**
+ * Provides additional arguments for the antlr operation.
+ *
+ * See {@link #arguments(String...)} for details.
+ *
+ * @param arguments the additional arguments
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation arguments(List arguments) {
+ arguments_.addAll(arguments);
+ return this;
+ }
+
+ /**
+ * Provides the source directories that will be used for the antlr operation.
+ *
+ * @param directories the source directories
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation sourceDirectories(List directories) {
+ sourceDirectories_.addAll(directories);
+ return this;
+ }
+
+ /**
+ * Provides the source files that will be used for the antlr operation.
+ *
+ * @param files the source files
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation sourceFiles(List files) {
+ sourceFiles_.addAll(files);
+ return this;
+ }
+
+ /**
+ * Provides the output directory where all output is generated.
+ *
+ * @param directory the output directory
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation outputDirectory(File directory) {
+ outputDirectory_ = directory;
+ return this;
+ }
+
+ /**
+ * Provides the location of grammars and tokens files.
+ *
+ * @param directory the lib directory
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation libDirectory(File directory) {
+ libDirectory_ = directory;
+ return this;
+ }
+
+ /**
+ * Provides grammar file encoding; e.g., euc-jp.
+ *
+ * @param encoding the encoding
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation grammarEncoding(String encoding) {
+ arguments("-encoding", encoding);
+ return this;
+ }
+
+ /**
+ * Specify output style for messages in antlr, gnu, vs2005.
+ *
+ * @param format the output styke
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation msgFormat(String format) {
+ arguments("-message-format", format);
+ return this;
+ }
+
+ /**
+ * Show exception details when available for errors and warnings.
+ *
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation longMessages() {
+ arguments("-long-messages");
+ return this;
+ }
+
+ /**
+ * Generate parse tree listener (default).
+ *
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation listener() {
+ listener_ = true;
+ return this;
+ }
+
+ /**
+ * Don't generate parse tree listener.
+ *
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation noListener() {
+ listener_ = false;
+ return this;
+ }
+
+ /**
+ * Generate parse tree visitor.
+ *
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation visitor() {
+ visitor_ = true;
+ return this;
+ }
+
+ /**
+ * Don't generate parse tree visitor (default).
+ *
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation noVisitor() {
+ visitor_ = false;
+ return this;
+ }
+
+ /**
+ * Specify a package/namespace for the generated code
+ *
+ * @param pkg the package name
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation pkg(String pkg) {
+ arguments("-package", pkg);
+ return this;
+ }
+
+ /**
+ * Generate file dependencies.
+ *
+ * @return this operation instance
+ * @since 1.0
+ */
+ public Antlr4Operation depend() {
+ arguments("-depend");
+ return this;
+ }
+
+ /**
+ * Retrieves the list of arguments that will be used for the
+ * antlr operation.
+ *
+ * This is a modifiable list that can be retrieved and changed.
+ *
+ * @return the arguments
+ * @since 1.0
+ */
+ public List arguments() {
+ return arguments_;
+ }
+
+ /**
+ * Retrieves the list of source directories that will be used for the
+ * antlr operation.
+ *
+ * This is a modifiable list that can be retrieved and changed.
+ *
+ * @return the source directories
+ * @since 1.0
+ */
+ public List sourceDirectories() {
+ return sourceDirectories_;
+ }
+
+ /**
+ * Retrieves the list of source files that will be used for the
+ * antlr operation.
+ *
+ * This is a modifiable list that can be retrieved and changed.
+ *
+ * @return the source files
+ * @since 1.0
+ */
+ public List sourceFiles() {
+ return sourceFiles_;
+ }
+
+ /**
+ * Retrieves the output directory where all output is generated.
+ *
+ * @return the output directory; or
+ * * {@code null} if the directory wasn't specified
+ * @since 1.0
+ */
+ public File outputDirectory() {
+ return outputDirectory_;
+ }
+
+ /**
+ * Retrieves the location of grammars and tokens files.
+ *
+ * @return the lib directory; or
+ * {@code null} if the directory wasn't specified
+ * @since 1.0
+ */
+ public File libDirectory() {
+ return libDirectory_;
+ }
+}
\ No newline at end of file
diff --git a/src/test/antlr/ArrayInit.g4 b/src/test/antlr/ArrayInit.g4
new file mode 100644
index 0000000..7c536c2
--- /dev/null
+++ b/src/test/antlr/ArrayInit.g4
@@ -0,0 +1,8 @@
+grammar ArrayInit;
+
+init : '{' value (',' value)* '}' ;
+value : init
+ | INT
+ ;
+INT : [0-9]+ ;
+WS : [ \t\r\n]+ -> skip ;
\ No newline at end of file
diff --git a/src/test/java/rife/bld/extension/Antlr4Test.java b/src/test/java/rife/bld/extension/Antlr4Test.java
new file mode 100644
index 0000000..3a0c06d
--- /dev/null
+++ b/src/test/java/rife/bld/extension/Antlr4Test.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ */
+package rife.bld.extension;
+
+import org.junit.jupiter.api.Test;
+import rife.resources.ResourceFinder;
+import rife.resources.ResourceFinderClasspath;
+import rife.tools.FileUtils;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class Antlr4Test {
+ @Test
+ void testInstantiation() {
+ var operation = new Antlr4Operation();
+ assertTrue(operation.arguments().isEmpty());
+ assertTrue(operation.sourceDirectories().isEmpty());
+ assertTrue(operation.sourceFiles().isEmpty());
+ assertNull(operation.libDirectory());
+ assertNull(operation.outputDirectory());
+ }
+
+ @Test
+ void testGenerateGrammar()
+ throws Exception {
+ var tmp = Files.createTempDirectory("test").toFile();
+ try {
+ assertEquals("", FileUtils.generateDirectoryListing(tmp));
+ new Antlr4Operation()
+ .sourceFiles(List.of(new File(ResourceFinderClasspath.instance().getResource("ArrayInit.g4").toURI())))
+ .outputDirectory(tmp)
+ .execute();
+ assertEquals("""
+ /ArrayInit.interp
+ /ArrayInit.tokens
+ /ArrayInitBaseListener.java
+ /ArrayInitLexer.interp
+ /ArrayInitLexer.java
+ /ArrayInitLexer.tokens
+ /ArrayInitListener.java
+ /ArrayInitParser.java""", FileUtils.generateDirectoryListing(tmp));
+ } finally {
+ FileUtils.deleteDirectory(tmp);
+ }
+ }
+}