introduces GeneratePrintVisitor which automatically generates the code for a syntax...
authorThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Thu, 5 Sep 2024 14:21:01 +0000 (14:21 +0000)
committerThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Thu, 5 Sep 2024 14:21:01 +0000 (14:21 +0000)
developer/executor/GeneratePrintVisitor [new file with mode: 0755]
developer/executor/GeneratePrintVisitorMethod [new file with mode: 0755]
developer/executor/env_build
developer/executor/makefile-project.mk
developer/executor/makefile-tool.mk
developer/executor/makefile-top.mk
developer/javac/Arithmetic_Syntax.java
developer/javac/GeneratePrintVisitor.java [new file with mode: 0644]
developer/javac/GeneratePrintVisitorMethod.java [new file with mode: 0644]

diff --git a/developer/executor/GeneratePrintVisitor b/developer/executor/GeneratePrintVisitor
new file mode 100755 (executable)
index 0000000..39d51ff
--- /dev/null
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+/var/user_data/Thomas-developer/GQL_to_Cypher/tool/jdk-22.0.1+8/bin/java -cp :/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm/GeneratePrintVisitor.jar GeneratePrintVisitor $@
diff --git a/developer/executor/GeneratePrintVisitorMethod b/developer/executor/GeneratePrintVisitorMethod
new file mode 100755 (executable)
index 0000000..17f323e
--- /dev/null
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+/var/user_data/Thomas-developer/GQL_to_Cypher/tool/jdk-22.0.1+8/bin/java -cp :/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/tool/executor/antlr-4.11.1-complete.jar:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm:/var/user_data/Thomas-developer/GQL_to_Cypher/developer/jvm/GeneratePrintVisitorMethod.jar GeneratePrintVisitorMethod $@
index 8779f1f..67adb33 100755 (executable)
@@ -44,6 +44,8 @@ fi
 export EXECUTOR_IN_FL="\
   RuleNameListRegx\
   RuleNameList\
+  GeneratePrintVisitorMethod\
+  GeneratePrintVisitor\
   ANTLRv4_RuleNameList\
   Arithmetic_Echo\
   Arithmetic_Echo__Test\
@@ -144,4 +146,4 @@ done
 export JAR_OUT_FPL
 
 
-#  LocalWords:  ANTLRv PrintRuleNameListRegx
+#  LocalWords:  ANTLRv PrintRuleNameListRegx RuleNameListRegx RuleNameList
index e623b33..6f7b660 100644 (file)
@@ -1,20 +1,21 @@
 #--------------------------------------------------------------------------------
-#  Project build
+# Project build
 #
+# GNU makefile
 
 # turn off implicit rules, because they can do unexpected things.
 .SUFFIXES:
 MAKEFLAGS += -r
 
-# Turns off the "feature" where `make` tries to make its makefiles as file targets. There
-# is no command line switch to turn this off.
+# `make` considers that PHONY targets do not correspond to files (other
+# targets do and the files have their dates checked). This declaration renders
+# innocuous the "feature" where `make` always tries to make its own
+# makefiles. There is no command line switch to turn this "feature" off.
 .PHONY: $(MAKEFILE_LIST)
 
 # 'make' has a "feature" where it deletes what it determines to be intermediate
-# files.  There is no command line switch to turn this behavior off. Combine
-# this feature with implicit rules to have loads of fun. At least this prevents
-# make from deleting its makefiles if it happens to decide one is an
-# intermediate file.
+# files. There is no command line switch to turn this "feature" off. Combine
+# this "feature" with implicit rules and have loads of fun.
 .PRECIOUS: $(MAKEFILE_LIST)
 
 #$(info makefile: $(MAKEFILE_LIST))
@@ -31,11 +32,16 @@ all: $(EXECUTOR_IN_FPL)
 
 
 #-----------------------------------------------
-# A utility for viewing all the rules in a grammar
+# These do not require antlr generated java files
 
 RuleNameListRegx: $(EXECUTOR_IN_DIR)/RuleNameListRegx
 RuleNameList: $(EXECUTOR_IN_DIR)/RuleNameList
 
