summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/bjc/rgens/parser/RGrammarBuilder.java')
-rwxr-xr-x[-rw-r--r--]src/main/java/bjc/rgens/parser/RGrammarBuilder.java226
1 files changed, 190 insertions, 36 deletions
diff --git a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
index b4cb04a..8f0a2d1 100644..100755
--- a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
+++ b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
@@ -1,13 +1,19 @@
package bjc.rgens.parser;
import bjc.rgens.parser.elements.CaseElement;
+
+import bjc.utils.data.IPair;
+import bjc.utils.data.Pair;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.IList;
+import bjc.utils.funcutils.ListUtils;
+import bjc.utils.funcutils.SetUtils;
-import static bjc.rgens.parser.RuleCase.CaseType.*;
-
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
+import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
@@ -46,9 +52,9 @@ public class RGrammarBuilder {
else if(rName.equals(""))
throw new IllegalArgumentException("The empty string is not a valid rule name");
- if(rules.containsKey(rName))
+ if(rules.containsKey(rName)) {
return rules.get(rName);
- else {
+ } else {
Rule ret = new Rule(rName);
rules.put(rName, ret);
@@ -66,8 +72,20 @@ public class RGrammarBuilder {
public RGrammar toRGrammar() {
RGrammar grammar = new RGrammar(rules);
+ if(initialRule != null) {
+ if(!rules.containsKey(initialRule)) {
+ throw new GrammarException(String.format("Rule '%s' doesn't exist\n", initialRule));
+ }
+ }
+
grammar.setInitialRule(initialRule);
+ for(String export : exportedRules) {
+ if(!rules.containsKey(export)) {
+ throw new GrammarException(String.format("Rule '%s' doesn't exist\n", export));
+ }
+ }
+
grammar.setExportedRules(exportedRules);
return grammar;
@@ -124,37 +142,48 @@ public class RGrammarBuilder {
* If the rule name is either invalid or not defined by this
* grammar, or if the suffix is invalid.
*/
- public void suffixWith(String ruleName, String suffix) {
+ public void suffixWith(String ruleName, IList<CaseElement> suffixes) {
if (ruleName == null) {
throw new NullPointerException("Rule name must not be null");
} else if (ruleName.equals("")) {
throw new IllegalArgumentException("The empty string is not a valid rule name");
} else if(!rules.containsKey(ruleName)) {
- String msg = String.format("Rule '%s' is not a valid rule name.");
+ String msg = String.format("Rule '%s' is not a valid rule name");
throw new IllegalArgumentException(msg);
}
- CaseElement element = CaseElement.createElement(suffix);
+ Set<CaseElement> elements = new HashSet<>(suffixes.getSize());
+ for(CaseElement suffix : suffixes) {
+ elements.add(suffix);
+ }
+
+ List<List<CaseElement>> suffixLists = powerList(elements);
+
+ FunctionalList<IPair<Integer, RuleCase>> newCases = new FunctionalList<>();
- FunctionalList<RuleCase> newCases = new FunctionalList<>();
+ IList<IPair<Integer, RuleCase>> caseList = rules.get(ruleName).getCases();
+ for (IPair<Integer, RuleCase> ruleCase : caseList) {
+ RuleCase cas = ruleCase.getRight();
- IList<RuleCase> caseList = rules.get(ruleName).getCases();
- for (RuleCase ruleCase : caseList) {
- FunctionalList<CaseElement> newCase = new FunctionalList<>();
+ for(List<CaseElement> suffixList : suffixLists) {
+ FunctionalList<CaseElement> newCase = new FunctionalList<>();
- for(CaseElement elm : ruleCase.getElements()) {
- newCase.add(elm);
- }
+ for(CaseElement elm : cas.elementList) {
+ newCase.add(elm);
+ }
- newCase.add(element);
+ for(CaseElement element : suffixList) {
+ newCase.add(element);
+ }
- newCases.add(new RuleCase(NORMAL, newCase));
+ newCases.add(new Pair<>(ruleCase.getLeft(), cas.withElements(newCase)));
+ }
}
- for (RuleCase newCase : newCases) {
- caseList.add(newCase);
+ for (IPair<Integer, RuleCase> newCase : newCases) {
+ rules.get(ruleName).addCase(newCase.getRight(), newCase.getLeft());
}
}
@@ -171,37 +200,48 @@ public class RGrammarBuilder {
* If the rule name is either invalid or not defined by this
* grammar, or if the prefix is invalid.
*/
- public void prefixWith(String ruleName, String prefix) {
+ public void prefixWith(String ruleName, IList<CaseElement> prefixes) {
if (ruleName == null) {
throw new NullPointerException("Rule name must not be null");
} else if (ruleName.equals("")) {
throw new IllegalArgumentException("The empty string is not a valid rule name");
} else if(!rules.containsKey(ruleName)) {
- String msg = String.format("Rule '%s' is not a valid rule name.");
+ String msg = String.format("Rule '%s' is not a valid rule name");
throw new IllegalArgumentException(msg);
}
- CaseElement element = CaseElement.createElement(prefix);
+ Set<CaseElement> elements = new HashSet<>(prefixes.getSize());
+ for(CaseElement prefix : prefixes) {
+ elements.add(prefix);
+ }
+
+ List<List<CaseElement>> prefixLists = powerList(elements);
- FunctionalList<RuleCase> newCases = new FunctionalList<>();
+ FunctionalList<IPair<Integer, RuleCase>> newCases = new FunctionalList<>();
- IList<RuleCase> caseList = rules.get(ruleName).getCases();
- for (RuleCase ruleCase : caseList) {
- FunctionalList<CaseElement> newCase = new FunctionalList<>();
+ IList<IPair<Integer, RuleCase>> caseList = rules.get(ruleName).getCases();
+ for (IPair<Integer, RuleCase> ruleCase : caseList) {
+ RuleCase cas = ruleCase.getRight();
- newCase.add(element);
+ for(List<CaseElement> prefixList : prefixLists) {
+ FunctionalList<CaseElement> newCase = new FunctionalList<>();
- for(CaseElement elm : ruleCase.getElements()) {
- newCase.add(elm);
- }
+ for(CaseElement elm: prefixList) {
+ newCase.add(elm);
+ }
- newCases.add(new RuleCase(NORMAL, newCase));
+ for(CaseElement elm :cas.elementList) {
+ newCase.add(elm);
+ }
+
+ newCases.add(new Pair<>(ruleCase.getLeft(), cas.withElements(newCase)));
+ }
}
- for (RuleCase newCase : newCases) {
- caseList.add(newCase);
+ for (IPair<Integer, RuleCase> newCase : newCases) {
+ rules.get(ruleName).addCase(newCase.getRight(), newCase.getLeft());
}
}
@@ -210,19 +250,85 @@ public class RGrammarBuilder {
throw new NullPointerException("ruleName must not be null");
} else if (ruleName.equals("")) {
throw new IllegalArgumentException("The empty string is not a valid rule name");
+ } else if (!rules.containsKey(ruleName)) {
+ throw new IllegalArgumentException(String.format("The rule '%s' doesn't exist", ruleName));
}
- IList<RuleCase> caseList = rules.get(ruleName).getCases();
+ IList<IPair<Integer, RuleCase>> caseList = rules.get(ruleName).getCases();
- IList<RuleCase> newCaseList = new FunctionalList<>();
+ IList<IPair<Integer, RuleCase>> newCaseList = new FunctionalList<>();
- for(RuleCase cse : caseList) {
- newCaseList.add(new RuleCase(SPACEFLATTEN, cse.getElements()));
+ for(IPair<Integer, RuleCase> cse : caseList) {
+ newCaseList.add(new Pair<>(cse.getLeft(), new FlatRuleCase(cse.getRight().elementList)));
}
+ System.err.printf("\t\tTRACE: Despacing %d cases of rule %s\n", caseList.getSize(), ruleName);
+
rules.get(ruleName).replaceCases(newCaseList);
}
+ public void setWeight(String ruleName) {
+ if (ruleName == null) {
+ throw new NullPointerException("ruleName must not be null");
+ } else if (ruleName.equals("")) {
+ throw new IllegalArgumentException("The empty string is not a valid rule name");
+ } else if (!rules.containsKey(ruleName)) {
+ throw new IllegalArgumentException(String.format("The rule '%s' doesn't exist", ruleName));
+ }
+
+ rules.get(ruleName).prob = Rule.ProbType.NORMAL;
+ }
+
+ public void setRuleRecur(String ruleName, int recurLimit) {
+ if (ruleName == null) {
+ throw new NullPointerException("ruleName must not be null");
+ } else if (ruleName.equals("")) {
+ throw new IllegalArgumentException("The empty string is not a valid rule name");
+ } else if (!rules.containsKey(ruleName)) {
+ throw new IllegalArgumentException(String.format("The rule '%s' doesn't exist", ruleName));
+ }
+
+ rules.get(ruleName).recurLimit = recurLimit;
+ }
+
+ public void setDescent(String ruleName, int descentFactor) {
+ if (ruleName == null) {
+ throw new NullPointerException("ruleName must not be null");
+ } else if (ruleName.equals("")) {
+ throw new IllegalArgumentException("The empty string is not a valid rule name");
+ } else if (!rules.containsKey(ruleName)) {
+ throw new IllegalArgumentException(String.format("The rule '%s' doesn't exist", ruleName));
+ }
+
+ Rule rl = rules.get(ruleName);
+
+ rl.prob = Rule.ProbType.DESCENDING;
+ rl.descentFactor = descentFactor;
+ }
+
+ public void setBinomial(String ruleName, int target, int bound, int trials) {
+ if (ruleName == null) {
+ throw new NullPointerException("ruleName must not be null");
+ } else if (ruleName.equals("")) {
+ throw new IllegalArgumentException("The empty string is not a valid rule name");
+ } else if (!rules.containsKey(ruleName)) {
+ throw new IllegalArgumentException(String.format("The rule '%s' doesn't exist", ruleName));
+ }
+
+ Rule rl = rules.get(ruleName);
+
+ rl.prob = Rule.ProbType.BINOMIAL;
+
+ rl.target = target;
+ rl.bound = bound;
+ rl.trials = trials;
+ }
+ /*
+ * @TODO
+ *
+ * Actually get this working
+ */
+ /*
public void regexizeRule(String rule, String pattern) {
if (rule == null) {
throw new NullPointerException("rule must not be null");
@@ -230,6 +336,8 @@ public class RGrammarBuilder {
throw new NullPointerException("pattern must not be null");
} else if (rule.equals("")) {
throw new IllegalArgumentException("The empty string is not a valid rule name");
+ } else if(!rules.containsKey(rule)) {
+ throw new IllegalArgumentException(String.format("The rule '%s' doesn't exist", rule));
}
IList<RuleCase> caseList = rules.get(rule).getCases();
@@ -241,6 +349,52 @@ public class RGrammarBuilder {
}
rules.get(rule).replaceCases(newCaseList);
+ }*/
+
+ private static <T> List<List<T>> powerList(Set<T> elements) {
+ /*
+ * Fast-case the most common usage
+ */
+ if(elements.size() == 1) {
+ List<List<T>> ret = new LinkedList<>();
+
+ List<T> curr = new ArrayList<>(elements.size());
+ for(T elem : elements) {
+ curr.add(elem);
+ }
+
+ ret.add(curr);
+
+ return ret;
+ }
+
+ Set<Set<T>> powerSet = SetUtils.powerSet(elements);
+
+ List<List<T>> list = new LinkedList<>();
+
+ for(Set<T> set : powerSet) {
+ /*
+ * Skip empty sets
+ */
+ if(set.size() == 0) continue;
+
+ List<T> stor = new ArrayList<>(set.size());
+
+ for(T elm : set) {
+ stor.add(elm);
+ }
+
+ for(List<T> permute : ListUtils.permuteList(stor)) {
+ System.err.printf("\t\tTRACE: generated permute ");
+ for(T elm : permute) {
+ System.err.printf("%s ", elm);
+ }
+ System.err.println();
+
+ list.add(permute);
+ }
+ }
+ return list;
}
}