summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorBenjamin J. Culkin <bjculkin@mix.wvu.edu>2019-08-28 19:50:36 -0300
committerBenjamin J. Culkin <bjculkin@mix.wvu.edu>2019-08-28 19:50:36 -0300
commit1914335b9505b0086a0aeed0997c566e0e5ceca3 (patch)
tree9ab2b53aa18f945c1693d503b555fef8a1032fc5 /src/main
parentb7193cf955e7b2d2474d728c4087bc36597f0c7f (diff)
Add additional comments & such
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/bjc/rgens/parser/ConfigLoader.java113
-rw-r--r--src/main/java/bjc/rgens/parser/ConfigSet.java42
-rw-r--r--src/main/java/bjc/rgens/parser/FlatRuleCase.java19
-rw-r--r--src/main/java/bjc/rgens/parser/GenerationState.java150
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/GrammarException.java5
-rw-r--r--src/main/java/bjc/rgens/parser/NormalRuleCase.java19
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammar.java67
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammarParser.java2
-rwxr-xr-xsrc/main/java/bjc/rgens/text/markov/Markov.java5
9 files changed, 380 insertions, 42 deletions
diff --git a/src/main/java/bjc/rgens/parser/ConfigLoader.java b/src/main/java/bjc/rgens/parser/ConfigLoader.java
index c282f8a..95adef4 100644
--- a/src/main/java/bjc/rgens/parser/ConfigLoader.java
+++ b/src/main/java/bjc/rgens/parser/ConfigLoader.java
@@ -23,6 +23,17 @@ import bjc.rgens.parser.templates.GrammarTemplate;
import static bjc.rgens.parser.RGrammarLogging.*;
+/*
+ * @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.
*
@@ -42,7 +53,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);
@@ -76,25 +87,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];
@@ -104,7 +147,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);
}
@@ -119,7 +162,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);
}
@@ -127,9 +170,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;
@@ -138,7 +188,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);
@@ -159,7 +215,6 @@ public class ConfigLoader {
/*
* @TODO Ben Culkin 9/8/17 :SubsetGrammar
* Implement subset grammars.
- *
*/
errs.addChild(fmt);
}
@@ -177,6 +232,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);
@@ -200,28 +257,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);
@@ -237,6 +302,7 @@ public class ConfigLoader {
} catch (IOException ioex) {
kid.addChild("ERROR: " + ioex.getMessage());
} finally {
+ // Reset the parent to its actual value.
lopts.parent = oldPar;
}
@@ -247,6 +313,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;
@@ -257,7 +324,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);
@@ -284,7 +351,7 @@ public class ConfigLoader {
errs.addChild(fmt);
}
- /* Add grammar to the set. */
+ /* Add template to the set. */
lopts.cfgSet.templates.put(template.name, template);
/*
@@ -292,11 +359,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);
@@ -338,7 +408,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();
@@ -346,14 +417,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;
}
@@ -377,9 +448,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);
@@ -398,7 +470,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 {
@@ -412,7 +484,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 ac6f554..5055810 100644
--- a/src/main/java/bjc/rgens/parser/FlatRuleCase.java
+++ b/src/main/java/bjc/rgens/parser/FlatRuleCase.java
@@ -4,7 +4,18 @@ import bjc.rgens.parser.elements.CaseElement;
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);
}
@@ -16,6 +27,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 35d831d..bda7472 100644
--- a/src/main/java/bjc/rgens/parser/GenerationState.java
+++ b/src/main/java/bjc/rgens/parser/GenerationState.java
@@ -13,40 +13,50 @@ import java.util.Map;
import java.util.Random;
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 cont
- * The string being generated.
+ * @param rw
+ * 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.
+ *
+ * @param gram
+ * The grammar we are generating from.
*/
public GenerationState(ReportWriter rw, Random rand, Map<String, String> vs,
Map<String, Rule> rvs, RGrammar gram) {
@@ -65,16 +75,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;
@@ -88,6 +126,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
//
@@ -108,6 +152,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);
@@ -118,6 +174,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);
@@ -126,6 +191,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)",
@@ -137,6 +211,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)",
@@ -148,6 +231,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)) {
@@ -159,6 +253,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)) {
@@ -170,6 +275,9 @@ public class GenerationState {
return rlVars.get(name);
}
+ /**
+ * Append the given string to our output.
+ */
public void appendContents(String strang) {
try {
contents.write(strang);
@@ -178,6 +286,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
//
@@ -196,18 +310,38 @@ public class GenerationState {
}
}
+ /**
+ * Get the report writer that we use for our input.
+ *
+ * @return The report writer that we write stuff &amp; 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 8fca86d..705a118 100644
--- a/src/main/java/bjc/rgens/parser/NormalRuleCase.java
+++ b/src/main/java/bjc/rgens/parser/NormalRuleCase.java
@@ -4,7 +4,18 @@ import java.util.List;
import bjc.rgens.parser.elements.CaseElement;
+/**
+ * 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);
}
@@ -20,6 +31,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 018f2f0..7e46d5d 100755
--- a/src/main/java/bjc/rgens/parser/RGrammar.java
+++ b/src/main/java/bjc/rgens/parser/RGrammar.java
@@ -37,12 +37,22 @@ import static bjc.utils.data.IPair.pair;
* @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;
@@ -66,8 +76,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. */
@@ -76,7 +89,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 dc4d82d..3675f39 100755
--- a/src/main/java/bjc/rgens/parser/RGrammarParser.java
+++ b/src/main/java/bjc/rgens/parser/RGrammarParser.java
@@ -141,7 +141,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 e21d60f..45f5b39 100755
--- a/src/main/java/bjc/rgens/text/markov/Markov.java
+++ b/src/main/java/bjc/rgens/text/markov/Markov.java
@@ -148,6 +148,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.