diff options
| author | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2018-06-05 13:50:31 -0300 |
|---|---|---|
| committer | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2018-06-05 13:50:31 -0300 |
| commit | 0164b842d14675b0a28dd143d36923e690e75d27 (patch) | |
| tree | f78674448a6ddf7acabf344d8f558adc2608b578 /src/main/java | |
| parent | a3da25a2988bab62a565a7cd2422a3150b85cbb5 (diff) | |
Config work
More work for getting going on templates, as well as just some
refactoring for future changes
Diffstat (limited to 'src/main/java')
| -rw-r--r-- | src/main/java/bjc/rgens/parser/ConfigLoader.java | 178 | ||||
| -rw-r--r-- | src/main/java/bjc/rgens/parser/ConfigSet.java | 13 | ||||
| -rw-r--r-- | src/main/java/bjc/rgens/parser/GrammarTemplate.java | 5 | ||||
| -rwxr-xr-x | src/main/java/bjc/rgens/parser/RGrammar.java | 12 | ||||
| -rwxr-xr-x | src/main/java/bjc/rgens/parser/RGrammarTest.java | 2 | ||||
| -rwxr-xr-x | src/main/java/bjc/rgens/parser/RGrammars.java | 2 |
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"); |
