diff options
| author | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2018-06-04 16:47:54 -0300 |
|---|---|---|
| committer | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2018-06-04 16:47:54 -0300 |
| commit | 3b760ca916c6a88265e348d77ee1f6497dace0a4 (patch) | |
| tree | 5d05409b79a9b585276722a54e7a70b7468374f5 /src/main/java/bjc/rgens | |
| parent | 2ca83db4239ea46572910baf0358e3f8608a3610 (diff) | |
Add line offset
Blocks should now properly give absolute numbers as to where they are
from
Diffstat (limited to 'src/main/java/bjc/rgens')
| -rwxr-xr-x | src/main/java/bjc/rgens/parser/RGrammarBuilder.java | 47 | ||||
| -rwxr-xr-x | src/main/java/bjc/rgens/parser/RGrammarParser.java | 80 |
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); /** |
