From 825d281097d821048f91eaac8dacf335365cb958 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Sun, 3 Jun 2018 21:31:50 -0300 Subject: Weighting part 1 This re-adds the capability to weight rules. However, no syntax has yet been add to perform that rule weighting --- .../java/bjc/rgens/parser/RGrammarBuilder.java | 71 ++++++++++++---------- .../java/bjc/rgens/parser/RGrammarFormatter.java | 11 ++-- src/main/java/bjc/rgens/parser/RGrammarParser.java | 2 +- src/main/java/bjc/rgens/parser/Rule.java | 38 +++++++++--- 4 files changed, 77 insertions(+), 45 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java index 3aa220a..047567d 100755 --- a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java +++ b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java @@ -1,6 +1,9 @@ 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; @@ -159,34 +162,34 @@ public class RGrammarBuilder { List> suffixLists = powerList(elements); - FunctionalList newCases = new FunctionalList<>(); + FunctionalList> newCases = new FunctionalList<>(); - IList caseList = rules.get(ruleName).getCases(); - for (RuleCase ruleCase : caseList) { + IList> caseList = rules.get(ruleName).getCases(); + for (IPair ruleCase : caseList) { for(List suffixList : suffixLists) { - FunctionalList newCase = new FunctionalList<>(); + FunctionalList newCase = new FunctionalList<>(); - for(CaseElement elm : ruleCase.getElements()) { - newCase.add(elm); - } + for(CaseElement elm : ruleCase.getRight().getElements()) { + newCase.add(elm); + } - for(CaseElement element : suffixList) { - newCase.add(element); - } + for(CaseElement element : suffixList) { + newCase.add(element); + } - /* - * @NOTE :AffixCasing - * - * Is this correct, or should we be mirroring the - * existing case type? - */ - newCases.add(new NormalRuleCase(newCase)); + /* + * @NOTE :AffixCasing + * + * Is this correct, or should we be mirroring the + * existing case type? + */ + newCases.add(new Pair<>(ruleCase.getLeft(), new NormalRuleCase(newCase))); } } - for (RuleCase newCase : newCases) { - caseList.add(newCase); + for (IPair newCase : newCases) { + rules.get(ruleName).addCase(newCase.getRight(), newCase.getLeft()); } } @@ -221,10 +224,10 @@ public class RGrammarBuilder { List> prefixLists = powerList(elements); - FunctionalList newCases = new FunctionalList<>(); + FunctionalList> newCases = new FunctionalList<>(); - IList caseList = rules.get(ruleName).getCases(); - for (RuleCase ruleCase : caseList) { + IList> caseList = rules.get(ruleName).getCases(); + for (IPair ruleCase : caseList) { for(List prefixList : prefixLists) { FunctionalList newCase = new FunctionalList<>(); @@ -232,7 +235,7 @@ public class RGrammarBuilder { newCase.add(elm); } - for(CaseElement elm : ruleCase.getElements()) { + for(CaseElement elm : ruleCase.getRight().getElements()) { newCase.add(elm); } @@ -242,13 +245,13 @@ public class RGrammarBuilder { * Is this correct, or should we be mirroring the * existing case type? */ - newCases.add(new NormalRuleCase(newCase)); + newCases.add(new Pair<>(ruleCase.getLeft(), new NormalRuleCase(newCase))); } } - for (RuleCase newCase : newCases) { - caseList.add(newCase); + for (IPair newCase : newCases) { + rules.get(ruleName).addCase(newCase.getRight(), newCase.getLeft()); } } @@ -261,17 +264,23 @@ public class RGrammarBuilder { throw new IllegalArgumentException(String.format("The rule '%s' doesn't exist", ruleName)); } - IList caseList = rules.get(ruleName).getCases(); + IList> caseList = rules.get(ruleName).getCases(); - IList newCaseList = new FunctionalList<>(); + IList> newCaseList = new FunctionalList<>(); - for(RuleCase cse : caseList) { - newCaseList.add(new FlatRuleCase(cse.getElements())); + for(IPair cse : caseList) { + newCaseList.add(new Pair<>(cse.getLeft(), new FlatRuleCase(cse.getRight().getElements()))); } rules.get(ruleName).replaceCases(newCaseList); } + /* + * @TODO + * + * Actually get this working + */ + /* public void regexizeRule(String rule, String pattern) { if (rule == null) { throw new NullPointerException("rule must not be null"); @@ -292,7 +301,7 @@ public class RGrammarBuilder { } rules.get(rule).replaceCases(newCaseList); - } + }*/ private static List> powerList(Set elements) { /* diff --git a/src/main/java/bjc/rgens/parser/RGrammarFormatter.java b/src/main/java/bjc/rgens/parser/RGrammarFormatter.java index a2454dc..7e058b0 100755 --- a/src/main/java/bjc/rgens/parser/RGrammarFormatter.java +++ b/src/main/java/bjc/rgens/parser/RGrammarFormatter.java @@ -1,6 +1,8 @@ package bjc.rgens.parser; import bjc.rgens.parser.elements.CaseElement; + +import bjc.utils.data.IPair; import bjc.utils.funcdata.IList; import java.util.HashSet; @@ -52,7 +54,7 @@ public class RGrammarFormatter { /* Format a rule. */ private static void processRule(Rule rule, StringBuilder sb) { - IList cases = rule.getCases(); + IList> cases = rule.getCases(); StringBuilder ruleBuilder = new StringBuilder(); @@ -61,20 +63,21 @@ public class RGrammarFormatter { int markerPos = ruleBuilder.length(); - processCase(cases.first(), ruleBuilder); + processCase(cases.first().getRight(), ruleBuilder); sb.append(ruleBuilder.toString().trim()); ruleBuilder = new StringBuilder(); - for (RuleCase cse : cases.tail()) { + for (IPair cse : cases.tail()) { sb.append("\n\t"); for (int i = 8; i < markerPos; i++) { ruleBuilder.append(" "); } - processCase(cse, ruleBuilder); + /* @TODO do this right, once we pick the syntax */ + processCase(cse.getRight(), ruleBuilder); sb.append(ruleBuilder.toString()); diff --git a/src/main/java/bjc/rgens/parser/RGrammarParser.java b/src/main/java/bjc/rgens/parser/RGrammarParser.java index 4045837..b2499f9 100755 --- a/src/main/java/bjc/rgens/parser/RGrammarParser.java +++ b/src/main/java/bjc/rgens/parser/RGrammarParser.java @@ -91,7 +91,7 @@ public class RGrammarParser { String name = body.substring(0, nameIndex).trim(); String patt = body.substring(nameIndex + 1).trim(); - build.regexizeRule(name, patt); + //build.regexizeRule(name, patt); }); pragmas.put("suffix-with", (body, build, level) -> { diff --git a/src/main/java/bjc/rgens/parser/Rule.java b/src/main/java/bjc/rgens/parser/Rule.java index 7043e0f..0022732 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; @@ -15,7 +17,7 @@ public class Rule { public final String name; /* The cases for this rule. */ - private IList cases; + private WeightedRandom cases; /** * Create a new grammar rule. @@ -35,7 +37,7 @@ public class Rule { name = ruleName; - cases = new FunctionalList<>(); + cases = new WeightedRandom<>(); } /** @@ -49,7 +51,21 @@ public class Rule { throw new NullPointerException("Case must not be null"); } - cases.add(cse); + cases.addProbability(1, cse); + } + + /** + * 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.addProbability(weight, cse); } /** @@ -59,7 +75,7 @@ public class Rule { * A random case from this rule. */ public RuleCase getCase() { - return cases.randItem(); + return cases.generateValue(); } /** @@ -72,7 +88,7 @@ public class Rule { * A random case from this rule. */ public RuleCase getCase(Random rnd) { - return cases.randItem(rnd::nextInt); + return cases.generateValue(rnd); } /** @@ -81,8 +97,8 @@ public class Rule { * @return * All the cases in this rule. */ - public IList getCases() { - return cases; + public IList> getCases() { + return cases.getValues(); } /** @@ -91,8 +107,12 @@ public class Rule { * @param cases * The new list of cases. */ - public void replaceCases(IList cases) { - this.cases = cases; + public void replaceCases(IList> cases) { + this.cases = new WeightedRandom<>(); + + for(IPair cse : cases) { + this.cases.addProbability(cse.getLeft(), cse.getRight()); + } } @Override -- cgit v1.2.3