+GeneratePrintVisitorMethod: $(EXECUTOR_IN_DIR)/GeneratePrintVisitorMethod
+GeneratePrintVisitor: $(EXECUTOR_IN_DIR)/GeneratePrintVisitor GeneratePrintVisitorMethod
+
+
+
 #-----------------------------------------------
 # Arithmetic
 
@@ -93,7 +99,6 @@ ANTLRv4_Syntax:\
        $(REMAKE) $(EXECUTOR_IN_DIR)/ANTLRv4_Syntax
 
 
-
 #-----------------------------------------------
 #  GQL_20240412
 
index 913d759..1e7e88c 100644 (file)
@@ -1,20 +1,21 @@
 #================================================================================
 # Build the tools that are needed for building the project.
 #
+# GNU makefile
 
 # turn off implicit rules, because they can do unexpected things.
 .SUFFIXES:
 MAKEFLAGS += -r
 
-# Turns off the "feature" where `make` tries to make its makefiles as file targets. There
-# is no command line switch to turn this off.
+# `make` considers that PHONY targets do not correspond to files (other
+# targets do and the files have their dates checked). This declaration renders
+# innocuous the "feature" where `make` always tries to make its own
+# makefiles. There is no command line switch to turn this "feature" off.
 .PHONY: $(MAKEFILE_LIST)
 
 # 'make' has a "feature" where it deletes what it determines to be intermediate
-# files.  There is no command line switch to turn this behavior off. Combine
-# this feature with implicit rules to have loads of fun. At least this prevents
-# make from deleting its makefiles if it happens to decide one is an
-# intermediate file.
+# files. There is no command line switch to turn this "feature" off. Combine
+# this "feature" with implicit rules and have loads of fun.
 .PRECIOUS: $(MAKEFILE_LIST)
 
 #$(info makefile: $(MAKEFILE_LIST))
index dc03a81..0642609 100644 (file)
@@ -1,20 +1,21 @@
 #================================================================================
 # top level makefile calls makefile-tool and makefile-project
 #
+# GNU makefile
 
 # turn off implicit rules, because they can do unexpected things.
 .SUFFIXES:
 MAKEFLAGS += -r
 
-# Turns off the "feature" where `make` tries to make its makefiles as file targets. There
-# is no command line switch to turn this off.
+# `make` considers that PHONY targets do not correspond to files (other
+# targets do and the files have their dates checked). This declaration renders
+# innocuous the "feature" where `make` always tries to make its own
+# makefiles. There is no command line switch to turn this "feature" off.
 .PHONY: $(MAKEFILE_LIST)
 
 # 'make' has a "feature" where it deletes what it determines to be intermediate
-# files.  There is no command line switch to turn this behavior off. Combine
-# this feature with implicit rules to have loads of fun. At least this prevents
-# make from deleting its makefiles if it happens to decide one is an
-# intermediate file.
+# files. There is no command line switch to turn this "feature" off. Combine
+# this "feature" with implicit rules and have loads of fun.
 .PRECIOUS: $(MAKEFILE_LIST)
 
 #$(info makefile: $(MAKEFILE_LIST))
