PrintRuleNameList handles multiline rules SyntaxTree_Arithmetic test with Visitor...
authorThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Sun, 11 Aug 2024 08:50:57 +0000 (08:50 +0000)
committerThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Sun, 11 Aug 2024 08:50:57 +0000 (08:50 +0000)
16 files changed:
developer/ANTLR/Arithmetic.g4 [new file with mode: 0644]
developer/ANTLR/GQL_test.g4 [deleted file]
developer/deprecated/makefile3 [new file with mode: 0644]
developer/deprecated/makefile4 [new file with mode: 0644]
developer/executor/PrintRuleNameList
developer/executor/Test__SyntaxTree_Arithmetic [new file with mode: 0755]
developer/executor/env_build
developer/executor/make
developer/javac/PrintRuleNameList.java
developer/javac/PrintVisitor.java
developer/javac/PrintVisitor_orig.java [new file with mode: 0644]
developer/javac/SyntaxTree_20240412.java
developer/javac/SyntaxTree_Arithmetic.java [new file with mode: 0644]
developer/javac/TestBench.java [new file with mode: 0644]
developer/javac/Test__SyntaxTree_Arithmetic.java [new file with mode: 0644]
developer/makefile

diff --git a/developer/ANTLR/Arithmetic.g4 b/developer/ANTLR/Arithmetic.g4
new file mode 100644 (file)
index 0000000..4a61ec4
--- /dev/null
@@ -0,0 +1,14 @@
+grammar Arithmetic;
+
+program:   expression EOF;
+
+expression
+    : expression ('*'|'/') expression
+    | expression ('+'|'-') expression
+    | '(' expression ')'
+    | INT
+    ;
+
+INT: [0-9]+;
+
+WS: [ \t\r\n]+ -> skip;
diff --git a/developer/ANTLR/GQL_test.g4 b/developer/ANTLR/GQL_test.g4
deleted file mode 100644 (file)
index 19cc208..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-grammar GQL_test;
-
-root: query+ EOF;
-
-query: '{' field+ '}';
-
-field: ID ':' value;
-
-value: STRING | number;
-
-number: INT | FLOAT;
-
-ID: [a-zA-Z_][a-zA-Z_0-9]*;
-STRING: '"' .*? '"';
-INT: [0-9]+;
-FLOAT: [0-9]+ '.' [0-9]+;
-WS: [ \t\n\r]+ -> skip;
diff --git a/developer/deprecated/makefile3 b/developer/deprecated/makefile3
new file mode 100644 (file)
index 0000000..251ac90
--- /dev/null
@@ -0,0 +1,84 @@
+#================================================================================
+# Make targets
+#
+
+all: setup $(PROGRAM_FPL)
+
+SyntaxTree_Test: $(ANTLR_OUT_GQL_Test_FPL)
+       make $(PROGRAM_SyntaxTree_Test)
+
+SyntaxTree_20240412: $(ANTLR_OUT_GQL_20240412_FPL)
+       make $(PROGRAM_SyntaxTree_20240412)
+
+PrintRuleNameList: $(PROGRAM_PrintRuleNameList)
+
+grammar: setup $(ANTLR_OUT_FPL)
+
+# Compile all the .java files.
+java: setup $(JAVA_COMP_OUT_FPL)
+
+# Specific grammar targets. Run them like this:
+# > make <grammar_name>
+# e.g. > make GQL_test
+$(foreach grammar,$(ANTLR_GRAMMAR_LIST),$(eval $(grammar): $(value ANTLR_OUT_$(grammar)_FPL)))
+
+.PHONY: version
+version:
+       $(info ANTLR_JAR is '$(notdir $(ANTLR_JAR))')
+       @ $(JAVA_COMP) --version
+       @ $(JAVA_ARCHIVE) --version
+       @ make -v | head -n 1
+       @ echo "makefile 0.2"
+
+.PHONY: setup
+# ANTLR automatically creates $(ANTLR_OUT_DIR)
+setup:
+       mkdir -p $(ANTLR_IN_DIR) $(JAVA_COMP_IN_PRIMARY_DIR) $(JVM_IN_DIR)
+       mkdir -p executor test deprecated experiment documentation temporary 
+
+# Default clean target
+.PHONY: setup
+clean:
+       @echo "Use the clean script from the executor directory instead of \`make clean\`"
+       @executor/clean
+
+#useful for distinguishing initial make error messages and message generated by rules firing
+nothing:
+       @:
+
+#================================================================================
+# recipes
+
+# Without this, GNU make deletes .jar files after making them.
+# Surely this is part of a spat between GNU and Sun Microsysitems, where they
+# now produce tools that delete each others files ;-)
+.PRECIOUS: $(JAVA_COMP_OUT_DIR)/%.jar
+
+$(ANTLR_OUT_DIR)/%Lexer.java \
+$(ANTLR_OUT_DIR)/%Parser.java \
+$(ANTLR_OUT_DIR)/%BaseVisitor.java \
+$(ANTLR_OUT_DIR)/%Visitor.java: $(ANTLR_IN_DIR)/%.g4
+       @echo "making grammar from:" $<
+       $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
+
+# Rule to build .class files from .java files
+$(JAVA_COMP_OUT_DIR)/%.class: $(JAVA_COMP_IN_PRIMARY_DIR)/%.java
+       @echo "Compiling $<..."
+       $(JAVA_COMP) -d $(JAVA_COMP_OUT_DIR) -sourcepath $(JAVA_COMP_IN_DL) $<
+       @echo "Created $@"
+
+# Rule to build .jar files from .class files
+$(JAVA_COMP_OUT_DIR)/%.jar: $(JAVA_COMP_OUT_DIR)/%.class
+       @echo "Building $*..."
+       $(JAVA_ARCHIVE) cf $@ -C $(JAVA_COMP_OUT_DIR) $*.class
+       @echo "Created $@"
+
+# Rule to create executable scripts from .jar files
+executor/%: $(JAVA_COMP_OUT_DIR)/%.jar
+       @echo "Creating script for $*..."
+       @echo "#!/usr/bin/env bash" > executor/$*
+       @echo "$(JAVA_INTERP) -cp $< $*" \$$\@ >> executor/$*
+       chmod +x executor/$*
+       @echo "Created script executor/$*"
+
+
diff --git a/developer/deprecated/makefile4 b/developer/deprecated/makefile4
new file mode 100644 (file)
index 0000000..288194f
--- /dev/null
@@ -0,0 +1,102 @@
+# Makefile version 0.2.6cp
+
+#================================================================================
+# recipes
+
+# Without this, GNU make deletes .jar files after making them.
+# Surely this is part of a spat between GNU and Sun Microsysitems, where they
+# now produce tools that delete each others files ;-)
+.PRECIOUS: $(JAVA_COMP_OUT_DIR)/%.jar
+
+# Rule to generate grammar files from .g4 files
+$(ANTLR_OUT_DIR)/GQL_20240412Lexer.java: $(ANTLR_IN_PRIMARY_DIR)/GQL_20240412.g4
+       @echo "making grammar from:" $<
+       $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
+
+$(ANTLR_OUT_DIR)/GQL_20240412Parser.java: $(ANTLR_IN_PRIMARY_DIR)/GQL_20240412.g4
+       @echo "making grammar from:" $<
+       $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
+
+$(ANTLR_OUT_DIR)/GQL_20240412BaseVisitor.java: $(ANTLR_IN_PRIMARY_DIR)/GQL_20240412.g4
+       @echo "making grammar from:" $<
+       $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
+
+$(ANTLR_OUT_DIR)/GQL_20240412Visitor.java: $(ANTLR_IN_PRIMARY_DIR)/GQL_20240412.g4
+       @echo "making grammar from:" $<
+       $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
+
+$(ANTLR_OUT_DIR)/GQL_testLexer.java: $(ANTLR_IN_PRIMARY_DIR)/GQL_test.g4
+       @echo "making grammar from:" $<
+       $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
+
+$(ANTLR_OUT_DIR)/GQL_testParser.java: $(ANTLR_IN_PRIMARY_DIR)/GQL_test.g4
+       @echo "making grammar from:" $<
+       $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
+
+$(ANTLR_OUT_DIR)/GQL_testBaseVisitor.java: $(ANTLR_IN_PRIMARY_DIR)/GQL_test.g4
+       @echo "making grammar from:" $<
+       $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
+
+$(ANTLR_OUT_DIR)/GQL_testVisitor.java: $(ANTLR_IN_PRIMARY_DIR)/GQL_test.g4
+       @echo "making grammar from:" $<
+       $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
+
+# Rule to build .class files from .java files in both primary and ANTLR directories
+$(JAVA_COMP_OUT_DIR)/%.class: $(JAVA_COMP_IN_PRIMARY_DIR)/%.java $(JAVA_COMP_IN_ANTLR_DIR)/%.java
+       @echo "Compiling $<..."
+       $(JAVA_COMP) -d $(JAVA_COMP_OUT_DIR) -sourcepath $(JAVA_COMP_IN_DL) $<
+       @echo "Created $@"
+
+# Rule to build .jar files from .class files
+$(JAVA_COMP_OUT_DIR)/%.jar: $(JAVA_COMP_OUT_DIR)/%.class
+       @echo "Building $*..."
+       $(JAVA_ARCHIVE) cf $@ -C $(JAVA_COMP_OUT_DIR) $*.class
+       @echo "Created $@"
+
+# Rule to create executable scripts from .jar files
+executor/%: $(JAVA_COMP_OUT_DIR)/%.jar
+       @echo "Creating script for $*..."
+       @echo "#!/usr/bin/env bash" > executor/$*
+       @echo "$(JAVA_INTERP) -cp $< $*" \$$\@ >> executor/$*
+       chmod +x executor/$*
+       @echo "Created script executor/$*"
+
+# Default target
+all: setup $(PROGRAM_FPL)
+
+SyntaxTree_Test: $(ANTLR_OUT_GQL_Test_FPL)
+       make $(PROGRAM_SyntaxTree_Test)
+
+SyntaxTree_20240412: $(ANTLR_OUT_DIR)/GQL_20240412Lexer.java $(ANTLR_OUT_DIR)/GQL_20240412Parser.java $(ANTLR_OUT_DIR)/GQL_20240412BaseVisitor.java $(ANTLR_OUT_DIR)/GQL_20240412Visitor.java
+       make $(PROGRAM_SyntaxTree_20240412)
+
+PrintRuleNameList: $(PROGRAM_PrintRuleNameList)
+
+grammar: setup $(ANTLR_OUT_DIR)/GQL_20240412Lexer.java $(ANTLR_OUT_DIR)/GQL_20240412Parser.java $(ANTLR_OUT_DIR)/GQL_20240412BaseVisitor.java $(ANTLR_OUT_DIR)/GQL_20240412Visitor.java $(ANTLR_OUT_DIR)/GQL_testLexer.java $(ANTLR_OUT_DIR)/GQL_testParser.java $(ANTLR_OUT_DIR)/GQL_testBaseVisitor.java $(ANTLR_OUT_DIR)/GQL_testVisitor.java
+
+# Compile all the .java files.
+java: setup $(JAVA_COMP_OUT_FPL)
+
+.PHONY: version
+version:
+       $(info ANTLR_JAR is '$(notdir $(ANTLR_JAR))')
+       @ $(JAVA_COMP) --version
+       @ $(JAVA_ARCHIVE) --version
+       @ make -v | head -n 1
+       @ echo "makefile 0.2.6cp"
+
+.PHONY: setup
+# ANTLR automatically creates $(ANTLR_OUT_DIR)
+setup:
+       mkdir -p $(ANTLR_IN_PRIMARY_DIR) $(JAVA_COMP_IN_PRIMARY_DIR) $(JVM_IN_DIR)
+       mkdir -p executor test deprecated experiment documentation temporary 
+
+# Default clean target
+.PHONY: clean
+clean:
+       @echo "Use the clean script from the executor directory instead of \`make clean\`"
+       @executor/clean
+
+# Useful for distinguishing initial make error messages and message generated by rules firing
+nothing:
+       @:
index bc89c04..598e6a2 100755 (executable)
@@ -1,2 +1,2 @@
 #!/usr/bin/env bash
