From: Thomas Walker Lynch Date: Thu, 5 Sep 2024 14:21:01 +0000 (+0000) Subject: introduces GeneratePrintVisitor which automatically generates the code for a syntax... X-Git-Url: https://git.reasoningtechnology.com/usr/lib/python2.7/functools.py?a=commitdiff_plain;h=bfa917d0d9ecb23e6eb995f6933bf6e351cecf81;p=GQL-to-Cypher introduces GeneratePrintVisitor which automatically generates the code for a syntax diagrammer print visitor --- diff --git a/developer/executor/GeneratePrintVisitor b/developer/executor/GeneratePrintVisitor new file mode 100755 index 0000000..39d51ff --- /dev/null +++ b/developer/executor/GeneratePrintVisitor @@ -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 index 0000000..17f323e --- /dev/null +++ b/developer/executor/GeneratePrintVisitorMethod @@ -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 $@ diff --git a/developer/executor/env_build b/developer/executor/env_build index 8779f1f..67adb33 100755 --- a/developer/executor/env_build +++ b/developer/executor/env_build @@ -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 diff --git a/developer/executor/makefile-project.mk b/developer/executor/makefile-project.mk index e623b33..6f7b660 100644 --- a/developer/executor/makefile-project.mk +++ b/developer/executor/makefile-project.mk @@ -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 diff --git a/developer/executor/makefile-tool.mk b/developer/executor/makefile-tool.mk index 913d759..1e7e88c 100644 --- a/developer/executor/makefile-tool.mk +++ b/developer/executor/makefile-tool.mk @@ -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)) diff --git a/developer/executor/makefile-top.mk b/developer/executor/makefile-top.mk index dc03a81..0642609 100644 --- a/developer/executor/makefile-top.mk +++ b/developer/executor/makefile-top.mk @@ -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)) diff --git a/developer/javac/Arithmetic_Syntax.java b/developer/javac/Arithmetic_Syntax.java index 9d1dd81..1f876e1 100644 --- a/developer/javac/Arithmetic_Syntax.java +++ b/developer/javac/Arithmetic_Syntax.java @@ -18,6 +18,7 @@ public class Arithmetic_Syntax { boolean pretty_print = false; List file_arg_list = new ArrayList<>(); boolean has_error = false; + String usage = "Usage: Arithmetic_Syntax [-pp] " // 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] "); + 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] "); + System.err.println("usage"); System.exit(1); } diff --git a/developer/javac/GeneratePrintVisitor.java b/developer/javac/GeneratePrintVisitor.java new file mode 100644 index 0000000..de99dda --- /dev/null +++ b/developer/javac/GeneratePrintVisitor.java @@ -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 "); + 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 ruleNames = extractRuleNames(parser); + + // Template for the PrintVisitor class + String classTemplate = """ + import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + + public class PrintVisitor extends AbstractParseTreeVisitor { + 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 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 index 0000000..6fb08d2 --- /dev/null +++ b/developer/javac/GeneratePrintVisitorMethod.java @@ -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 "); + 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); + } +}