summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/rgens
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/bjc/rgens')
-rw-r--r--src/main/java/bjc/rgens/parser/ConfigLoader.java178
-rw-r--r--src/main/java/bjc/rgens/parser/ConfigSet.java13
-rw-r--r--src/main/java/bjc/rgens/parser/GrammarTemplate.java5
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammar.java12
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammarTest.java2
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammars.java2
6 files changed, 204 insertions, 8 deletions
diff --git a/src/main/java/bjc/rgens/parser/ConfigLoader.java b/src/main/java/bjc/rgens/parser/ConfigLoader.java
new file mode 100644
index 0000000..26c5f66
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/ConfigLoader.java
@@ -0,0 +1,178 @@
+package bjc.rgens.parser;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Scanner;
+
+public class ConfigLoader {
+ /**
+ * Load a grammar set from a configuration file.
+ *
+ * @param cfgFile
+ * The configuration file to load from.
+ *
+ * @return
+ * The grammar set created by the configuration file.
+ *
+ * @throws IOException
+ * If something goes wrong during configuration loading.
+ */
+ public static RGrammarSet fromConfigFile(Path cfgFile) throws IOException {
+ /* The grammar set to hand back. */
+ RGrammarSet set = new RGrammarSet();
+
+ long startCFGTime = System.nanoTime();
+
+ /* Get the directory that contains the config file. */
+ Path cfgParent = cfgFile.getParent();
+
+ try(Scanner scn = new Scanner(cfgFile)) {
+ int lno = 0;
+
+ /* Execute lines from the configuration file. */
+ while (scn.hasNextLine()) {
+ String ln = scn.nextLine().trim();
+
+ lno += 1;
+
+ try {
+ /* Ignore blank/comment lines. */
+ if (ln.equals("")) return;
+
+ if (ln.startsWith("#")) return;
+
+ /* Handle mixed whitespace. */
+ ln = ln.replaceAll("\\s+", " ");
+
+ /* Get line type */
+ int typeIdx = ln.indexOf(" ');
+ if(typeIdx == -1) {
+ throw new GrammarException("Must specify config line type");
+ }
+ String type = ln.substring(0, typeIdx).trim();
+ ln = ln.substring(typeIdx).trim();
+
+ switch(type) {
+ case "load":
+ loadConfigLine(ln, set, cfgParent);
+ break;
+ default:
+ throw new GrammarException("Unknown config line type " + type);
+ }
+ } catch(GrammarException gex) {
+ System.out.printf("ERROR: Line %s of grammar set %s\n", lno, cfgFile);
+
+ System.err.printf("ERROR: Line %s of grammar set %s\n", lno, cfgFile);
+ gex.printStackTrace();
+
+ System.out.println();
+ System.out.println();
+
+ System.err.println();
+ System.err.println();
+ }
+ }
+ }
+
+ long endCFGTime = System.nanoTime();
+
+ long cfgDur = endCFGTime - startCFGTime;
+
+ System.err.printf("\n\nPERF: Read config file %s in %d ns (%f s)\n", cfgFile, cfgDur, cfgDur / 1000000000.0);
+
+ return set;
+ }
+
+ private static void loadConfigLine(String ln, RGrammarSet set, Path cfgParent) throws IOException {
+
+ /*
+ * Get the place where the tag ID ends
+ */
+ int tagIdx = ln.indexOf(" ");
+ if(tagIdx == -1) {
+ throw new GrammarException("Must specify a tag as to what a line is");
+ }
+ String tag = ln.substring(0, tagIdx).trim();
+ ln = ln.substring(tagIdx).trim();
+
+ /*
+ * Get the place where the name of the grammar
+ * ends.
+ */
+ int nameIdx = ln.indexOf(" ");
+ if (nameIdx == -1) {
+ throw new GrammarException("Must specify a name for a loaded object");
+ }
+ String name = ln.substring(0, nameIdx);
+ ln = ln.substring(nameIdx).trim();
+
+ switch(tag) {
+ case "template":
+ {
+ throw new GrammarException("Templates aren't implemented yet");
+ }
+ case "subset":
+ {
+ /* @TODO implement subset grammars */
+ throw new GrammarException("Sub-grammar sets aren't implemented yet");
+ }
+ case "gram":
+ case "grammar":
+ {
+ Path path = Paths.get(ln);
+
+ /*
+ * Convert from configuration relative path to
+ * absolute path.
+ */
+ Path convPath = cfgParent.resolve(path.toString());
+
+ if(Files.isDirectory(convPath)) {
+ throw new GrammarException("Can't load grammar from directory" + convPath.toString());
+ } else {
+ /* Load grammar file. */
+ try {
+ long startFileTime = System.nanoTime();
+
+ BufferedReader fis = Files.newBufferedReader(convPath);
+ RGrammar gram = RGrammarParser.readGrammar(fis);
+ if(gram.name == null) {
+ System.err.printf("\tINFO: Naming unnamed grammar loaded from %s off config name %s\n",
+ convPath, name);
+
+ gram.name = name;
+ }
+
+ fis.close();
+
+ long endFileTime = System.nanoTime();
+
+ long fileTime = endFileTime - startFileTime;
+
+ System.err.printf("\tPERF: Read grammar %s (from %s) in %d ns (%f s)\n",
+ gram.name, convPath, fileTime, fileTime / 1000000000.0);
+
+ /* Add grammar to the set. */
+ set.addGrammar(name, gram);
+
+ /*
+ * Mark where the grammar came
+ * from.
+ */
+ set.loadedFrom.put(name, path.toString());
+ } catch (GrammarException gex) {
+ String msg = String.format("Error loading file '%s'", path);
+ throw new GrammarException(msg, gex);
+ }
+ }
+ }
+ break;
+ default:
+ String msg = String.format("Unrecognized tag type '%s'", tag);
+ throw new GrammarException(msg);
+ }
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/ConfigSet.java b/src/main/java/bjc/rgens/parser/ConfigSet.java
new file mode 100644
index 0000000..949962c
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/ConfigSet.java
@@ -0,0 +1,13 @@
+package bjc.rgens.parser;
+
+public class ConfigSet {
+ public final Map<String, RGrammarSet> grammars;
+ public final Map<String, GrammarTemplate> templates;
+ public final Map<String, ConfigSet> subconfigs;
+
+ public ConfigSet() {
+ grammars = new HashMap<>();
+ templates = new HashMap<>();
+ subconfigs = new HashMap<>();
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/GrammarTemplate.java b/src/main/java/bjc/rgens/parser/GrammarTemplate.java
new file mode 100644
index 0000000..8d13877
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/GrammarTemplate.java
@@ -0,0 +1,5 @@
+package bjc.rgens.parser;
+
+public class GrammarTemplate {
+ public final List<String> lines;
+}
diff --git a/src/main/java/bjc/rgens/parser/RGrammar.java b/src/main/java/bjc/rgens/parser/RGrammar.java
index 1b68c80..381eac1 100755
--- a/src/main/java/bjc/rgens/parser/RGrammar.java
+++ b/src/main/java/bjc/rgens/parser/RGrammar.java
@@ -31,6 +31,8 @@ import edu.gatech.gtri.bktree.MutableBkTree;
* @author EVE
*/
public class RGrammar {
+ public String name;
+
/* The max distance between possible alternate rules. */
private static final int MAX_DISTANCE = 6;
@@ -51,9 +53,6 @@ public class RGrammar {
}
}
- /* The pattern for matching the name of a variable. */
- private static Pattern NAMEVAR_PATTERN = Pattern.compile("\\$(\\w+)");
-
/* The rules of the grammar. */
private Map<String, Rule> rules;
/* The rules imported from other grammars. */
@@ -163,7 +162,7 @@ public class RGrammar {
if(rl.doRecur()) {
RuleCase start = rules.get(fromRule).getCase(state.rnd);
- System.err.printf("\tFINE: Generating %s (from %s)\n", start, fromRule);
+ System.err.printf("\tFINE: Generating %s (from %s in %s)\n", start, fromRule, name);
generateCase(start, state);
@@ -266,7 +265,7 @@ public class RGrammar {
if (initRule.equals("")) {
throw new GrammarException("The empty string is not a valid rule name");
} else if (!rules.containsKey(initRule)) {
- String msg = String.format("No rule '%s' local to this grammar defined.", initRule);
+ String msg = String.format("No rule '%s' local to this grammar (%s) defined.", initRule, name);
throw new GrammarException(msg);
}
@@ -286,7 +285,8 @@ public class RGrammar {
for (String rname : exportRules) {
if (!rules.containsKey(rname)) {
- String msg = String.format("No rule '%s' local to this grammar defined", initialRule);
+ String msg = String.format("No rule '%s' local to this grammar (%s) defined for export",
+ name, rname);
throw new GrammarException(msg);
}
diff --git a/src/main/java/bjc/rgens/parser/RGrammarTest.java b/src/main/java/bjc/rgens/parser/RGrammarTest.java
index e4811d4..0238fc0 100755
--- a/src/main/java/bjc/rgens/parser/RGrammarTest.java
+++ b/src/main/java/bjc/rgens/parser/RGrammarTest.java
@@ -19,7 +19,7 @@ public class RGrammarTest {
* Unused CLI args.
*/
public static void main(String[] args) {
- URL rsc = RGrammarTest.class.getResource("/server-config-sample.cfg");
+ URL rsc = RGrammarTest.class.getResource("/server-config-sample.gcfg");
try {
/* Load a grammar set. */
diff --git a/src/main/java/bjc/rgens/parser/RGrammars.java b/src/main/java/bjc/rgens/parser/RGrammars.java
index df612ac..ad94388 100755
--- a/src/main/java/bjc/rgens/parser/RGrammars.java
+++ b/src/main/java/bjc/rgens/parser/RGrammars.java
@@ -20,7 +20,7 @@ public class RGrammars {
private static void loadSet() {
try {
- URI rsc = RGrammarTest.class.getResource("/server-config-sample.cfg").toURI();
+ URI rsc = RGrammarTest.class.getResource("/server-config-sample.gcfg").toURI();
Map<String, String> env = new HashMap<>();
env.put("create", "true");