various cleanup, first/rough pass on a build doc, some comments
authorThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Wed, 4 Sep 2024 14:41:58 +0000 (14:41 +0000)
committerThomas Walker Lynch <xtujpz@reasoningtechnology.com>
Wed, 4 Sep 2024 14:41:58 +0000 (14:41 +0000)
developer/executor/env_build
developer/executor/make
developer/executor/makefile-project.mk
developer/executor/makefile-tool.mk
developer/executor/makefile-top.mk
developer/javac/ANTLR_OUT_FL.java
executor/env_dev
ologist/build.html [new file with mode: 0644]

index b8f9ef1..a631a60 100755 (executable)
@@ -1,39 +1,44 @@
 #!/usr/bin/env bash
 
-# Ensure the script is sourced
-if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
-  echo "This script must be sourced, not executed. Exiting."
-  return 1
-fi
-
-# Note these suffixes:
+# The build environment. 
+#
+# Hopefully no edits are required here to build this project's programs.
+#
+# The most common edit here is to add the name of a new program to the EXECUTOR_IN_FL.
+# That variable is found in the next section.
+#
+# The `env_dev` script should have been sourced already. (env_dev is analogous
+# to the Python virutal environment `activate`.)  `env_dev` will set `developer/executor/`
+# first in the search PATH.  In that directory there is a script called `make` which
+# is a wrapper to `/bin/make`.  That script sources this file.  Hence, this file
+# is the environment for make, aka the build environment.
+#
+# Note these suffixes found on variable names:
 # _FL  = File List
 # _FP  = File Path
 # _FPL = File Path List 
 # _DL  = Directory List
 # _DP  = Directory path
 # _DPL = Directory path list
-
+#
 # _PRIMARY = stuff not built
 # _IN  things input to some program
 # _OUT things output by some program
+#
+# Relative paths values are relative to the $REPO_HOME/developer directory, unless
+# for good reason which is obvious or stated in a comment adjacent to the variable.
 
-#--------------------------------------------------------------------------------
-# commands
-
-export BIN_MAKE=/bin/make
 
+# Ensure the script is sourced rather than run directly
+if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+  echo "This script must be sourced, not executed. Exiting."
+  return 1
+fi
 
 #--------------------------------------------------------------------------------
-# to be built
+# programs to be built
+# each new executable will also need a custom target in makefile-project.mk
 
-# export PROGRAM_PrintRuleNameList="executor/PrintRuleNameList"
-# export PROGRAM_SyntaxTree_Arithmetic="executor/SyntaxTree_Arithmetic"
-# export PROGRAM_Test__SyntaxTree_Arithmetic="executor/Test__SyntaxTree_Arithmetic"
-# export PROGRAM_SyntaxTree_20240412="executor/SyntaxTree_20240412"
-
-
-# Add each new executable to this list, and give it a custom target in the makefile.
 export EXECUTOR_IN_FL="\
   PrintRuleNameList\
   TerminalToCategory\
@@ -81,6 +86,7 @@ export CLASSPATH="${CLASSPATH}:${JVM_IN_DP}"
 #
 #  set by project manager: JAVA_HOME, ANTLR_JAR, DEVELOPER_HOME
 #
+export BIN_MAKE=/bin/make
 export JAVA_COMP="${JAVA_HOME}/bin/javac"
 export JAVA_INTERP="${JAVA_HOME}/bin/java"
 export JAVA_ARCHIVE="${JAVA_HOME}/bin/jar"
@@ -94,35 +100,12 @@ export TEMP_DIR="$DEVELOPER_HOME"/temporary
 #--------------------------------------------------------------------------------
 # ANTLR files
 #
