aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/parsers
diff options
context:
space:
mode:
authorEduardo Pedroni <ep625@york.ac.uk>2014-04-26 19:56:24 +0100
committerEduardo Pedroni <ep625@york.ac.uk>2014-04-26 19:56:24 +0100
commit4c8de2402f2878cde7587c7f3bbf4ffaea86efd4 (patch)
tree29156510f648a2d9f8de4df3b2617d4a056e1d90 /src/jcgp/backend/parsers
parentb0c0698e5503c2506217117bf144fde31e6f6601 (diff)
Moved files around to different folders, and commented some more packages. Aiming to have the entire backend fully commented by the end of today
Diffstat (limited to 'src/jcgp/backend/parsers')
-rw-r--r--src/jcgp/backend/parsers/ChromosomeParser.java14
-rw-r--r--src/jcgp/backend/parsers/FunctionParser.java75
-rw-r--r--src/jcgp/backend/parsers/ParameterParser.java117
-rw-r--r--src/jcgp/backend/parsers/TestCaseParser.java74
4 files changed, 178 insertions, 102 deletions
diff --git a/src/jcgp/backend/parsers/ChromosomeParser.java b/src/jcgp/backend/parsers/ChromosomeParser.java
index ed1399a..92568cc 100644
--- a/src/jcgp/backend/parsers/ChromosomeParser.java
+++ b/src/jcgp/backend/parsers/ChromosomeParser.java
@@ -14,7 +14,7 @@ import jcgp.backend.resources.ModifiableResources;
import jcgp.backend.resources.Resources;
/**
- * This class includes a method for parsing .chr files and another
+ * This class contains a method for parsing .chr files and another
* for writing .chr files from given chromosomes.
*
* @author Eduardo Pedroni
@@ -50,7 +50,7 @@ public abstract class ChromosomeParser {
try {
fr = new FileReader(file);
} catch (FileNotFoundException e) {
- resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + ".");
+ resources.println("[Parser] Error: could not find " + file.getAbsolutePath());
return;
}
Scanner in = new Scanner(fr);
@@ -70,7 +70,7 @@ public abstract class ChromosomeParser {
try {
fr = new FileReader(file);
} catch (FileNotFoundException e) {
- resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + ".");
+ resources.println("[Parser] Error: could not find " + file.getAbsolutePath());
return;
}
in = new Scanner(fr);
@@ -122,10 +122,10 @@ public abstract class ChromosomeParser {
}
in.close();
- resources.println("[Parser] File parsed successfully.");
+ resources.println("[Parser] File parsed successfully");
} else {
- resources.println("[Parser] Error: the topology of the chromosome in " + file.getName() + " does not match that of the experiment.");
+ resources.println("[Parser] Error: the topology of the chromosome in " + file.getName() + " does not match that of the experiment");
}
}
@@ -143,7 +143,7 @@ public abstract class ChromosomeParser {
try {
writer = new PrintWriter(file);
} catch (FileNotFoundException e) {
- resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + ".");
+ resources.println("[Parser] Error: could not find " + file.getAbsolutePath());
return;
}
@@ -184,7 +184,7 @@ public abstract class ChromosomeParser {
writer.close();
- resources.println("[Parser] Chromosome saved successfully.");
+ resources.println("[Parser] Chromosome saved successfully");
}
}
diff --git a/src/jcgp/backend/parsers/FunctionParser.java b/src/jcgp/backend/parsers/FunctionParser.java
index cc52ce9..806099e 100644
--- a/src/jcgp/backend/parsers/FunctionParser.java
+++ b/src/jcgp/backend/parsers/FunctionParser.java
@@ -6,21 +6,35 @@ import java.io.FileReader;
import java.util.Scanner;
import jcgp.backend.function.FunctionSet;
-import jcgp.backend.modules.problem.Problem;
-import jcgp.backend.resources.ModifiableResources;
+import jcgp.backend.resources.Resources;
/**
- * Parses the functions from a .par file.
- * Functions marked with a 1 are enabled,
- * and those marked with 0 are disabled.
+ * Contains a static method for parsing functions from a
+ * .par file.
*
* @author Eduardo Pedroni
*
*/
public abstract class FunctionParser {
- public static void parseFunctions(File file, Problem problem, ModifiableResources resources) {
-
+ /**
+ * Reads the specified file and attempts to enable
+ * and disable the functions in the FunctionSet
+ * accordingly.
+ * <br><br>
+ * Standard CGP .par files do not contain enough information
+ * to determine if they match the currently selected function set.
+ * For this reason, the parser assumes the function set is correct
+ * and treats functions by their index rather than their name. Any
+ * index outside the bounds of the function set is ignored and a
+ * warning message is printed once parsing is complete.
+ *
+ * @param file the .par file to parse.
+ * @param functionSet the function set whose functions should be modified.
+ * @param resources used for printing console messages.
+ */
+ public static void parse(File file, FunctionSet functionSet, Resources resources) {
+ // create file reader and scanner to parse, return if file does not exist
FileReader fr;
try {
fr = new FileReader(file);
@@ -30,23 +44,56 @@ public abstract class FunctionParser {
}
Scanner in = new Scanner(fr);
- FunctionSet functionSet = problem.getFunctionSet();
+ boolean excessFunctions = false;
resources.println("[Parser] Parsing file: " + file.getAbsolutePath() + "...");
+ /*
+ * The encoding used in .par files is quite simple, so regex matches are used to extract
+ * the values.
+ *
+ * A standard .par file contains functions in the following format:
+ *
+ * 0 1 modulus-0
+ * 0 1 sqrt-1
+ * 0 1 reciprocal-2
+ *
+ * The first integer signals whether to enable or disable the function. Any non-zero value
+ * is treated as "enable". The second integer is the function arity. The integer following
+ * the function name is the function index.
+ *
+ * The scanner is used to return each line separately. Every line that ends in a number
+ * is treated as a function line and split into an array, which holds its composing integers.
+ * This array is then used to enable or disabled the indexed function.
+ *
+ * A flag is raised if the index exceeds the total number of functions, and a warning is
+ * printed once parsing is complete regarding the index mismatch.
+ *
+ */
while (in.hasNextLine()) {
String line = in.nextLine();
if (line.substring(line.length() - 1).matches("[0-9]")) {
String[] splitString = line.split("[^0-9]+");
int functionIndex = Integer.parseInt(splitString[splitString.length - 1]);
- if (Integer.parseInt(splitString[0]) != 0 && !functionSet.isEnabled(functionSet.getFunction(functionIndex))) {
- functionSet.enableFunction(functionIndex);
- resources.println("[Parser] Enabled function: " + functionSet.getFunction(functionIndex));
- } else if (Integer.parseInt(splitString[0]) == 0 && functionSet.isEnabled(functionSet.getFunction(functionIndex))) {
- functionSet.disableFunction(functionIndex);
- resources.println("[Parser] Disabled function: " + functionSet.getFunction(functionIndex));
+
+ if (functionIndex < functionSet.getTotalFunctionCount()) {
+ if (Integer.parseInt(splitString[0]) != 0) {
+ functionSet.enableFunction(functionIndex);
+ resources.println("[Parser] Enabled function: " + functionSet.getFunction(functionIndex));
+ } else if (Integer.parseInt(splitString[0]) == 0) {
+ functionSet.disableFunction(functionIndex);
+ resources.println("[Parser] Disabled function: " + functionSet.getFunction(functionIndex));
+ }
+ } else {
+ excessFunctions = true;
}
}
}
+
+ // warn the user function index went out of bounds
+ if (excessFunctions) {
+ resources.println("[Parser] Warning: the parameter file contained more functions than the current function set");
+ }
+
in.close();
resources.println("[Parser] Finished parsing functions");
}
diff --git a/src/jcgp/backend/parsers/ParameterParser.java b/src/jcgp/backend/parsers/ParameterParser.java
index ae72126..711b4d2 100644
--- a/src/jcgp/backend/parsers/ParameterParser.java
+++ b/src/jcgp/backend/parsers/ParameterParser.java
@@ -7,71 +7,94 @@ import java.util.Scanner;
import jcgp.backend.resources.ModifiableResources;
+/**
+ * Contains a static method for parsing parameters from a
+ * .par file.
+ *
+ * @author Eduardo Pedroni
+ *
+ */
public abstract class ParameterParser {
- public static void parseParameters(File file, ModifiableResources resources) {
-
+ /**
+ * Parses the parameters from a specified CGP parameter file and
+ * modifies the experiment resources appropriately.
+ * <br><br>
+ * CGP .par files do not follow a very strict convention, so this
+ * parser does its best to cope with format irregularities. Parsing
+ * works even if the parameters are in the wrong order, and unknown
+ * parameters are simply ignored.
+ *
+ * @param file the .par file to parse.
+ * @param resources a reference to the resources object that must be modified.
+ */
+ public static void parse(File file, ModifiableResources resources) {
+ // create reader and scanner, print message if file is missing
FileReader fr;
try {
fr = new FileReader(file);
} catch (FileNotFoundException e) {
- resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + ".");
+ resources.println("[Parser] Error: could not find " + file.getAbsolutePath());
return;
}
Scanner in = new Scanner(fr);
resources.println("[Parser] Parsing file: " + file.getAbsolutePath() + "...");
+ // parse line by line
while (in.hasNextLine()) {
+ // split if one or more tabs or one or more spaces are found
String[] splitString = in.nextLine().split("( |\t)+");
-
- switch (splitString[1]) {
- case "population_size":
- resources.setPopulationSize(Integer.parseInt(splitString[0]));
- resources.println("[Parser] Population size is now " + resources.populationSize() + ".");
- break;
-
- case "num_generations":
- resources.setGenerations(Integer.parseInt(splitString[0]));
- resources.println("[Parser] Total generations is now " + resources.generations() + ".");
- break;
-
- case "num_runs_total":
- resources.setRuns(Integer.parseInt(splitString[0]));
- resources.println("[Parser] Total runs is now " + resources.runs() + ".");
- break;
-
- case "num_rows":
- resources.setRows(Integer.parseInt(splitString[0]));
- resources.println("[Parser] Row number is now " + resources.rows() + ".");
- break;
-
- case "num_cols":
- resources.setColumns(Integer.parseInt(splitString[0]));
- resources.println("[Parser] Column number is now " + resources.columns() + ".");
- break;
+ // expected length is 2, anything beyond that should also work
+ if (splitString.length >= 2) {
+ switch (splitString[1]) {
+ case "population_size":
+ resources.setPopulationSize(Integer.parseInt(splitString[0]));
+ resources.println("[Parser] Population size is now " + resources.populationSize());
+ break;
+
+ case "num_generations":
+ resources.setGenerations(Integer.parseInt(splitString[0]));
+ resources.println("[Parser] Total generations is now " + resources.generations());
+ break;
+
+ case "num_runs_total":
+ resources.setRuns(Integer.parseInt(splitString[0]));
+ resources.println("[Parser] Total runs is now " + resources.runs());
+ break;
+
+ case "num_rows":
+ resources.setRows(Integer.parseInt(splitString[0]));
+ resources.println("[Parser] Row number is now " + resources.rows());
+ break;
+
+ case "num_cols":
+ resources.setColumns(Integer.parseInt(splitString[0]));
+ resources.println("[Parser] Column number is now " + resources.columns());
+ break;
+
+ case "levels_back":
+ resources.setLevelsBack(Integer.parseInt(splitString[0]));
+ resources.println("[Parser] Levels back is now " + resources.levelsBack());
+ break;
+
+ case "report_interval":
+ resources.setReportInterval(Integer.parseInt(splitString[0]));
+ resources.println("[Parser] Report interval is now " + resources.levelsBack());
+ break;
+
+ case "global_seed":
+ resources.setSeed(Integer.parseInt(splitString[0]));
+ resources.println("[Parser] Seed is now " + resources.seed());
+ break;
- case "levels_back":
- resources.setLevelsBack(Integer.parseInt(splitString[0]));
- resources.println("[Parser] Levels back is now " + resources.levelsBack() + ".");
- break;
-
- case "report_interval":
- resources.setReportInterval(Integer.parseInt(splitString[0]));
- resources.println("[Parser] Report interval is now " + resources.levelsBack() + ".");
- break;
-
- case "global_seed":
- resources.setSeed(Integer.parseInt(splitString[0]));
- resources.println("[Parser] Seed is now " + resources.seed() + ".");
- break;
-
- default:
- break;
+ default:
+ break;
+ }
}
}
in.close();
- resources.println("[Parser] Finished parsing parameters.");
+ resources.println("[Parser] Finished parsing parameters");
}
}
diff --git a/src/jcgp/backend/parsers/TestCaseParser.java b/src/jcgp/backend/parsers/TestCaseParser.java
index cef018e..bcfa8a9 100644
--- a/src/jcgp/backend/parsers/TestCaseParser.java
+++ b/src/jcgp/backend/parsers/TestCaseParser.java
@@ -8,14 +8,34 @@ import java.util.Scanner;
import jcgp.backend.modules.problem.TestCaseProblem;
import jcgp.backend.resources.ModifiableResources;
+/**
+ * Contains a static method for parsing values from a
+ * CGP problem data file. The actual file extension
+ * varies from problem to problem, and is therefore
+ * defined in the experiment's Problem instance.
+ *
+ *
+ * @author Eduardo Pedroni
+ *
+ */
public abstract class TestCaseParser {
+ /**
+ * Sets the number of inputs and outputs in the resources
+ * to match the given file, and parses each test case
+ * from the file into the specified problem.
+ *
+ * @param file the problem file to parse.
+ * @param problem the problem into which to parse the problem data.
+ * @param resources a modifiable reference to the experiment's resources
+ */
public static void parse(File file, TestCaseProblem<?> problem, ModifiableResources resources) {
+ // create reader and scanner, print error message if file is missing
FileReader fr;
try {
fr = new FileReader(file);
} catch (FileNotFoundException e) {
- resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + ".");
+ resources.println("[Parser] Error: could not find " + file.getAbsolutePath());
return;
}
resources.println("[Parser] Parsing file: " + file.getAbsolutePath() + "...");
@@ -24,28 +44,44 @@ public abstract class TestCaseParser {
int inputs = 0, outputs = 0;
int cases = 0;
+ // this overwrites any previously added test cases
problem.clearTestCases();
while (in.hasNextLine()) {
String nextLine = in.nextLine();
-
+ // set resources input count to parsed value
if (nextLine.startsWith(".i")) {
String[] split = nextLine.split(" +");
inputs = Integer.parseInt(split[1]);
- } else if (nextLine.startsWith(".o")) {
+ resources.setInputs(inputs);
+ resources.println("[Parser] Number of inputs set to " + resources.inputs());
+ }
+ // set resources output count to parsed value
+ else if (nextLine.startsWith(".o")) {
String[] split = nextLine.split(" +");
outputs = Integer.parseInt(split[1]);
+ resources.setOutputs(outputs);
+ resources.println("[Parser] Number of outputs set to " + resources.outputs());
+
} else if (nextLine.startsWith(".p") || nextLine.startsWith(".t")) {
readingTestCases = true;
+
} else if (nextLine.startsWith(".e")) {
readingTestCases = false;
+
+ /*
+ * Split every line at one or more spaces or tabs, and
+ * parse the two sides into inputs and outputs.
+ */
} else if (readingTestCases) {
String[] split = nextLine.split("( |\t)+");
String[] inputCases = new String[inputs];
String[] outputCases = new String[outputs];
+
for (int i = 0; i < inputs; i++) {
inputCases[i] = split[i];
}
+
for (int o = 0; o < outputs; o++) {
outputCases[o] = split[o + inputs];
}
@@ -54,37 +90,7 @@ public abstract class TestCaseParser {
cases++;
}
}
- resources.println("[Parser] Finished, added " + cases + " test cases.");
- in.close();
- }
-
- public static void parseParameters(File file, ModifiableResources resources) {
-
- FileReader fr;
- try {
- fr = new FileReader(file);
- } catch (FileNotFoundException e) {
- resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + ".");
- return;
- }
-
- resources.println("[Parser] Parsing parameters...");
- Scanner in = new Scanner(fr);
-
- while (in.hasNextLine()) {
- String nextLine = in.nextLine();
- if (nextLine.startsWith(".i")) {
- String[] split = nextLine.split(" +");
- resources.setInputs(Integer.parseInt(split[1]));
- resources.println("[Parser] Number of inputs set to " + resources.inputs());
- } else if (nextLine.startsWith(".o")) {
- String[] split = nextLine.split(" +");
- resources.setOutputs(Integer.parseInt(split[1]));
- resources.println("[Parser] Number of outputs set to " + resources.outputs());
- }
- }
+ resources.println("[Parser] Finished, added " + cases + " test cases");
in.close();
-
- resources.println("[Parser] Finished parsing parameters.");
}
}