summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorBenjamin J. Culkin <bjculkin@mix.wvu.edu>2018-06-04 16:47:54 -0300
committerBenjamin J. Culkin <bjculkin@mix.wvu.edu>2018-06-04 16:47:54 -0300
commit3b760ca916c6a88265e348d77ee1f6497dace0a4 (patch)
tree5d05409b79a9b585276722a54e7a70b7468374f5 /src/main
parent2ca83db4239ea46572910baf0358e3f8608a3610 (diff)
Add line offset
Blocks should now properly give absolute numbers as to where they are from
Diffstat (limited to 'src/main')
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammarBuilder.java47
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammarParser.java80
2 files changed, 111 insertions, 16 deletions
diff --git a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
index 20cba93..59f3a4c 100755
--- a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
+++ b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
@@ -272,9 +272,23 @@ public class RGrammarBuilder {
newCaseList.add(new Pair<>(cse.getLeft(), new FlatRuleCase(cse.getRight().getElements())));
}
+ System.err.printf("\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");
@@ -286,6 +300,39 @@ public class RGrammarBuilder {
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
*
diff --git a/src/main/java/bjc/rgens/parser/RGrammarParser.java b/src/main/java/bjc/rgens/parser/RGrammarParser.java
index 7085f06..ecca7ca 100755
--- a/src/main/java/bjc/rgens/parser/RGrammarParser.java
+++ b/src/main/java/bjc/rgens/parser/RGrammarParser.java
@@ -99,6 +99,49 @@ public class RGrammarParser {
build.setRuleRecur(parts[0], Integer.parseInt(parts[1]));
});
+ pragmas.put("enable-weight", (body, build, level) -> {
+ String[] parts = body.split(" ");
+
+ if(parts.length != 2) {
+ throw new GrammarException("Enable-weight pragma takes one arguments: the name of the rule to set the weight factor for");
+ }
+
+ build.setWeight(parts[0]);
+ });
+ pragmas.put("enable-descent", (body, build, level) -> {
+ String[] parts = body.split(" ");
+
+ if(parts.length != 2) {
+ throw new GrammarException("Enable-descent pragma takes two arguments: the name of the rule to set the descent factor for, and the new value of the factor");
+ }
+
+ if(!parts[1].matches("\\A\\d+\\Z")) {
+ throw new GrammarException("Factor value must be an integer");
+ }
+
+ build.setDescent(parts[0], Integer.parseInt(parts[1]));
+ });
+
+ pragmas.put("enable-binomial", (body, build, level) -> {
+ String[] parts = body.split(" ");
+
+ if(parts.length != 4) {
+ throw new GrammarException("Enable-descent pragma takes four arguments: the name of the rule to set the binomial factors for, and the three binomial parameters (target, bound trials)");
+ }
+
+ if(!parts[1].matches("\\A\\d+\\Z")) {
+ throw new GrammarException("Target value must be an integer");
+ }
+ if(!parts[2].matches("\\A\\d+\\Z")) {
+ throw new GrammarException("Bound value must be an integer");
+ }
+ if(!parts[3].matches("\\A\\d+\\Z")) {
+ throw new GrammarException("Trials value must be an integer");
+ }
+
+ build.setBinomial(parts[0], Integer.parseInt(parts[1]), Integer.parseInt(parts[2]), Integer.parseInt(parts[3]));
+ });
+
pragmas.put("regex-rule", (body, build, level) -> {
int nameIndex = body.indexOf(" ");
@@ -164,7 +207,7 @@ public class RGrammarParser {
if(DEBUG)
System.err.printf("Handling top-level block (%s)\n", block);
- handleBlock(build, block.contents, 0);
+ handleBlock(build, block.contents, 0, block.startLine);
});
if(LINES)
@@ -184,7 +227,7 @@ public class RGrammarParser {
/* Handles an arbitrary block. */
private static void handleBlock(RGrammarBuilder build, String block,
- int level) throws GrammarException {
+ int level, int lineOffset) throws GrammarException {
/* Discard empty blocks. */
if (block.equals("") || block.matches("\\R"))
return;
@@ -199,11 +242,11 @@ public class RGrammarParser {
String blockType = block.substring(0, typeSep).trim();
if (blockType.equalsIgnoreCase("pragma")) {
- handlePragmaBlock(block, build, level);
+ handlePragmaBlock(block, build, level, lineOffset);
} else if (blockType.startsWith("[")) {
- handleRuleBlock(block, build, level);
+ handleRuleBlock(block, build, level, lineOffset);
} else if (blockType.equalsIgnoreCase("where")) {
- handleWhereBlock(block, build, level);
+ handleWhereBlock(block, build, level, lineOffset);
} else if (blockType.startsWith("#")) {
if(DEBUG)
System.err.printf("Handled comment block (%s)\n", block);
@@ -224,11 +267,13 @@ public class RGrammarParser {
/* Handle reading a block of pragmas. */
private static void handlePragmaBlock(String block, RGrammarBuilder build,
- int level) throws GrammarException {
+ int level, int lineOffset) throws GrammarException {
String dlm = String.format(TMPL_PRAGMA_BLOCK_DELIM, level);
try (BlockReader pragmaReader = new SimpleBlockReader(dlm, new StringReader(block))) {
try {
pragmaReader.forEachBlock((pragma) -> {
+ pragma.lineOffset = lineOffset;
+
if(DEBUG)
System.err.printf("Handled pragma block (%s)\n", pragma);
@@ -251,7 +296,7 @@ public class RGrammarParser {
throw new GrammarException(msg);
}
- handlePragma(pragmaBody, build, level);
+ handlePragma(pragmaBody, build, level, pragma.startLine + lineOffset);
});
} catch (GrammarException gex) {
Block pragma = pragmaReader.getBlock();
@@ -266,7 +311,7 @@ public class RGrammarParser {
/* Handle an individual pragma in a block. */
private static void handlePragma(String pragma, RGrammarBuilder build,
- int level) throws GrammarException {
+ int level, int lineOffset) throws GrammarException {
int bodySep = pragma.indexOf(' ');
if (bodySep == -1)
@@ -295,7 +340,7 @@ public class RGrammarParser {
/* Handle a block of a rule declaration and one or more cases. */
private static void handleRuleBlock(String ruleBlock, RGrammarBuilder build,
- int level) throws GrammarException {
+ int level, int lineOffset) throws GrammarException {
String dlm = String.format(TMPL_RULEDECL_BLOCK_DELIM, level);
try (BlockReader ruleReader = new SimpleBlockReader(dlm, new StringReader(ruleBlock))) {
try {
@@ -303,19 +348,20 @@ public class RGrammarParser {
/* Rule with a declaration followed by multiple cases. */
ruleReader.nextBlock();
Block declBlock = ruleReader.getBlock();
+ declBlock.lineOffset = lineOffset;
String declContents = declBlock.contents;
- Rule rl = handleRuleDecl(build, declContents);
+ Rule rl = handleRuleDecl(build, declContents, lineOffset + declBlock.startLine);
ruleReader.forEachBlock((block) -> {
/* Ignore comment lines. */
if(block.contents.trim().startsWith("#")) return;
- handleRuleCase(block.contents, build, rl);
+ handleRuleCase(block.contents, build, rl, block.startLine + lineOffset);
});
} else {
/* Rule with a declaration followed by a single case. */
- handleRuleDecl(build, ruleBlock);
+ handleRuleDecl(build, ruleBlock, lineOffset);
}
} catch (GrammarException gex) {
String msg = String.format("Error in rule case (%s)", ruleReader.getBlock());
@@ -328,7 +374,7 @@ public class RGrammarParser {
}
/* Handle a rule declaration and its initial case. */
- private static Rule handleRuleDecl(RGrammarBuilder build, String declContents) {
+ private static Rule handleRuleDecl(RGrammarBuilder build, String declContents, int lineOffset) {
int declSep = declContents.indexOf("\u2192");
if (declSep == -1) {
@@ -357,13 +403,13 @@ public class RGrammarParser {
Rule rul = build.getOrCreateRule(ruleName);
- handleRuleCase(ruleBody, build, rul);
+ handleRuleCase(ruleBody, build, rul, lineOffset);
return rul;
}
/* Handle a single case of a rule. */
- private static void handleRuleCase(String cse, RGrammarBuilder build, Rule rul) {
+ private static void handleRuleCase(String cse, RGrammarBuilder build, Rule rul, int lineOffset) {
Pair<IList<CaseElement>, Integer> caseParts = parseElementString(cse);
rul.addCase(new NormalRuleCase(caseParts.getLeft()), caseParts.getRight());
@@ -371,7 +417,7 @@ public class RGrammarParser {
/* Handle a where block (a block with local rules). */
private static void handleWhereBlock(String block, RGrammarBuilder build,
- int level) throws GrammarException {
+ int level, int lineOffset) throws GrammarException {
int nlIndex = block.indexOf("\\nin");
if (nlIndex == -1) {
@@ -386,6 +432,7 @@ public class RGrammarParser {
new StringReader(trimBlock))) {
try {
Block whereCtx = whereReader.next();
+ whereCtx.lineOffset = lineOffset;
StringReader ctxReader = new StringReader(whereCtx.contents.trim());
String ctxDelim = String.format(TMPL_TOPLEVEL_BLOCK_DELIM, level + 1);
@@ -393,6 +440,7 @@ public class RGrammarParser {
try (BlockReader bodyReader = new SimpleBlockReader(ctxDelim, ctxReader)) {
@SuppressWarnings("unused")
Block whereBody = whereReader.next();
+ whereBody.lineOffset = lineOffset + whereCtx.startLine;
System.err.printf("\tUNIMPLEMENTED WHERE:\n%s\n", whereBody.contents);
/**