index 9d1dd81..1f876e1 100644 (file)
@@ -18,6 +18,7 @@ public class Arithmetic_Syntax {
     boolean pretty_print = false;
     List<String> file_arg_list = new ArrayList<>();
     boolean has_error = false;
+    String usage = "Usage: Arithmetic_Syntax [-pp] <source-file>"
 
     // Parse the options and arguments
     for (String arg : arg_array) {
@@ -35,13 +36,13 @@ public class Arithmetic_Syntax {
 
     // If there were any errors, print usage and exit
     if (has_error) {
-      System.err.println("Usage: java Arithmetic_Syntax [-pp] <input-file>");
+      System.err.println(usage);
       System.exit(1);
     }
 
     // Ensure there is exactly one input file
     if (file_arg_list.size() != 1) {
-      System.err.println("Usage: java Arithmetic_Syntax [-pp] <input-file>");
+      System.err.println("usage");
       System.exit(1);
     }
 
diff --git a/developer/javac/GeneratePrintVisitor.java b/developer/javac/GeneratePrintVisitor.java
new file mode 100644 (file)
index 0000000..de99dda
--- /dev/null
@@ -0,0 +1,67 @@
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.tree.*;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+import java.io.PrintWriter;
+
+public class GeneratePrintVisitor {
+
+    public static void main(String[] args) throws IOException {
+        if (args.length != 2) {
+            System.err.println("Usage: java GeneratePrintVisitor <grammarFile> <outputFile>");
+            System.exit(1);
+        }
+
+        String grammarFile = args[0];
+        String outputFile = args[1];
+
+        // Extract the grammar name from the file name
+        String grammarName = Paths.get(grammarFile).getFileName().toString().replace(".g4", "");
+        String parserName = grammarName + "Parser";
+
+        // Parse the .g4 file
+        CharStream input = CharStreams.fromFileName(grammarFile);
+        ANTLRv4Lexer lexer = new ANTLRv4Lexer(input);
+        CommonTokenStream tokens = new CommonTokenStream(lexer);
+        ANTLRv4Parser parser = new ANTLRv4Parser(tokens);
+
+        // Extract rules
+        ParseTree tree = parser.grammarSpec();
+        List<String> ruleNames = extractRuleNames(parser);
+
+        // Template for the PrintVisitor class
+        String classTemplate = """
+            import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
+
+            public class PrintVisitor extends AbstractParseTreeVisitor<String> {
+                private final String[] ruleNames;
+
+                public PrintVisitor(String[] ruleNames) {
+                    this.ruleNames = ruleNames;
+                }
+
+                // Generated print methods
+            """;
+
+        // Generate and output the PrintVisitor class
+        try (PrintWriter writer = new PrintWriter(outputFile)) {
+            // Write the class template
+            writer.print(classTemplate);
+
+            // Generate and write the print methods
+            for (String ruleName : ruleNames) {
+                GeneratePrintVisitorMethod.generatePrintMethod(parserName, ruleName, writer);
+            }
+
+            // Close the class
+            writer.println("}");
+        }
+    }
+
+    private static List<String> extractRuleNames(Parser parser) {
+        // Extract rule names from the parser
+        return List.of(parser.getRuleNames());
+    }
+}
diff --git a/developer/javac/GeneratePrintVisitorMethod.java b/developer/javac/GeneratePrintVisitorMethod.java
new file mode 100644 (file)
index 0000000..6fb08d2
--- /dev/null
@@ -0,0 +1,44 @@
+import java.io.PrintWriter;
+
+public class GeneratePrintVisitorMethod {
+
+    public static void main(String[] args) {
+        if (args.length != 3) {
+            System.err.println("Usage: GeneratePrintVisitorMethod <parserName> <ruleName> <outputFile>");
+            System.exit(1);
+        }
+
+        String parserName = args[0];
+        String ruleName = args[1];
+        String outputFile = args[2];
+
+        try (PrintWriter writer = new PrintWriter(outputFile)) {
+            generatePrintMethod(parserName, ruleName, writer);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void generatePrintMethod(String parserName, String ruleName, PrintWriter writer) {
+        // Template for the print method using text blocks
+        String template = """
+            public String visit _______0_ (_______1_. _______0_ Context ctx) {
+                StringBuilder result = new StringBuilder();
+                result.append("_______0_(");
+                for (int i = 0; i < ctx.getChildCount(); i++) {
+                    if (i > 0) result.append(", ");
+                    result.append(visit(ctx.getChild(i)));
+                }
+                result.append(")");
+                return result.toString();
+            }
+            """;
+
+        // Fill in the blanks in the template
+        template = template.replace("_______0_", ruleName);
+        template = template.replace("_______1_", parserName);
+
+        // Write the template to the output file
+        writer.print(template);
+    }
+}