diff options
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/java/bjc/rgens/parser/ConfigLoader.java | 113 | ||||
| -rw-r--r-- | src/main/java/bjc/rgens/parser/ConfigSet.java | 42 | ||||
| -rw-r--r-- | src/main/java/bjc/rgens/parser/FlatRuleCase.java | 19 | ||||
| -rw-r--r-- | src/main/java/bjc/rgens/parser/GenerationState.java | 149 | ||||
| -rwxr-xr-x | src/main/java/bjc/rgens/parser/GrammarException.java | 5 | ||||
| -rw-r--r-- | src/main/java/bjc/rgens/parser/NormalRuleCase.java | 19 | ||||
| -rwxr-xr-x | src/main/java/bjc/rgens/parser/RGrammar.java | 67 | ||||
| -rwxr-xr-x | src/main/java/bjc/rgens/parser/RGrammarParser.java | 2 | ||||
| -rwxr-xr-x | src/main/java/bjc/rgens/text/markov/Markov.java | 5 |
9 files changed, 377 insertions, 44 deletions
diff --git a/src/main/java/bjc/rgens/parser/ConfigLoader.java b/src/main/java/bjc/rgens/parser/ConfigLoader.java index 028d99e..ee3476b 100644 --- a/src/main/java/bjc/rgens/parser/ConfigLoader.java +++ b/src/main/java/bjc/rgens/parser/ConfigLoader.java @@ -27,6 +27,17 @@ import bjc.rgens.parser.templates.GrammarTemplate; import bjc.utils.funcutils.FileUtils; import bjc.utils.ioutils.LevelSplitter; +/* + * @TODO @CLEANUP Ben Culkin 7/21/2019 :LoadingInfo + * Instead of using the same tree for both storing errors and storing other + * things, there should be a data structure where we stuff a couple of trees + * that track things like errors, warnings, information etc. + * + * For a counterpoint on the benefits we get from the integrated tree, and the + * possibility of using our own that stores the stuff we want, see the note + * below at :ErrorLine + */ + /** * Class that performs loading of grammar sets from config files. * @@ -46,7 +57,7 @@ public class ConfigLoader { * If something goes wrong during configuration loading. */ public static ConfigSet fromConfigFile(Path cfgFile, LoadOptions lopts) throws IOException { - String msg = String.format("INFO: Loading config file %s", cfgFile); + String msg = String.format("INFO: Loading config file from path '%s'", cfgFile); ITree<String> errTree = new Tree<>(msg); @@ -80,25 +91,57 @@ public class ConfigLoader { // Get the directory that contains the config file. if (lopts.parent == null) lopts.parent = cfgFile.getParent(); + int lno = 0; try(Scanner scn = new Scanner(cfgFile)) { - int lno = 0; while (scn.hasNextLine()) { // Execute a line from the configuration file. + + // @NOTE: Do we want to also track logical + // lines, or just physical ones? - ben, + // 9/21/2019 lno += 1; + // @NOTE: Does this replaceAll need to exist? - + // ben, 9/21/2019 String ln = scn.nextLine().trim().replaceAll("\\s+", " "); // Ignore blank/comment lines. if (ln.equals("")) continue; if (ln.startsWith("#")) continue; - ITree<String> header = new Tree<>(String.format("INFO: Processed line %d", lno)); + // @TODO Ben Culkin 9/21/2019 :LineCont + // We should support some sort of line + // continuation ability, probably using the '\' + // since that what UNIX uses in most places + ITree<String> header = new Tree<>(String.format("INFO: Processing line %d", lno)); String[] parts = StringUtils.levelSplit(ln, " ").toArray(new String[0]); if(parts.length < 1) { // Must specify a line type + // + // @TODO Ben Culkin 9/21/2019 :ErrorLine + // Think about whether there is a better + // way to do tracking of the line number + // and adding it to the messages we + // generate. + // + // We do need a better way to pass along + // filename/line number pairs to various + // parts of the code + // + // Actually, do we? As long as we stick + // with this integrated tree design, and + // then just print all the nodes on the + // way to the error, folding away all + // of the other nodes, it should be just + // fine. In fact, if we do our own tree + // impl. (since we don't care that much + // about any of the features from + // FunctionalTree, and have our own sort + // of stuff we want to be tracking in + // the nodes) it may actually be faster. header.addChild("ERROR: Must specify config line type"); } else { String type = parts[0]; @@ -108,7 +151,7 @@ public class ConfigLoader { loadConfigLine(parts, lopts, header); break; default: - String fmt = String.format("ERROR: Unknown config line type %s", type); + String fmt = String.format("ERROR: Unknown config line type '%s'", type); header.addChild(fmt); } @@ -123,7 +166,7 @@ public class ConfigLoader { long cfgDur = endCFGTime - startCFGTime; if (lopts.doPerf) { - String fmt = String.format("PERF: Read config file %s in %d ns (%f s)", cfgFile, cfgDur, cfgDur / 1000000000.0); + String fmt = String.format("PERF: Read config file (%d lines) from path '%s' in %d ns (%f s)", lno, cfgFile, cfgDur, cfgDur / 1000000000.0); errs.addChild(fmt); } @@ -131,9 +174,16 @@ public class ConfigLoader { return lopts.cfgSet; } + // Load a line from a config file. private static void loadConfigLine(String[] parts, LoadOptions lopts, ITree<String> errs) throws IOException { if(parts.length < 2) { - // Must specify an object type + // Must specify the type of config object you wish to + // load. + // + // @TODO Ben Culkin 9/21/2019 :AutoType + // Maybe add some sort of support for determining the + // type of the config object based of the file we want + // to load it from? errs.addChild("ERROR: Must specify type for config object"); return; @@ -142,7 +192,13 @@ public class ConfigLoader { String tag = parts[1]; if (parts.length < 3) { - // Must specify an object name + // All loaded config objects require that a name be + // bound to them. + // + // @TODO Ben Culkin 9/21/2019 :AutoName + // Perhaps do a thing that auto-picks a plausible name + // for the object based off of the file name we're + // loading from? String fmt = String.format("ERROR: Must specify a name for config object of type '%s'", tag); errs.addChild(fmt); @@ -163,7 +219,6 @@ public class ConfigLoader { /* * @TODO Ben Culkin 9/8/17 :SubsetGrammar * Implement subset grammars. - * */ errs.addChild(fmt); } @@ -181,6 +236,8 @@ public class ConfigLoader { } } + // Load a 'directory' config object, by recursively attempting to + // auto-load all of the items in the directory as objects private static void loadDirectory(String name, String[] parts, LoadOptions lopts, ITree<String> errs) throws IOException { if(parts.length < 4) { String fmt = String.format("ERROR: Must specify a path to load directory '%s' from", name); @@ -204,28 +261,36 @@ public class ConfigLoader { errs.addChild(fmt); } else { // Create an iterator over all of the files in the - // provided directory + // provided directory. This will also have the files for + // the sub-directories added to it as well QueuedIterator<File> dirItr = new QueuedIterator<>(dirPath.toFile().listFiles()); - ITree<String> header = new Tree<>(String.format("INFO: Bulk-loading files from directory '%s'", lopts.parent)); + ITree<String> header = new Tree<>(String.format("INFO: Bulk-loading objects from directory '%s'", lopts.parent)); while (dirItr.hasNext()) { File curFile = dirItr.next(); String fName = curFile.toString(); - ITree<String> kid = new Tree<>(String.format("INFO: Processing file '%s'", fName)); + ITree<String> kid = new Tree<>(String.format("INFO: Processing object from path '%s'", fName)); Path oldPar = lopts.parent; + + // Reset the parent to be the directory for the + // current file. lopts.parent = curFile.toPath().getParent(); try { + // @NOTE: This can probably be reused + // for :AutoType and :AutoName, if we + // abstract parts of it out in some + // way... if (curFile.isDirectory()) { dirItr.last(curFile.listFiles()); } else if (fName.endsWith(".gram")) { Reader rdr = new FileReader(curFile); - doLoadGrammar(rdr, null, lopts, kid); + doLoadGrammar(rdr, null, lopts, kid, curFile.toPath()); } else if (fName.endsWith(".gtpl")) { Reader rdr = new FileReader(curFile); @@ -241,6 +306,7 @@ public class ConfigLoader { } catch (IOException ioex) { kid.addChild("ERROR: " + ioex.getMessage()); } finally { + // Reset the parent to its actual value. lopts.parent = oldPar; } @@ -251,6 +317,7 @@ public class ConfigLoader { } } + // Actually do the work of loading a 'template' object private static void doLoadTemplate(Reader rdr, String name, LoadOptions lopts, ITree<String> errs) throws IOException { String actName; @@ -261,7 +328,7 @@ public class ConfigLoader { if(template.name == null) { if(name == null) { - String fmt = String.format("INFO: Using default name for template"); + String fmt = String.format("WARN: Using default name for template"); errs.addChild(fmt); @@ -288,7 +355,7 @@ public class ConfigLoader { errs.addChild(fmt); } - /* Add grammar to the set. */ + /* Add template to the set. */ lopts.cfgSet.templates.put(template.name, template); /* @@ -296,11 +363,14 @@ public class ConfigLoader { * * Do we need to do this for templates? * + * Probably, if only to allow for some better diagnostics when + * we need them - ben, 9/21/2019 */ //Mark where the template came from. //set.loadedFrom.put(template.name, path.toString()); } + // Load a 'template' type grammar object private static void loadTemplate(String name, String[] parts, LoadOptions lopts, ITree<String> errs) throws IOException { if(parts.length < 4) { String fmt = String.format("ERROR: Must specify a path to load template '%s' from", name); @@ -342,7 +412,8 @@ public class ConfigLoader { } } - private static void doLoadGrammar(Reader rdr, String name, LoadOptions lopts, ITree<String> errs) throws IOException { + // Actually load a 'grammar' object + private static void doLoadGrammar(Reader rdr, String name, LoadOptions lopts, ITree<String> errs, Path convPath) throws IOException { String actName; long startFileTime = System.nanoTime(); @@ -350,14 +421,14 @@ public class ConfigLoader { RGrammar gram = RGrammarParser.readGrammar(rdr, lopts, errs); if(gram.name == null) { if(name == null) { - errs.addChild("INFO: Using default name for grammar"); + errs.addChild("WARN: Using default name for grammar"); actName = "default-name"; } else { actName = name; } - String fmt = String.format("Naming unnamed grammar off config name '%s'", actName); + String fmt = String.format("INFO: Naming unnamed grammar off config name '%s'", actName); gram.name = actName; } @@ -381,9 +452,10 @@ public class ConfigLoader { * Mark where the grammar came * from. */ - lopts.gramSet.loadedFrom.put(gram.name, lopts.parent.toString()); + lopts.gramSet.loadedFrom.put(gram.name, convPath.toString()); } + // Load a 'grammar' object private static void loadGrammar(String name, String[] parts, LoadOptions lopts, ITree<String> errs) throws IOException { if(parts.length < 4) { String fmt = String.format("ERROR: Must provide a path to load grammar '%s' from", name); @@ -402,7 +474,7 @@ public class ConfigLoader { Path convPath = lopts.parent.resolve(path.toString()); if(!Files.exists(convPath) || Files.isDirectory(convPath)) { - String fmt = String.format("ERROR: %s is not a valid grammar file", convPath); + String fmt = String.format("ERROR: '%s' is not a valid grammar file", convPath); errs.addChild(fmt); } else { @@ -416,7 +488,8 @@ public class ConfigLoader { Reader rdr = new FileReader(convPath.toFile()); ITree<String> kid = new Tree<>(String.format("INFO: Loading grammar '%s' from '%s'", name, convPath)); - doLoadGrammar(rdr, name, lopts, kid); + + doLoadGrammar(rdr, name, lopts, kid, convPath); errs.addChild(kid); } catch (IOException ioex) { diff --git a/src/main/java/bjc/rgens/parser/ConfigSet.java b/src/main/java/bjc/rgens/parser/ConfigSet.java index 8d7c63e..0ed8167 100644 --- a/src/main/java/bjc/rgens/parser/ConfigSet.java +++ b/src/main/java/bjc/rgens/parser/ConfigSet.java @@ -5,23 +5,65 @@ import java.util.Map; import bjc.rgens.parser.templates.GrammarTemplate; +/** + * Represents a collection of grammar sets, templates and subcollections of the same + * that are logically grouped together. + * + * In many cases, there will be a one-to-one mapping between grammar sets and + * config sets, but that doesn't have to be the case. In addition, the config + * set provides a convenient place to set the non-grammar objects that are + * defined via config files, such as templates, or Markov generators. + * + * @author Ben Culkin + */ public class ConfigSet { + // @NOTE Should these fields be public, or do we want to create accessor + // methods for them, since at least grammars have some extra stuff that + // needs to be done when they are associated/unassociated with a config + // set. + /* + * Represents all of the grammar sets that are mapped into this config + * set. + */ public final Map<String, RGrammarSet> grammars; + + /* + * Represents all of the templates that are mapped into this config set. + */ public final Map<String, GrammarTemplate> templates; + + /* + * Represents all of the sub-configurations that are mapped into this + * config set. + */ public final Map<String, ConfigSet> subconfigs; + /** + * Create a new blank config set. + */ public ConfigSet() { grammars = new HashMap<>(); templates = new HashMap<>(); subconfigs = new HashMap<>(); } + /** + * Create a grammar set with the given name in this config set. + * + * @param name + * The name of the grammar set to create. + * + * @return The grammar set, properly bound and initialized for this + * config set. + */ public RGrammarSet createGSet(String name) { RGrammarSet st = new RGrammarSet(); + // Init. the properties of the grammar set st.belongsTo = this; st.name = name; + // Add it to ourselves grammars.put(name, st); return st; diff --git a/src/main/java/bjc/rgens/parser/FlatRuleCase.java b/src/main/java/bjc/rgens/parser/FlatRuleCase.java index 3e5378e..18559a1 100644 --- a/src/main/java/bjc/rgens/parser/FlatRuleCase.java +++ b/src/main/java/bjc/rgens/parser/FlatRuleCase.java @@ -5,7 +5,18 @@ import bjc.utils.funcdata.IList; import java.util.List; +/** + * A rule case that inserts nothing in between case elements. + * + * @author Ben Culkin + */ public class FlatRuleCase extends RuleCase { + /** + * Create a new flat rule case. + * + * @param elms + * The case elements that make up this case. + */ public FlatRuleCase(List<CaseElement> elms) { super(elms); } @@ -17,6 +28,14 @@ public class FlatRuleCase extends RuleCase { } } + /** + * Create a new flat rule case with the given case elements. + * + * @param elms + * The elements to use for the rule case. + * + * @return A flat rule case, with the given elements. + */ public FlatRuleCase withElements(List<CaseElement> elms) { return new FlatRuleCase(elms); } diff --git a/src/main/java/bjc/rgens/parser/GenerationState.java b/src/main/java/bjc/rgens/parser/GenerationState.java index ad2282c..7a7adb9 100644 --- a/src/main/java/bjc/rgens/parser/GenerationState.java +++ b/src/main/java/bjc/rgens/parser/GenerationState.java @@ -11,44 +11,49 @@ import java.util.Random; import bjc.utils.esodata.MapSet; import bjc.utils.ioutils.ReportWriter; -/* +import static bjc.rgens.parser.RGrammarLogging.*; +/** * The current state during generation. * + * @author Ben Culkin */ public class GenerationState { - /** The current string. */ + /* The current output. */ private ReportWriter contents; /** The RNG. */ public Random rnd; /** The current grammar. */ public RGrammar gram; - /** The rules of the grammar. */ + + /* The rules of the grammar. */ private Map<String, Rule> rules; - /** The rules imported from other grammars. */ + /* The rules imported from other grammars. */ private Map<String, Rule> importRules; /** The current set of variables. */ private MapSet<String, String> vars; private MapSet<String, Rule> rlVars; + /* The base random number generator. */ private static final Random BASE = new Random(); /** * Create a new generation state. * - * @param rw - * The place to write the string. + * The place to write output to. * * @param rand - * The RNG to use. + * The random number generator to use. * * @param vs - * The variables to use. + * The normal variables to use. + * * @param rvs - * The rule variables to use. + * The rule variables to use. + * * @param gram - * The current grammar. + * The grammar we are generating from. */ public GenerationState(ReportWriter rw, Random rand, Map<String, String> vs, Map<String, Rule> rvs, RGrammar gram) { @@ -67,16 +72,44 @@ public class GenerationState { this.importRules = gram.getImportRules(); } + /** + * Create a new generation state, from a given grammar. + * + * @param gram + * The grammar to generate from. + * + * @return + * A new generation state, with the provided parameters. + */ public static GenerationState fromGrammar(RGrammar gram) { return fromGrammar(BASE, gram); } + /** + * Create a new generation state, using a provided random generator and + * grammar. + * + * @param rand + * The random number generator to use. + * + * @param gram + * The grammar to generate from. + * + * @return + * A new generation state, with the provided parameters. + */ public static GenerationState fromGrammar(Random rand, RGrammar gram) { ReportWriter rw = new ReportWriter(new StringWriter()); return new GenerationState(rw, rand, new HashMap<>(), new HashMap<>(), gram); } + /** + * Swap the grammar for the state. + * + * @param gram + * The grammar to swap to. + */ public void swapGrammar(RGrammar gram) { if (this.gram == gram) return; @@ -90,6 +123,12 @@ public class GenerationState { rlVars.setCreateMap(gram.name); } + /** + * Create a copy of this generation state, writing into a fresh buffer. + * + * @return A generation state that is a copy of this one, but writes into a + * fresh buffer. + */ public GenerationState newBuf() { // @NOTE 9/5/18 // @@ -110,6 +149,18 @@ public class GenerationState { * they are importing the rule from, so as to make it clear which rules * are imported, and which aren't */ + /** + * Find an instance of a rule. + * + * @param ruleName + * The name of the rule to look for. + * + * @param allowImports + * Whether or not to look for imported rules. + * + * @return The rule instance you were looking for, or null if none by that + * name happen to exist. + */ public Rule findRule(String ruleName, boolean allowImports) { if (rules.containsKey(ruleName)) { return rules.get(ruleName); @@ -120,6 +171,15 @@ public class GenerationState { return null; } + /** + * Find an instance of an imported rule. + * + * @param ruleName + * The name of the rule to look for. + * + * @return The rule instance you were looking for, or null if none by that + * name happen to exist. + */ public Rule findImport(String ruleName) { if (importRules.containsKey(ruleName)) { return importRules.get(ruleName); @@ -128,6 +188,15 @@ public class GenerationState { return null; } + /** + * Define a normal variable. + * + * @param name + * The name to give the variable. + * + * @param val + * The value to give the variable. + */ public void defineVar(String name, String val) { if (vars.containsKey(name)) warn("Shadowing variable %s with value %s (old value %s)", name, val, vars.get(name)); @@ -137,6 +206,15 @@ public class GenerationState { vars.put(name, val); } + /** + * Define a rule variable. + * + * @param name + * The name to give the variable. + * + * @param rle + * The value to give the variable. + */ public void defineRuleVar(String name, Rule rle) { if (rlVars.containsKey(name)) warn("Shadowing rule variable %s with value %s (old value %s)", name, rlVars.get(name), rle); @@ -147,6 +225,17 @@ public class GenerationState { rlVars.put(name, rle); } + /** + * Find a variable. + * + * @param name + * The variable to look for. + * + * @return The value of the variable. + * + * @throws GrammarException If the variable isn't found, or if it was an + * auto-variable that failed to generate succesfully. + */ public String findVar(String name) { if (!vars.containsKey(name)) if (gram.autoVars.containsKey(name)) { gram.autoVars.get(name).generate(this); @@ -157,6 +246,17 @@ public class GenerationState { return vars.get(name); } + /** + * Find a rule variable. + * + * @param name + * The variable to look for. + * + * @return The value of the variable. + * + * @throws GrammarException If the variable isn't found, or if it was an + * auto-variable that failed to generate succesfully. + */ public Rule findRuleVar(String name) { if (!rlVars.containsKey(name)) if (gram.autoRlVars.containsKey(name)) { gram.autoRlVars.get(name).generate(this); @@ -167,6 +267,9 @@ public class GenerationState { return rlVars.get(name); } + /** + * Append the given string to our output. + */ public void appendContents(String strang) { try { contents.write(strang); @@ -175,6 +278,12 @@ public class GenerationState { } } + /** + * Replace the current contents of our output with the given string. + * + * @param strang + * The string to replace the output with. + */ public void setContents(String strang) { // @NOTE 9/5/18 // @@ -193,18 +302,38 @@ public class GenerationState { } } + /** + * Get the report writer that we use for our input. + * + * @return The report writer that we write stuff & things to. + */ public ReportWriter getWriter() { return contents; } + /** + * Get our output as a string. + */ public String getContents() { return contents.toString(); } + /** + * Execute a find/replace on our output. + * + * @param find + * The pattern to look for + * + * @param replace + * The string to replace occurances of 'find' with. + */ public void findReplaceContents(String find, String replace) { setContents(getContents().replaceAll(find, replace)); } + /** + * Clear out our contents. + */ public void clearContents() { contents = contents.duplicate(new StringWriter()); } diff --git a/src/main/java/bjc/rgens/parser/GrammarException.java b/src/main/java/bjc/rgens/parser/GrammarException.java index ea98206..271f717 100755 --- a/src/main/java/bjc/rgens/parser/GrammarException.java +++ b/src/main/java/bjc/rgens/parser/GrammarException.java @@ -64,6 +64,11 @@ public class GrammarException extends RuntimeException { this.rootMessage = rootMsg; } + /** + * Get the root cause of this exception. + * + * @return The root cause of this exception. + */ public String getRootMessage() { return rootMessage == null? getMessage() : rootMessage; } diff --git a/src/main/java/bjc/rgens/parser/NormalRuleCase.java b/src/main/java/bjc/rgens/parser/NormalRuleCase.java index dcb56cb..95926c0 100644 --- a/src/main/java/bjc/rgens/parser/NormalRuleCase.java +++ b/src/main/java/bjc/rgens/parser/NormalRuleCase.java @@ -5,7 +5,18 @@ import java.util.List; import bjc.rgens.parser.elements.CaseElement; import bjc.utils.funcdata.IList; +/** + * A rule case that inserts spaces in between elements, where appropriate. + * + * @author Ben Culkin + */ public class NormalRuleCase extends RuleCase { + /** + * Create a new normal rule case. + * + * @param elms + * The elements of this case. + */ public NormalRuleCase(List<CaseElement> elms) { super(elms); } @@ -21,6 +32,14 @@ public class NormalRuleCase extends RuleCase { } } + /** + * Create a new normal rule case. + * + * @param elms + * The elements of this case. + * + * @return A normal rule case with those elements. + */ public NormalRuleCase withElements(List<CaseElement> elms) { return new NormalRuleCase(elms); } diff --git a/src/main/java/bjc/rgens/parser/RGrammar.java b/src/main/java/bjc/rgens/parser/RGrammar.java index 5b2ae08..cca7c01 100755 --- a/src/main/java/bjc/rgens/parser/RGrammar.java +++ b/src/main/java/bjc/rgens/parser/RGrammar.java @@ -35,12 +35,22 @@ import edu.gatech.gtri.bktree.MutableBkTree; * @author EVE */ public class RGrammar { + /** + * The grammar set this grammar belongs to. + */ public RGrammarSet belongsTo; + /** + * The name of this grammar. + */ public String name; + /** + * The post-processing find/replace pairs applied to this grammars outputs. + */ public List<IPair<String, String>> postprocs; + /* The default post-processing rules to apply. */ private static final List<IPair<String, String>> builtinPostprocs; public boolean useBuiltinPostprocs = true; @@ -65,8 +75,11 @@ public class RGrammar { } } - /* The rules of the grammar. */ + /** + * The rules of the grammar. + */ public Map<String, Rule> rules; + /* The rules imported from other grammars. */ private Map<String, Rule> importRules; /* The rules exported from this grammar. */ @@ -75,7 +88,14 @@ public class RGrammar { /* The initial rule of this grammar. */ private String initialRule; + /** + * The normal auto-variables for this grammar. + */ public Map<String, CaseElement> autoVars; + + /** + * The rule auto-variables for this grammar. + */ public Map<String, CaseElement> autoRlVars; /* The tree to use for finding rule suggestions. */ @@ -119,6 +139,7 @@ public class RGrammar { pair("\\s(ish|burg|ton|ville|opolis|field|boro|dale)", "$1") ); } + /** * Create a new randomized grammar using the specified set of rules. * @@ -177,14 +198,16 @@ public class RGrammar { * Generate a string from this grammar, starting from the specified rule. * * @param startRule - * The rule to start generating at, or null to use the initial rule - * for this grammar. + * The rule to start generating at, or null to use the initial rule for this grammar. * * @param rnd - * The random number generator to use. + * The random number generator to use. * * @param vars - * The set of variables to use. + * The set of variables to use. + * + * @param rlVars + * The set of rule variables to use. * * @return A possible string from the grammar. */ @@ -199,8 +222,7 @@ public class RGrammar { * Generate a string from this grammar, starting from the specified rule. * * @param startRule - * The rule to start generating at, or null to use the initial rule - * for this grammar. + * The rule to start generating at, or null to use the initial rule for this grammar. * * @param state * The generation state. @@ -209,6 +231,18 @@ public class RGrammar { return generate(startRule, state, true); } + /** + * Generate a string from this grammar, starting from the specified rule. + * + * @param startRule + * The rule to start generating at, or null to use the initial rule for this grammar. + * + * @param doPostprocess + * Whether or not we should perform post-processing of our output. + * + * @param state + * The generation state. + */ public String generate(String startRule, GenerationState state, boolean doPostprocess) { String fromRule = startRule; @@ -224,10 +258,7 @@ public class RGrammar { } } - /* - * We don't search imports, so it will always belong to this - * grammar. - */ + /* We don't search imports for the initial rule, so it will always belong to this grammar. */ Rule rl = state.findRule(fromRule, false); if(rl == null) @@ -244,6 +275,7 @@ public class RGrammar { return body; } + /* Postprocess the output. */ private String postprocessRes(String strang) { String body = strang; @@ -264,6 +296,7 @@ public class RGrammar { * * @param start * The rule case to generate. + * * @param state * The current generation state. */ @@ -289,13 +322,21 @@ public class RGrammar { * Set the initial rule of this grammar. * * @param initRule - * The initial rule of this grammar, or null to say there is no - * initial rule. + * The initial rule of this grammar, or null to say there is no initial rule. */ public void setInitialRule(String initRule) { setInitialRule(initRule, new Tree<>()); } + /** + * Set the initial rule of this grammar. + * + * @param initRule + * The initial rule of this grammar, or null to say there is no initial rule. + * + * @param errs + * The tree to store errors in. + */ public void setInitialRule(String initRule, ITree<String> errs) { /* Passing null, nulls our initial rule. */ if (initRule == null) { diff --git a/src/main/java/bjc/rgens/parser/RGrammarParser.java b/src/main/java/bjc/rgens/parser/RGrammarParser.java index a1dce8a..4a6ba8d 100755 --- a/src/main/java/bjc/rgens/parser/RGrammarParser.java +++ b/src/main/java/bjc/rgens/parser/RGrammarParser.java @@ -154,7 +154,7 @@ public class RGrammarParser { try (BlockReader reader = new SimpleBlockReader(dlm, is)) { if (!reader.hasNextBlock()) { - errs.addChild("At least one top-level block must be present"); + errs.addChild("ERROR: At least one top-level block must be present"); return null; } diff --git a/src/main/java/bjc/rgens/text/markov/Markov.java b/src/main/java/bjc/rgens/text/markov/Markov.java index c428dcb..1fff8c9 100755 --- a/src/main/java/bjc/rgens/text/markov/Markov.java +++ b/src/main/java/bjc/rgens/text/markov/Markov.java @@ -152,6 +152,11 @@ public class Markov { return map; } + /* + * @TODO @PERF Ben Culkin 7/21/2019 :PerfSelect + * Couldn't we come up some better way to do the random sampling? Maybe use + * like the reservoir sampling stuff, or build the array list ahead of time? + */ /** * Using probability, returns a pseudo-random character to follow the * substring. |