-/var/user_data/Thomas-developer/GQL_to_Cypher/tool/jdk-22.0.1+8/bin/java -cp jvm/PrintRuleNameList.jar PrintRuleNameList $@
+/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/tool/executor/antlr-4.11.1-complete.jar:jvm:jvm/PrintRuleNameList.jar PrintRuleNameList $@
diff --git a/developer/executor/Test__SyntaxTree_Arithmetic b/developer/executor/Test__SyntaxTree_Arithmetic
new file mode 100755 (executable)
index 0000000..038b1ad
--- /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/tool/executor/antlr-4.11.1-complete.jar:jvm:jvm/Test__SyntaxTree_Arithmetic.jar Test__SyntaxTree_Arithmetic $@
index 5d353ae..8e10c74 100755 (executable)
@@ -48,11 +48,12 @@ export CLASSPATH="$ANTLR_JAR"
 # to be built
 #
 export PROGRAM_PrintRuleNameList="executor/PrintRuleNameList"
-export PROGRAM_SyntaxTree_Test="executor/SyntaxTree_Test"
+export PROGRAM_SyntaxTree_Arithmetic="executor/SyntaxTree_Arithmetic"
+export PROGRAM_Test__SyntaxTree_Arithmetic="executor/Test__SyntaxTree_Arithmetic"
 export PROGRAM_SyntaxTree_20240412="executor/SyntaxTree_20240412"
 
 # an all programs list
