diff options
Diffstat (limited to 'RGens/src')
5 files changed, 86 insertions, 32 deletions
diff --git a/RGens/src/main/java/bjc/rgens/newparser/CaseElement.java b/RGens/src/main/java/bjc/rgens/newparser/CaseElement.java index 2eb2e3a..7d04156 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/CaseElement.java +++ b/RGens/src/main/java/bjc/rgens/newparser/CaseElement.java @@ -1,5 +1,9 @@ package bjc.rgens.newparser; +import static bjc.rgens.newparser.CaseElement.ElementType.LITERAL; +import static bjc.rgens.newparser.CaseElement.ElementType.RANGE; +import static bjc.rgens.newparser.CaseElement.ElementType.RULEREF; + /** * A element in a rule case. * @@ -27,10 +31,14 @@ public class CaseElement { RANGE; } + private static final String SPECIAL_CASELEM = "\\{[^}]\\}"; + private static final String REFER_CASELEM = "\\[[^\\]]+\\]"; + private static final String RANGE_CASELM = "\\[\\d+\\.\\.\\d+\\]"; + /** * The type of this element. */ - public final CaseElement.ElementType type; + public final ElementType type; /** * The literal string value of this element. @@ -225,4 +233,42 @@ public class CaseElement { return String.format("Unknown type '%s'", type); } } + + /** + * Create a case element from a string. + * + * @param csepart + * The string to convert. + * + * @return A case element representing the string. + */ + public static CaseElement createElement(String csepart) { + if(csepart == null) { + throw new NullPointerException("Case part cannot be null"); + } + + if(csepart.matches(CaseElement.SPECIAL_CASELEM)) { + /* + * Handle other cases. + */ + } else if(csepart.matches(CaseElement.REFER_CASELEM)) { + if(csepart.matches(CaseElement.RANGE_CASELM)) { + /* + * Handle ranges + */ + String rawRange = csepart.substring(1, csepart.length() - 1); + + int firstNum = Integer.parseInt(rawRange.substring(0, rawRange.indexOf('.'))); + int secondNum = Integer.parseInt(rawRange.substring(rawRange.lastIndexOf('.') + 1)); + + return new CaseElement(RANGE, firstNum, secondNum); + } else { + return new CaseElement(RULEREF, csepart); + } + } else { + return new CaseElement(LITERAL, csepart); + } + + throw new IllegalArgumentException(String.format("Unknown case part '%s'")); + } }
\ No newline at end of file diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java index ed02e87..c57cd1e 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java @@ -18,6 +18,7 @@ public class RGrammar { public GenerationState(StringBuilder contents, Random rnd) { this.contents = contents; + this.rnd = rnd; } } diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java index 52304f5..27a9bb3 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java @@ -8,7 +8,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import static bjc.rgens.newparser.CaseElement.ElementType.*; import static bjc.rgens.newparser.RuleCase.CaseType.*; /** @@ -18,12 +17,6 @@ import static bjc.rgens.newparser.RuleCase.CaseType.*; * */ public class RGrammarBuilder { - private static final String RANGE_CASELM = "\\[\\d+\\.\\.\\d+\\]"; - - private static final String REFER_CASELEM = "\\[[^\\]]+\\]"; - - private static final String SPECIAL_CASELEM = "{[^}]}"; - private IList<CaseElement> currentCase; private Rule currRule; @@ -97,27 +90,9 @@ public class RGrammarBuilder { * @param csepart */ public void addCasePart(String csepart) { - if(csepart.matches(SPECIAL_CASELEM)) { - /* - * Handle other cases. - */ - } else if(csepart.matches(REFER_CASELEM)) { - if(csepart.matches(RANGE_CASELM)) { - /* - * Handle ranges - */ - String rawRange = csepart.substring(1, csepart.length() - 1); - - int firstNum = Integer.parseInt(rawRange.substring(0, rawRange.indexOf('.'))); - int secondNum = Integer.parseInt(rawRange.substring(rawRange.lastIndexOf('.') + 1)); - - currentCase.add(new CaseElement(RANGE, firstNum, secondNum)); - } else { - currentCase.add(new CaseElement(RULEREF, csepart)); - } - } else { - currentCase.add(new CaseElement(LITERAL, csepart)); - } + CaseElement element = CaseElement.createElement(csepart); + + currentCase.add(element); } /** @@ -180,7 +155,7 @@ public class RGrammarBuilder { } else if(init.equals("")) { throw new IllegalArgumentException("The empty string is not a valid rule name"); } else if(!rules.containsKey(init)) { - throw new IllegalArgumentException(String.format("No rule named '%s' found", init)); + throw new IllegalArgumentException(String.format("No local rule named '%s' found", init)); } initialRule = init; @@ -202,9 +177,38 @@ public class RGrammarBuilder { } else if(export.equals("")) { throw new NullPointerException("The empty string is not a valid rule name"); } else if(!rules.containsKey(export)) { - throw new IllegalArgumentException(String.format("No rule named '%s' found", export)); + throw new IllegalArgumentException(String.format("No local rule named '%s' found", export)); } exportedRules.add(export); } + + /** + * Suffix a given case element to every case of a specific rule. + * + * @param ruleName + * The rule to suffix. + * + * @param suffix + * The suffix to add. + * + * @throws IllegalArgumentException + * 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) { + 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)) { + throw new IllegalArgumentException(String.format("No local rule named '%s' found", ruleName)); + } + + CaseElement element = CaseElement.createElement(suffix); + + for(RuleCase ruleCase : rules.get(ruleName).getCases()) { + ruleCase.getElements().add(element); + } + } } diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java index 3d7b708..82c52ee 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java @@ -254,6 +254,9 @@ public class RGrammarParser { "A rule must be given at least one case in its declaration, and" + "seperated from that case by \u2192"); } + + System.out.println( + "WARNING: Empty space separating a declaration and its case is deprecated. Use \u2192 instead"); } String ruleName = declContents.substring(0, declSep).trim(); diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammarTest.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammarTest.java index ff23d79..375e35f 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammarTest.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammarTest.java @@ -16,7 +16,7 @@ public class RGrammarTest { * Unused CLI args. */ public static void main(String[] args) { - InputStream stream = RGrammarTest.class.getResourceAsStream("/sample-grammars/web.gram"); + InputStream stream = RGrammarTest.class.getResourceAsStream("/sample-grammars/college.gram"); RGrammarSet grammarSet = new RGrammarSet(); |