-
 export ANTLR_IN_PRIMARY_FPL=$(ls ${ANTLR_IN_PRIMARY_DIR}/*.g4 2>/dev/null | tr '\n' ' ')
 export ANTLR_GRAMMAR_LIST=$(basename -s .g4 ${ANTLR_IN_PRIMARY_FPL})
 if [ -z "${ANTLR_IN_PRIMARY_FPL}" ]; then
   echo "No ANTLR input grammar files found"
 fi
 
-# replaced with a tool called ANTLR_OUR_FL
-#
-# This function accepts a grammar name, or a grammar name with an extension; 
-# and sets a variable of the form ANTLR_OUT_<grammar>_FPL to a list of
-# files that ANTLR would produce for <grammar>.
-# set_ANTLR_out_fpl_var() {
-#  local grammar=$1
-#  export ANTLR_OUT_${grammar}_FPL="${ANTLR_OUT_DIR}/${grammar}Lexer.java ${ANTLR_OUT_DIR}/${grammar}Parser.java ${ANTLR_OUT_DIR}/${grammar}BaseVisitor.java ${ANTLR_OUT_DIR}/${grammar}Visitor.java"
-# }
-
-# Generate ANTLR_OUT_<grammar>_FPL for each grammar
-# for grammar in ${ANTLR_GRAMMAR_LIST}; do
-#  set_ANTLR_out_fpl_var ${grammar}
-# done
-
-# Combine all individual file lists into ANTLR_OUT_FPL
-# ANTLR_OUT_FPL=""
-# for grammar in ${ANTLR_GRAMMAR_LIST}; do
-#   ANTLR_OUT_FPL="${ANTLR_OUT_FPL} $(eval echo \$ANTLR_OUT_${grammar}_FPL)"
-# done
-# export ANTLR_OUT_FPL
-
 #--------------------------------------------------------------------------------
 # Java files 
 #
index 714a070..fcc76d3 100755 (executable)
@@ -12,4 +12,11 @@ cd "$DEVELOPER_HOME"
 # in case there have been edits to the environment
 source "${EXECUTOR_IN_DIR}"/env_build
 
+# If make is called with no arguments, we will make the entire project.
+# Making the project has a dependency on the tools, so if they have not
+# been made, they will be made before the project is made.
+if [[ $# -eq 0 ]]; then
+  set -- "project"
+fi
+
 ${BIN_MAKE} --no-print-directory -f "${EXECUTOR_IN_DIR}"/makefile-top.mk $@
index b406cd1..badb939 100644 (file)
@@ -1,62 +1,70 @@
-
-$(info makefile: $(MAKEFILE_LIST))
-$(info project_MAKECMDGOALS: $(MAKECMDGOALS))
+#--------------------------------------------------------------------------------
+#  Project build
+#
 
 # turn off implicit rules
 .SUFFIXES:
 MAKEFLAGS += -r
 
 # `make` always tries to make its makefiles as targets. This prevents that.
-.SECONDARY: $(MAKEFILE_LIST)
+.PHONY: $(MAKEFILE_LIST)
+.PRECIOUS: $(MAKEFILE_LIST)
+
+$(info makefile: $(MAKEFILE_LIST))
+$(info project_MAKECMDGOALS: $(MAKECMDGOALS))
 
 #================================================================================
 # Custom make targets
 #
 
 project: $(EXECUTOR_IN_FPL)
-
 PrintRuleNameList: $(EXECUTOR_IN_DIR)/PrintRuleNameList
 
 
 #-----------------------------------------------
 # Arithmetic
 
-ANTLR_OUT_Arithmetic_FL := $(shell ANTLR_OUT_FL Arithmetic.g4 -visitor -no-listener -no-tokens)
-ANTLR_OUT_Arithmetic_FPL := $(addprefix $(ANTLR_OUT_DIR)/, $(ANTLR_OUT_Arithmetic_FL))
-Arithmetic_Echo: $(ANTLR_OUT_Arithmetic_FPL) $(JAVA_COMP_IN_PRIMARY_DIR)/Arithmetic_Echo_PrintVisitor.java
+ANTLR_OUT_Arithmetic_FPL $(shell ANTLR_OUT_FL Arithmetic -path $(ANTLR_OUT_DIR))
+Arithmetic_Echo:\
+  $(ANTLR_OUT_Arithmetic_FPL)
+  $(JAVA_COMP_IN_PRIMARY_DIR)/Arithmetic_Echo_PrintVisitor.java
        @if [ -z "$(ANTLR_OUT_Arithmetic_FPL)" ]; then \
          echo "variable ANTLR_OUT_Arithmetic_FPL empty."; \
          exit 1; \
        fi
        make $(EXECUTOR_IN_DIR)/Arithmetic_Echo
 
-# Arithmetic_Echo__Test: $(ANTLR_OUT_Arithmetic_FPL) $(JAVA_COMP_IN_PRIMARY_DIR)/Arithmetic_Echo_PrintVisitor.java
-#      @if [ -z "$(ANTLR_OUT_Arithmetic_FPL)" ]; then \
-#        echo "variable ANTLR_OUT_Arithmetic_FPL empty."; \
-#        exit 1; \
-#      fi
-#      $(BIN_MAKE) $(EXECUTOR_IN_DIR)/Arithmetic_Echo__Test
-
-# Arithmetic_Syntax: $(ANTLR_OUT_Arithmetic_FPL) $(JAVA_COMP_IN_PRIMARY_DIR)/Arithmetic_Syntax_PrintVisitor.java
-#      @if [ -z "$(ANTLR_OUT_Arithmetic_FPL)" ]; then \
-#        echo "variable ANTLR_OUT_Arithmetic_FPL empty."; \
-#        exit 1; \
-#      fi
-#      $(BIN_MAKE) $(EXECUTOR_IN_DIR)/Arithmetic_Syntax
-
-# Arithmetic_Syntax__Test: $(ANTLR_OUT_Arithmetic_FPL) $(JAVA_COMP_IN_PRIMARY_DIR)/Arithmetic_Syntax_PrintVisitor.java
-#      @if [ -z "$(ANTLR_OUT_Arithmetic_FPL)" ]; then \
-#        echo "variable ANTLR_OUT_Arithmetic_FPL empty."; \
-#        exit 1; \
-#      fi
-#      $(BIN_MAKE) $(EXECUTOR_IN_DIR)/Arithmetic_Syntax__Test
+Arithmetic_Echo__Test:\
+  $(ANTLR_OUT_Arithmetic_FPL)
+  $(JAVA_COMP_IN_PRIMARY_DIR)/Arithmetic_Echo_PrintVisitor.java
+       @if [ -z "$(ANTLR_OUT_Arithmetic_FPL)" ]; then \
+         echo "variable ANTLR_OUT_Arithmetic_FPL empty."; \
+         exit 1; \
+       fi
+       $(BIN_MAKE) $(EXECUTOR_IN_DIR)/Arithmetic_Echo__Test
+
+Arithmetic_Syntax:\
+  $(ANTLR_OUT_Arithmetic_FPL)
+  $(JAVA_COMP_IN_PRIMARY_DIR)/Arithmetic_Syntax_PrintVisitor.java
+       @if [ -z "$(ANTLR_OUT_Arithmetic_FPL)" ]; then \
+         echo "variable ANTLR_OUT_Arithmetic_FPL empty."; \
+         exit 1; \
+       fi
+       $(BIN_MAKE) $(EXECUTOR_IN_DIR)/Arithmetic_Syntax
+
+Arithmetic_Syntax__Test:\
+  $(ANTLR_OUT_Arithmetic_FPL)
+  $(JAVA_COMP_IN_PRIMARY_DIR)/Arithmetic_Syntax_PrintVisitor.java
+       @if [ -z "$(ANTLR_OUT_Arithmetic_FPL)" ]; then \
+         echo "variable ANTLR_OUT_Arithmetic_FPL empty."; \
+         exit 1; \
+       fi
+       $(BIN_MAKE) $(EXECUTOR_IN_DIR)/Arithmetic_Syntax__Test
 
 #-----------------------------------------------
 #  GQL_20240412
 
-ANTLR_OUT_GQL_20240412_FL := $(shell ANTLR_OUT_FL GQL_20240412.g4 -visitor -no-listener -no-tokens)
-ANTLR_OUT_GQL_20240412_FPL := $(addprefix $(ANTLR_OUT_DIR)/, $(ANTLR_OUT_GQL_20240412_FL))
-
+ANTLR_OUT_GQL_20240412_FPL := $(shell ANTLR_OUT_FL GQL_20240412 -path $(ANTLR_OUT_DIR))
 GQL_20240412_Syntax: $(ANTLR_OUT_GQL_20240412_FPL) $(JAVA_COMP_IN_PRIMARY_DIR)/GQL_20240412_Syntax_PrintVisitor.java
        @if [ -z "$(ANTLR_OUT_GQL_20240412_FPL)" ]; then \
          echo "variable ANTLR_OUT_GQL_20240412_FPL empty."; \
index 2972b10..db4037c 100644 (file)
@@ -1,13 +1,14 @@
 
-$(info makefile: $(MAKEFILE_LIST))
-$(info project_MAKECMDGOALS: $(MAKECMDGOALS))
-
 # turn off implicit rules
 .SUFFIXES:
 MAKEFLAGS += -r
 
 # `make` always tries to make its makefiles as targets. This prevents that.
-.SECONDARY: $(MAKEFILE_LIST)
+.PHONY: $(MAKEFILE_LIST)
+.PRECIOUS: $(MAKEFILE_LIST)
+
+$(info makefile: $(MAKEFILE_LIST))
+$(info project_MAKECMDGOALS: $(MAKECMDGOALS))
 
 #================================================================================
 # Custom make targets
index 649a083..4e88b53 100644 (file)
@@ -1,20 +1,26 @@
-$(info makefile: $(MAKEFILE_LIST))
-$(info project_MAKECMDGOALS: $(MAKECMDGOALS))
+# In GNU make, pattern matches can not be empty strings.
+# `> make project`, or `make project-project` makes the entire project
+# `> make tool-tool` makes all the tools (while not making the project).
 
 # turn off implicit rules
 .SUFFIXES:
 MAKEFLAGS += -r
 
-# `make` always tries to make its makefiles as targets. This prevents that.
-.SECONDARY: $(MAKEFILE_LIST)
+# `make` always tries to make its make files as target files. This prevents that.
+.PHONY: $(MAKEFILE_LIST)
+.PRECIOUS: $(MAKEFILE_LIST)
+
+$(info makefile: $(MAKEFILE_LIST))
+$(info project_MAKECMDGOALS: $(MAKECMDGOALS))
+
 
 #================================================================================
 # Custom make targets
 #
-.PHONY: top version clean setup tool- project-
+.PHONY: top version clean setup
 
 # The 'all' target now depends on 'tool' and 'project'
-top: setup tool- project-
+top: setup tool-tool project-project
 
 # for distinguishing between make syntax errors and build errors
 nothing:
@@ -29,18 +35,17 @@ version:
 
 # `clean` is program independent of `make`
 clean:
-       @echo "Use the clean script from the $(EXECUTOR_IN_DIR) directory instead of \`make clean\`"
-       @$(EXECUTOR_IN_DIR)/clean
+       @echo "Use the command `clean <option>` instead of make.`"
 
 setup:
        mkdir -p $(ANTLR_IN_PRIMARY_DIR) $(JAVA_COMP_IN_PRIMARY_DIR) $(JVM_IN_DIR)
-       mkdir -p $(EXECUTOR_IN_DIR) test deprecated experiment documentation temporary
+       mkdir -p $(EXECUTOR_IN_DIR) test deprecated experiment ologist temporary
 
 # Ensure tools are built before building the project programs
 tool-%: setup
        $(BIN_MAKE) -f $(EXECUTOR_IN_DIR)/makefile-tool.mk -$(MAKEFLAGS) $*
 
-project-%: tool
+project-%: tool-tool
        $(BIN_MAKE) -f $(EXECUTOR_IN_DIR)/makefile-project.mk -$(MAKEFLAGS) $*
 
 # delegate other targets to the project
index bdd85a3..15094ba 100644 (file)
@@ -1,49 +1,80 @@
 /*
+Run the command with no arguments for a usage message.
 
 Accepts an antlr grammar file name of the form: [path/]<name>[Lexer/Parser][.g4]
 
-Prints a space separated list of files antlr4 would output.
+Prints a space-separated list of files antlr4 would output.
 
 The <name>Lexer or <name>Parser suffix, or absence thereof, tell this program if
 antlr would create lexer and parser files, or both.
 
-The `-visitor` and `no-lsistner` options also affect the output, as they would
-for antlr.
 
 */
+
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
 public class ANTLR_OUT_FL {
 
+    // Constant for the usage message
+    private static final String USAGE_MESSAGE = "Usage: java ANTLR_OUT_FL <grammar-file> " +
+            "[-visitor (default)] [-no-visitor] " +
+            "[-listener] [-no-listener (default)] " +
+            "[-tokens] [-no-tokens (default)] " +
+            "[-path <path>]";
+
     public static void main(String[] args) {
         if (args.length == 0) {
-            System.err.println("Usage: java ANTLR_OUT_FL <grammar-file> [-visitor] [-no-listener]");
+            System.err.println(USAGE_MESSAGE);
             System.exit(1);
         }
 
-        boolean visitor = false;
-        boolean noListener = false;
-        boolean noTokens = false;
+        // Defaults
+        boolean visitor = true;
+        boolean noListener = true;
+        boolean noTokens = true;
+        String outputPath = "";  // Default empty path
         List<String> argList = new ArrayList<>();
 
         // Parse the arguments
-        for (String arg : args) {
+        for (int i = 0; i < args.length; i++) {
+            String arg = args[i];
             if (arg.startsWith("-")) {
                 switch (arg) {
                     case "-visitor":
                         visitor = true;
                         break;
+                    case "-no-visitor":
+                        visitor = false;
+                        break;
+                    case "-listener":
+                        noListener = false;
+                        break;
                     case "-no-listener":
                         noListener = true;
                         break;
+                    case "-tokens":
+                        noTokens = false;
+                        break;
                     case "-no-tokens":
                         noTokens = true;
                         break;
+                    case "-path":
+                        // Ensure the next argument exists and isn't another option
+                        if (i + 1 < args.length && !args[i + 1].startsWith("-")) {
+                            outputPath = args[++i];  // Get the next argument as the path
+                            if (!outputPath.endsWith("/")) {
+                                outputPath += "/";  // Ensure the path ends with a slash
+                            }
+                        } else {
+                            System.err.println(USAGE_MESSAGE);
+                            System.exit(1);
+                        }
+                        break;
                     default:
                         System.err.println("Unrecognized option: " + arg);
-                        System.err.println("Usage: java ANTLR_OUT_FL <grammar-file> [-visitor] [-no-listener]");
+                        System.err.println(USAGE_MESSAGE);
                         System.exit(1);
                 }
             } else {
@@ -53,13 +84,13 @@ public class ANTLR_OUT_FL {
 
         // Ensure there is exactly one grammar file argument
         if (argList.size() != 1) {
-            System.err.println("Usage: java ANTLR_OUT_FL <grammar-file> [-visitor] [-no-listener]");
+            System.err.println(USAGE_MESSAGE);
             System.exit(1);
         }
 
         String grammarFile = argList.get(0);
 
-        List<String> generatedFiles = generateFileList(grammarFile, visitor, noListener ,noTokens);
+        List<String> generatedFiles = generateFileList(grammarFile, visitor, noListener, noTokens, outputPath);
 
         // Print the files in a space-separated format on a single line
         if (!generatedFiles.isEmpty()) {
@@ -71,7 +102,7 @@ public class ANTLR_OUT_FL {
         System.out.println(); // Print a newline at the end
     }
 
-  public static List<String> generateFileList(String grammarFile, boolean visitor, boolean noListener ,boolean noTokens) {
+    public static List<String> generateFileList(String grammarFile, boolean visitor, boolean noListener, boolean noTokens, String outputPath) {
         String baseName = new File(grammarFile).getName().replace(".g4", "");
         List<String> fileList = new ArrayList<>();
 
@@ -82,25 +113,25 @@ public class ANTLR_OUT_FL {
 
         if (isLexer || isCombined) {
             // Lexer files
-            fileList.add(baseName + "Lexer.java");
-            if (!noTokens) fileList.add(baseName + "Lexer.tokens");
+            fileList.add(outputPath + baseName + "Lexer.java");
+            if (!noTokens) fileList.add(outputPath + baseName + "Lexer.tokens");
         }
 
         if (isParser || isCombined) {
             // Parser files
-            fileList.add(baseName + "Parser.java");
-            if (!noTokens) fileList.add(baseName + ".tokens");
+            fileList.add(outputPath + baseName + "Parser.java");
+            if (!noTokens) fileList.add(outputPath + baseName + ".tokens");
 
             // Listener-related files
             if (!noListener) {
-                fileList.add(baseName + "Listener.java");
-                fileList.add(baseName + "BaseListener.java");
+                fileList.add(outputPath + baseName + "Listener.java");
+                fileList.add(outputPath + baseName + "BaseListener.java");
             }
 
             // Visitor-related files
             if (visitor) {
-                fileList.add(baseName + "Visitor.java");
-                fileList.add(baseName + "BaseVisitor.java");
+                fileList.add(outputPath + baseName + "Visitor.java");
+                fileList.add(outputPath + baseName + "BaseVisitor.java");
             }
         }
 
index 6b1e0fb..ecc55c4 100644 (file)
@@ -18,6 +18,5 @@ export DEVELOPER_HOME="$REPO_HOME/developer"
 
 export PATH="$DEVELOPER_HOME"/executor:"$REPO_HOME"/tool/executor:"$JAVA_HOME"/bin:"$PATH"
 cd "$DEVELOPER_HOME"
-source "$DEVELOPER_HOME"/executor/env_build
 
 echo "${BASH_SOURCE[0]}" "complete"
diff --git a/ologist/build.html b/ologist/build.html
new file mode 100644 (file)
index 0000000..ac24ab4
--- /dev/null
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Building the Project: A Developer's Guide</title>
+</head>
+<body>
+
+  <h1>Building the Project: A Developer’s Guide</h1>
+
+  <p>This document is intended to guide developers on how to build existing programs and extend the build environment when needed.</p>
+
+  <h2>Section 1: Building Existing Programs</h2>
+
+  <h3>1.1 Prerequisites</h3>
+  <ul>
+    <li><strong>Setting Up Your Environment:</strong> 
+      Ensure that <code>make</code> is available in your system’s <code>PATH</code>.
+      Make sure necessary environment variables such as <code>DEVELOPER_HOME</code> and <code>EXECUTOR_IN_DIR</code> are set.
+      Source the <code>env_build</code> script to configure the environment:
+      <pre><code>source /path/to/env_build</code></pre>
+    </li>
+  </ul>
+
+  <h3>1.2 Basic Build Process</h3>
+  <ul>
+    <li><strong>How to Use Make:</strong> 
+      Developers can use the <code>make</code> command to build specific programs. 
+      For example:
+      <pre><code>make X</code></pre>
+      Here, <code>X</code> is the name of the program you wish to build. 
+      If you do not specify any program, <code>make</code> will build the entire project:
+      <pre><code>make</code></pre>
+    </li>
+    <li><strong>Sample Commands:</strong>
+      <pre><code>make Arithmetic_Echo</code></pre>
+      <pre><code>make Arithmetic_Syntax</code></pre>
+    </li>
+  </ul>
+
+  <h3>1.3 Understanding the Output</h3>
+  <ul>
+    <li>After a successful build, executables will be created in the <code>executor</code> directory.
+      <br>The <code>makefile-top.mk</code> file will be the top-level control file for managing the build process.
+    </li>
+  </ul>
+
+  <h2>Section 2: Advanced Usage for Developers</h2>
+
+  <h3>2.1 Adding New Programs</h3>
+  <ul>
+    <li><strong>Steps to Add a New Program:</strong>
+      <ul>
+        <li>Modify <code>makefile-project.mk</code> and <code>makefile-tool.mk</code> to include the new program.</li>
+        <li>Add the program name to the <code>EXECUTOR_IN_FL</code> list in <code>env_build</code>.</li>
+        <li>Ensure that source files (e.g., <code>.java</code> or ANTLR grammar files) are properly placed in the relevant directories.</li>
+      </ul>
+    </li>
+  </ul>
+
+  <h3>2.2 Advanced Make Commands</h3>
+  <ul>
+    <li><strong>Using <code>project-X</code> and <code>tool-Y</code>:</strong>
+      Developers can use advanced make commands to build only specific components.
+      For example:
+      <pre><code>make project-Arithmetic_Syntax</code></pre>
+      This command builds the <code>Arithmetic_Syntax</code> component only.
+      Similarly, use <code>make tool-X</code> to build a specific tool:
+      <pre><code>make tool-Y</code></pre>
+    </li>
+  </ul>
+
+  <h3>2.3 Debugging and Extending the Build Environment</h3>
+  <ul>
+    <li><strong>Environment Variables:</strong>
+      Developers can modify environment variables in the <code>env_build</code> script to add or remove programs, directories, or paths.
+      <br>Common variables include:
+      <ul>
+        <li><code>EXECUTOR_IN_FL</code>: The list of programs to build.</li>
+        <li><code>ANTLR_OUT_DIR</code>: Directory for ANTLR-generated files.</li>
+        <li><code>JAVA_COMP_IN_FPL</code>: File list for Java compilation.</li>
+      </ul>
+    </li>
+  </ul>
+
+</body>
+</html>
+
+