summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/rgens/parser/Rule.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/bjc/rgens/parser/Rule.java')
-rwxr-xr-x[-rw-r--r--]src/main/java/bjc/rgens/parser/Rule.java132
1 files changed, 121 insertions, 11 deletions
diff --git a/src/main/java/bjc/rgens/parser/Rule.java b/src/main/java/bjc/rgens/parser/Rule.java
index 7043e0f..ac67158 100644..100755
--- a/src/main/java/bjc/rgens/parser/Rule.java
+++ b/src/main/java/bjc/rgens/parser/Rule.java
@@ -1,7 +1,9 @@
package bjc.rgens.parser;
+import bjc.utils.data.IPair;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.IList;
+import bjc.utils.gen.WeightedRandom;
import java.util.Random;
@@ -11,12 +13,34 @@ import java.util.Random;
* @author EVE
*/
public class Rule {
+ public RGrammar belongsTo;
+
/** The name of this grammar rule. */
- public final String name;
+ public String name;
/* The cases for this rule. */
- private IList<RuleCase> cases;
+ private WeightedRandom<RuleCase> cases;
+
+ public static enum ProbType {
+ NORMAL,
+ DESCENDING,
+ BINOMIAL
+ }
+
+ public ProbType prob;
+
+ public int descentFactor;
+
+ public int target;
+ public int bound;
+ public int trials;
+
+ public int recurLimit = 5;
+ private int currentRecur;
+ private final static Random BASE = new Random();
+
+ private int serial = 1;
/**
* Create a new grammar rule.
*
@@ -35,7 +59,9 @@ public class Rule {
name = ruleName;
- cases = new FunctionalList<>();
+ cases = new WeightedRandom<>();
+
+ prob = ProbType.NORMAL;
}
/**
@@ -45,11 +71,25 @@ public class Rule {
* The case to add.
*/
public void addCase(RuleCase cse) {
+ addCase(cse, 1);
+ }
+
+ /**
+ * Adds a case to the rule.
+ *
+ * @param cse
+ * The case to add.
+ */
+ public void addCase(RuleCase cse, int weight) {
if (cse == null) {
throw new NullPointerException("Case must not be null");
}
- cases.add(cse);
+ cse.belongsTo = this;
+ cse.debugName = String.format("%s-%d", name, serial);
+ serial += 1;
+
+ cases.addProbability(weight, cse);
}
/**
@@ -59,7 +99,7 @@ public class Rule {
* A random case from this rule.
*/
public RuleCase getCase() {
- return cases.randItem();
+ return getCase(BASE);
}
/**
@@ -72,7 +112,16 @@ public class Rule {
* A random case from this rule.
*/
public RuleCase getCase(Random rnd) {
- return cases.randItem(rnd::nextInt);
+ switch(prob) {
+ case DESCENDING:
+ return cases.getDescent(descentFactor, rnd);
+ case BINOMIAL:
+ return cases.getBinomial(target, bound, trials, rnd);
+ case NORMAL:
+ return cases.generateValue(rnd);
+ default:
+ return cases.generateValue(rnd);
+ }
}
/**
@@ -81,8 +130,8 @@ public class Rule {
* @return
* All the cases in this rule.
*/
- public IList<RuleCase> getCases() {
- return cases;
+ public IList<IPair<Integer, RuleCase>> getCases() {
+ return cases.getValues();
}
/**
@@ -91,8 +140,17 @@ public class Rule {
* @param cases
* The new list of cases.
*/
- public void replaceCases(IList<RuleCase> cases) {
- this.cases = cases;
+ public void replaceCases(IList<IPair<Integer, RuleCase>> cases) {
+ this.cases = new WeightedRandom<>();
+
+ for(IPair<Integer, RuleCase> cse : cases) {
+ RuleCase cs = cse.getRight();
+ cs.belongsTo = this;
+ cs.debugName = String.format("%s-%d", name, serial);
+ serial += 1;
+
+ this.cases.addProbability(cse.getLeft(), cs);
+ }
}
@Override
@@ -129,6 +187,58 @@ public class Rule {
@Override
public String toString() {
- return String.format("Rule [ruleName='%s', ruleCases=%s]", name, cases);
+ return String.format("Rule '%s' with %d cases", name, cases.getValues().getSize());
+ }
+
+ public boolean doRecur() {
+ if(currentRecur > recurLimit) return false;
+
+ currentRecur += 1;
+
+ return true;
+ }
+
+ public void endRecur() {
+ if(currentRecur > 0) currentRecur -= 1;
+ }
+
+ public Rule exhaust() {
+ Rule rl = new Rule(name);
+
+ rl.belongsTo = belongsTo;
+
+ rl.cases = cases.exhaustible();
+
+ rl.prob = prob;
+
+ rl.descentFactor = descentFactor;
+
+ rl.target = target;
+ rl.bound = bound;
+ rl.trials = trials;
+
+ rl.recurLimit = recurLimit;
+ /* @NOTE Is this the right thing to do? */
+ rl.currentRecur = 0;
+
+ return rl;
+ }
+
+ public void generate(GenerationState state) {
+ state.swapGrammar(belongsTo);
+
+ if(doRecur()) {
+ RuleCase cse = getCase(state.rnd);
+
+ System.err.printf("\tFINE: Generating %s (from %s)\n", cse, belongsTo.name);
+
+ belongsTo.generateCase(cse, state);
+
+ endRecur();
+ }
+
+ if(name.contains("+")) {
+ state.contents = new StringBuilder(state.contents.toString().replaceAll("\\s+", ""));
+ }
}
}