-export PROGRAM_FPL="${PROGRAM_PrintRuleNameList} ${PROGRAM_SyntaxTree_Test} ${PROGRAM_SyntaxTree_20240412}"
+export PROGRAM_FPL="${PROGRAM_PrintRuleNameList} ${PROGRAM_SyntaxTree_Arithmetic} ${PROGRAM_SyntaxTree_20240412} ${PROGRAM_Test__SyntaxTree_Arithmetic}"
 
 #--------------------------------------------------------------------------------
 # misc
index 94e85a0..9f3cd80 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
 cd "$DEVELOPER_HOME" || { echo "Failed to change directory to" "$DEVELOPER_HOME"; exit 1; }
-
+source executor/env_build
 /usr/bin/make --no-builtin-rules --keep-going $@
 
index 7d82992..6c58e64 100644 (file)
@@ -22,14 +22,18 @@ public class PrintRuleNameList {
     Set<String> ruleNames = new HashSet<>();
 
     try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
+      StringBuilder content = new StringBuilder();
       String line;
-      Pattern rulePattern = Pattern.compile("^([a-zA-Z_][a-zA-Z0-9_]*)\\s*:");
-
       while ((line = br.readLine()) != null) {
-        Matcher matcher = rulePattern.matcher(line);
-        if (matcher.find()) {
-          ruleNames.add(matcher.group(1));
-        }
+        content.append(line).append("\n");
+      }
+
+      // Updated pattern to handle multi-line rules
+      Pattern rulePattern = Pattern.compile("(?m)^\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*:");
+
+      Matcher matcher = rulePattern.matcher(content.toString());
+      while (matcher.find()) {
+        ruleNames.add(matcher.group(1));
       }
 
       System.out.println("Extracted Rules:");
index 3001677..c5a7d4a 100644 (file)
@@ -1,7 +1,6 @@
-import org.antlr.v4.runtime.tree.*;
-import org.antlr.v4.runtime.RuleContext;
+import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
 
-public class PrintVisitor extends AbstractParseTreeVisitor<String> implements GQL_20240412Visitor<String> {
+public class PrintVisitor extends ArithmeticBaseVisitor<String> {
   private final String[] ruleNames;
 
   public PrintVisitor(String[] ruleNames) {
@@ -9,250 +8,24 @@ public class PrintVisitor extends AbstractParseTreeVisitor<String> implements GQ
   }
 
   @Override
-  public String visit(ParseTree tree) {
-    if (tree instanceof TerminalNode) {
-      return tree.getText();
-    }
-
-    StringBuilder sb = new StringBuilder();
-    String ruleName = ruleNames[((RuleContext) tree).getRuleIndex()];
-    sb.append(ruleName).append("(");
-
-    for (int i = 0; i < tree.getChildCount(); i++) {
-      sb.append(visit(tree.getChild(i)));
-      if (i < tree.getChildCount() - 1) {
-        sb.append(" ");
-      }
-    }
-
-    sb.append(")");
-    return sb.toString();
-  }
-
-  @Override
-  public String visitGeneralLogarithmFunction(GQL_20240412Parser.GeneralLogarithmFunctionContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitGeneralLogarithmBase(GQL_20240412Parser.GeneralLogarithmBaseContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitGeneralLogarithmArgument(GQL_20240412Parser.GeneralLogarithmArgumentContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitCommonLogarithm(GQL_20240412Parser.CommonLogarithmContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNaturalLogarithm(GQL_20240412Parser.NaturalLogarithmContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitExponentialFunction(GQL_20240412Parser.ExponentialFunctionContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitPowerFunction(GQL_20240412Parser.PowerFunctionContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNumericValueExpressionBase(GQL_20240412Parser.NumericValueExpressionBaseContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNumericValueExpressionExponent(GQL_20240412Parser.NumericValueExpressionExponentContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNumericValueExpressionFactor(GQL_20240412Parser.NumericValueExpressionFactorContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNumericValueExpressionSummand(GQL_20240412Parser.NumericValueExpressionSummandContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNumericValueExpression(GQL_20240412Parser.NumericValueExpressionContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitBooleanValueExpressionBase(GQL_20240412Parser.BooleanValueExpressionBaseContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitBooleanValueExpressionFactor(GQL_20240412Parser.BooleanValueExpressionFactorContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitBooleanValueExpressionSummand(GQL_20240412Parser.BooleanValueExpressionSummandContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitBooleanValueExpression(GQL_20240412Parser.BooleanValueExpressionContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitFieldPath(GQL_20240412Parser.FieldPathContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNodeLabel(GQL_20240412Parser.NodeLabelContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitEdgeLabel(GQL_20240412Parser.EdgeLabelContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitLabel(GQL_20240412Parser.LabelContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNodeType(GQL_20240412Parser.NodeTypeContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitEdgeType(GQL_20240412Parser.EdgeTypeContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitType(GQL_20240412Parser.TypeContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitFieldName(GQL_20240412Parser.FieldNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNodeName(GQL_20240412Parser.NodeNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitEdgeName(GQL_20240412Parser.EdgeNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitAliasName(GQL_20240412Parser.AliasNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitTypeName(GQL_20240412Parser.TypeNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitLabelName(GQL_20240412Parser.LabelNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNonTypeName(GQL_20240412Parser.NonTypeNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitTypeVariableName(GQL_20240412Parser.TypeVariableNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitFieldVariableName(GQL_20240412Parser.FieldVariableNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNodeVariableName(GQL_20240412Parser.NodeVariableNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitEdgeVariableName(GQL_20240412Parser.EdgeVariableNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitVariableName(GQL_20240412Parser.VariableNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitDatabaseName(GQL_20240412Parser.DatabaseNameContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitDateString(GQL_20240412Parser.DateStringContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitTimeString(GQL_20240412Parser.TimeStringContext ctx) {
-    return visitChildren(ctx);
+  public String visitProgram(ArithmeticParser.ProgramContext ctx) {
+    return visit(ctx.expression());
   }
 
   @Override
-  public String visitDatetimeString(GQL_20240412Parser.DatetimeStringContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitDurationLiteral(GQL_20240412Parser.DurationLiteralContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitDurationString(GQL_20240412Parser.DurationStringContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNodeSynonym(GQL_20240412Parser.NodeSynonymContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitEdgesSynonym(GQL_20240412Parser.EdgesSynonymContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitEdgeSynonym(GQL_20240412Parser.EdgeSynonymContext ctx) {
-    return visitChildren(ctx);
-  }
-
-  @Override
-  public String visitNonReservedWords(GQL_20240412Parser.NonReservedWordsContext ctx) {
-    return visitChildren(ctx);
+  public String visitExpression(ArithmeticParser.ExpressionContext ctx) {
+    if (ctx.INT() != null) {
+      return ctx.INT().getText();
+    } else if (ctx.getChildCount() == 3 && ctx.getChild(0).getText().equals("(")) {
+      // Handle parentheses
+      return visit(ctx.expression(0));  // Remove the extra parentheses
+    } else {
+      String left = visit(ctx.expression(0));
+      String right = visit(ctx.expression(1));
+      String operator = ctx.getChild(1).getText();
+      return "(" + left + " " + operator + " " + right + ")";
+    }
   }
 
-
 }
+
diff --git a/developer/javac/PrintVisitor_orig.java b/developer/javac/PrintVisitor_orig.java
new file mode 100644 (file)
index 0000000..ddb127d
--- /dev/null
@@ -0,0 +1,26 @@
+import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
+
+public class PrintVisitor extends AbstractParseTreeVisitor<String> implements ArithmeticVisitor<String> {
+    private final String[] ruleNames;
+
+    public PrintVisitor(String[] ruleNames) {
+        this.ruleNames = ruleNames;
+    }
+
+    @Override
+    public String visitProgram(ArithmeticParser.ProgramContext ctx) {
+        return visit(ctx.expression());
+    }
+
+    @Override
+    public String visitExpression(ArithmeticParser.ExpressionContext ctx) {
+        if (ctx.INT() != null) {
+            return ctx.INT().getText();
+        } else {
+            String left = visit(ctx.expression(0));
+            String right = visit(ctx.expression(1));
+            String operator = ctx.getChild(1).getText();
+            return "(" + left + " " + operator + " " + right + ")";
+        }
+    }
+}
index a8db135..f338cb1 100644 (file)
@@ -3,8 +3,9 @@ import org.antlr.v4.runtime.tree.*;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.lang.reflect.Method;
 
-public class SyntaxTree20240412 {
+public class SyntaxTree_20240412 {
 
   // Versioned Lexer and Parser
   static final Class<?> GQL_Lexer = GQL_20240412Lexer.class;
diff --git a/developer/javac/SyntaxTree_Arithmetic.java b/developer/javac/SyntaxTree_Arithmetic.java
new file mode 100644 (file)
index 0000000..f841c31
--- /dev/null
@@ -0,0 +1,37 @@
+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.lang.reflect.Method;
+
+public class SyntaxTree_Arithmetic {
+
+  // Versioned Lexer and Parser
+  static final Class<?> GQL_Lexer = ArithmeticLexer.class;
+  static final Class<?> GQL_Parser = ArithmeticParser.class;
+
+  public static void main(String[] args) throws IOException {
+    if (args.length != 1) {
+      System.err.println("Usage: java SyntaxTree <input-file>");
+      System.exit(1);
+    }
+
+    String inputFile = args[0];
+    String input = new String(Files.readAllBytes(Paths.get(inputFile)));
+
+    try {
+      Lexer lexer = (Lexer) GQL_Lexer.getConstructor(CharStream.class).newInstance(CharStreams.fromString(input));
+      CommonTokenStream tokens = new CommonTokenStream(lexer);
+      Parser parser = (Parser) GQL_Parser.getConstructor(TokenStream.class).newInstance(tokens);
+      Method startRule = parser.getClass().getMethod("program"); // Assuming 'program' is the start rule
+      ParseTree tree = (ParseTree) startRule.invoke(parser);
+
+      PrintVisitor visitor = new PrintVisitor(parser.getRuleNames());
+      String syntaxTree = visitor.visit(tree);
+      System.out.println(syntaxTree);
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+}
diff --git a/developer/javac/TestBench.java b/developer/javac/TestBench.java
new file mode 100644 (file)
index 0000000..8bdcc67
--- /dev/null
@@ -0,0 +1,28 @@
+import java.util.Map;
+
+public class TestBench {
+
+    public static void runTests(Map<String, Boolean> tests) {
+        int totalTests = tests.size();
+        int passedTests = 0;
+        int failedTests = 0;
+
+        for (Map.Entry<String, Boolean> test : tests.entrySet()) {
+            try {
+                if (test.getValue()) {
+                    passedTests++;
+                } else {
+                    System.out.println("failed: " + test.getKey());
+                    failedTests++;
+                }
+            } catch (Exception e) {
+                System.out.println("failed: " + test.getKey());
+                failedTests++;
+            }
+        }
+
+        System.out.println("Total tests run: " + totalTests);
+        System.out.println("Total tests passed: " + passedTests);
+        System.out.println("Total tests failed: " + failedTests);
+    }
+}
diff --git a/developer/javac/Test__SyntaxTree_Arithmetic.java b/developer/javac/Test__SyntaxTree_Arithmetic.java
new file mode 100644 (file)
index 0000000..4b475f0
--- /dev/null
@@ -0,0 +1,94 @@
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.tree.*;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Test__SyntaxTree_Arithmetic {
+
+  public static boolean PrintVisitor_0() {
+    // Simple smoke test
+    try {
+      String input = "3 + 5";
+      String expectedOutput = "(3 + 5)";
+      String actualOutput = runSyntaxTree(input);
+      return expectedOutput.equals(actualOutput);
+    } catch (Exception e) {
+      return false;
+    }
+  }
+
+  public static boolean PrintVisitor_1() {
+    // Test with multiplication
+    try {
+      String input = "2 * 3";
+      String expectedOutput = "(2 * 3)";
+      String actualOutput = runSyntaxTree(input);
+      return expectedOutput.equals(actualOutput);
+    } catch (Exception e) {
+      return false;
+    }
+  }
+
+  public static boolean PrintVisitor_2() {
+    // Test with parentheses
+    try {
+      String input = "2 * (3 + 4)";
+      String expectedOutput = "(2 * (3 + 4))";
+      String actualOutput = runSyntaxTree(input);
+      return expectedOutput.equals(actualOutput);
+    } catch (Exception e) {
+      return false;
+    }
+  }
+
+  public static boolean PrintVisitor_3() {
+    // Test with division
+    try {
+      String input = "10 / 2";
+      String expectedOutput = "(10 / 2)";
+      String actualOutput = runSyntaxTree(input);
+      return expectedOutput.equals(actualOutput);
+    } catch (Exception e) {
+      return false;
+    }
+  }
+
+  public static boolean PrintVisitor_4() {
+    // Test with complex expression
+    try {
+      String input = "3 + 5 * (10 - 4)";
+      String expectedOutput = "(3 + (5 * (10 - 4)))";
+      String actualOutput = runSyntaxTree(input);
+      // Uncomment the print statement for debugging
+      // System.out.println("PrintVisitor_4 - Expected: " + expectedOutput + ", Actual: " + actualOutput);
+      return expectedOutput.equals(actualOutput);
+    } catch (Exception e) {
+      return false;
+    }
+  }
+
+
+
+  private static String runSyntaxTree(String input) throws Exception {
+    Lexer lexer = new ArithmeticLexer(CharStreams.fromString(input));
+    CommonTokenStream tokens = new CommonTokenStream(lexer);
+    Parser parser = new ArithmeticParser(tokens);
+    Method startRule = parser.getClass().getMethod("program");
+    ParseTree tree = (ParseTree) startRule.invoke(parser);
+
+    PrintVisitor visitor = new PrintVisitor(parser.getRuleNames());
+    return visitor.visit(tree);
+  }
+
+  public static void main(String[] args) {
+    Map<String, Boolean> tests = new HashMap<>();
+    tests.put("PrintVisitor_0", PrintVisitor_0());
+    tests.put("PrintVisitor_1", PrintVisitor_1());
+    tests.put("PrintVisitor_2", PrintVisitor_2());
+    tests.put("PrintVisitor_3", PrintVisitor_3());
+    tests.put("PrintVisitor_4", PrintVisitor_4());
+
+    TestBench.runTests(tests);
+  }
+}
index 251ac90..2e31368 100644 (file)
@@ -4,14 +4,35 @@
 
 all: setup $(PROGRAM_FPL)
 
-SyntaxTree_Test: $(ANTLR_OUT_GQL_Test_FPL)
-       make $(PROGRAM_SyntaxTree_Test)
+
+PrintRuleNameList: $(PROGRAM_PrintRuleNameList)
+
+
+SyntaxTree_Arithmetic: $(ANTLR_OUT_Arithmetic_FPL)
+       @if [ -z "$(ANTLR_OUT_Arithmetic_FPL)" ]; then \
+         echo "variable ANTLR_OUT_Arithmetic_FPL empty."; \
+         exit 1; \
+       fi
+       make $(PROGRAM_SyntaxTree_Arithmetic)
+
+
+Test__SyntaxTree_Arithmetic: $(ANTLR_OUT_Arithmetic_FPL)
+       @if [ -z "$(ANTLR_OUT_Arithmetic_FPL)" ]; then \
+         echo "variable ANTLR_OUT_Arithmetic_FPL empty."; \
+         exit 1; \
+       fi
+       make $(PROGRAM_Test__SyntaxTree_Arithmetic)
+
 
 SyntaxTree_20240412: $(ANTLR_OUT_GQL_20240412_FPL)
+       @if [ -z "$(ANTLR_OUT_GQL_20240412_FPL)" ]; then \
+         echo "variable ANTLR_OUT_GQL_20240412_FPL empty."; \
+         exit 1; \
+       fi
        make $(PROGRAM_SyntaxTree_20240412)
 
-PrintRuleNameList: $(PROGRAM_PrintRuleNameList)
 
+# make the `.java` files for all grammars
 grammar: setup $(ANTLR_OUT_FPL)
 
 # Compile all the .java files.
@@ -49,15 +70,11 @@ nothing:
 #================================================================================
 # recipes
 
-# Without this, GNU make deletes .jar files after making them.
-# Surely this is part of a spat between GNU and Sun Microsysitems, where they
-# now produce tools that delete each others files ;-)
-.PRECIOUS: $(JAVA_COMP_OUT_DIR)/%.jar
 
 $(ANTLR_OUT_DIR)/%Lexer.java \
 $(ANTLR_OUT_DIR)/%Parser.java \
 $(ANTLR_OUT_DIR)/%BaseVisitor.java \
-$(ANTLR_OUT_DIR)/%Visitor.java: $(ANTLR_IN_DIR)/%.g4
+$(ANTLR_OUT_DIR)/%Visitor.java: $(ANTLR_IN_PRIMARY_DIR)/%.g4
        @echo "making grammar from:" $<
        $(JAVA_INTERP) -jar $(ANTLR_JAR) -Dlanguage=Java -visitor -o $(ANTLR_OUT_DIR_PARENT) $<
 
@@ -67,18 +84,20 @@ $(JAVA_COMP_OUT_DIR)/%.class: $(JAVA_COMP_IN_PRIMARY_DIR)/%.java
        $(JAVA_COMP) -d $(JAVA_COMP_OUT_DIR) -sourcepath $(JAVA_COMP_IN_DL) $<
        @echo "Created $@"
 
+
+# Without this, GNU make inserts an 'rm -rf' not on the recipe and deletes the .jar files
+# after making them.  Why make why?
+.PRECIOUS: $(JAVA_COMP_OUT_DIR)/%.jar
+
 # Rule to build .jar files from .class files
 $(JAVA_COMP_OUT_DIR)/%.jar: $(JAVA_COMP_OUT_DIR)/%.class
        @echo "Building $*..."
        $(JAVA_ARCHIVE) cf $@ -C $(JAVA_COMP_OUT_DIR) $*.class
        @echo "Created $@"
 
-# Rule to create executable scripts from .jar files
 executor/%: $(JAVA_COMP_OUT_DIR)/%.jar
        @echo "Creating script for $*..."
        @echo "#!/usr/bin/env bash" > executor/$*
-       @echo "$(JAVA_INTERP) -cp $< $*" \$$\@ >> executor/$*
+       @echo "$(JAVA_INTERP) -cp ${CLASSPATH}:$(JAVA_COMP_OUT_DIR):$< $*" \$$\@ >> executor/$*
        chmod +x executor/$*
        @echo "Created script executor/$*"
-
-