diff options
Diffstat (limited to 'src/main/java/bjc/rgens/parser/RGrammarBuilder.java')
| -rwxr-xr-x[-rw-r--r--] | src/main/java/bjc/rgens/parser/RGrammarBuilder.java | 226 |
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; } } |
