From 0faa5175b6f0de8835ed514615ac64135f406b29 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Tue, 29 May 2018 15:35:02 -0300 Subject: Move files out of folder --- .../java/bjc/rgens/parser/GrammarException.java | 36 -- RGens/src/main/java/bjc/rgens/parser/RGrammar.java | 491 --------------------- .../java/bjc/rgens/parser/RGrammarBuilder.java | 246 ----------- .../java/bjc/rgens/parser/RGrammarFormatter.java | 97 ---- .../main/java/bjc/rgens/parser/RGrammarParser.java | 394 ----------------- .../main/java/bjc/rgens/parser/RGrammarSet.java | 290 ------------ .../main/java/bjc/rgens/parser/RGrammarTest.java | 72 --- .../src/main/java/bjc/rgens/parser/RGrammars.java | 67 --- .../main/java/bjc/rgens/parser/RegexRuleCase.java | 32 -- RGens/src/main/java/bjc/rgens/parser/Rule.java | 134 ------ RGens/src/main/java/bjc/rgens/parser/RuleCase.java | 88 ---- .../rgens/parser/elements/BlankCaseElement.java | 7 - .../bjc/rgens/parser/elements/CaseElement.java | 147 ------ .../parser/elements/ExpVariableCaseElement.java | 7 - .../parser/elements/LitVariableCaseElement.java | 7 - .../rgens/parser/elements/LiteralCaseElement.java | 7 - .../rgens/parser/elements/RangeCaseElement.java | 43 -- .../bjc/rgens/parser/elements/RuleCaseElement.java | 7 - .../rgens/parser/elements/StringCaseElement.java | 41 -- .../rgens/parser/elements/VariableCaseElement.java | 60 --- .../src/main/java/bjc/rgens/parser/new-syntax.txt | 13 - 21 files changed, 2286 deletions(-) delete mode 100644 RGens/src/main/java/bjc/rgens/parser/GrammarException.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/RGrammar.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/RGrammarBuilder.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/RGrammarFormatter.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/RGrammarParser.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/RGrammarSet.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/RGrammarTest.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/RGrammars.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/RegexRuleCase.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/Rule.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/RuleCase.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/elements/CaseElement.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java delete mode 100644 RGens/src/main/java/bjc/rgens/parser/new-syntax.txt (limited to 'RGens/src/main/java/bjc/rgens/parser') diff --git a/RGens/src/main/java/bjc/rgens/parser/GrammarException.java b/RGens/src/main/java/bjc/rgens/parser/GrammarException.java deleted file mode 100644 index 9eaa0a1..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/GrammarException.java +++ /dev/null @@ -1,36 +0,0 @@ -package bjc.rgens.parser; - -/** - * The exception thrown when something goes wrong while parsing a - * grammar. - * - * @author student - */ -public class GrammarException extends RuntimeException { - /* Serialization ID. */ - private static final long serialVersionUID = -7287427479316953668L; - - /** - * Create a new grammar exception with the specified message. - * - * @param msg - * The message for this exception. - */ - public GrammarException(String msg) { - super(msg); - } - - /** - * Create a new grammar exception with the specified message and - * cause. - * - * @param msg - * The message for this exception. - * - * @param cause - * The cause of this exception. - */ - public GrammarException(String msg, Exception cause) { - super(msg, cause); - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/RGrammar.java b/RGens/src/main/java/bjc/rgens/parser/RGrammar.java deleted file mode 100644 index 38f38c8..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/RGrammar.java +++ /dev/null @@ -1,491 +0,0 @@ -package bjc.rgens.parser; - -import bjc.rgens.parser.elements.CaseElement; -import bjc.rgens.parser.elements.LiteralCaseElement; -import bjc.rgens.parser.elements.RangeCaseElement; -import bjc.rgens.parser.elements.RuleCaseElement; -import bjc.rgens.parser.elements.VariableCaseElement; -import bjc.utils.funcutils.StringUtils; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.text.similarity.LevenshteinDistance; - -import edu.gatech.gtri.bktree.BkTreeSearcher; -import edu.gatech.gtri.bktree.BkTreeSearcher.Match; -import edu.gatech.gtri.bktree.Metric; -import edu.gatech.gtri.bktree.MutableBkTree; - -/** - * Represents a randomized grammar. - * - * @author EVE - */ -public class RGrammar { - /* The max distance between possible alternate rules. */ - private static final int MAX_DISTANCE = 6; - - /* The metric for the levenshtein distance. */ - private static final class LevenshteinMetric implements Metric { - private static LevenshteinDistance DIST; - - static { - DIST = LevenshteinDistance.getDefaultInstance(); - } - - public LevenshteinMetric() { - } - - @Override - public int distance(String x, String y) { - return DIST.apply(x, y); - } - } - - /* The current state during generation. */ - private static class GenerationState { - /* The current string. */ - public StringBuilder contents; - /* The RNG. */ - public Random rnd; - - /* The current set of variables. */ - public Map vars; - - /** - * Create a new generation state. - * - * @param cont - * The string being generated. - * - * @param rand - * The RNG to use. - * - * @param vs - * The variables to use. - */ - public GenerationState(StringBuilder cont, Random rand, Map vs) { - contents = cont; - rnd = rand; - vars = vs; - } - } - - /* The pattern for matching the name of a variable. */ - private static Pattern NAMEVAR_PATTERN = Pattern.compile("\\$(\\w+)"); - - /* The rules of the grammar. */ - private Map rules; - /* The rules imported from other grammars. */ - private Map importRules; - /* The rules exported from this grammar. */ - private Set exportRules; - /* The initial rule of this grammar. */ - private String initialRule; - - /* The tree to use for finding rule suggestions. */ - private BkTreeSearcher ruleSearcher; - - /** - * Create a new randomized grammar using the specified set of rules. - * - * @param ruls - * The rules to use. - */ - public RGrammar(Map ruls) { - rules = ruls; - } - - /** - * Sets the imported rules to use. - * - * Imported rules are checked for rule definitions after local definitions are - * checked. - * - * @param importedRules - * The set of imported rules to use. - */ - public void setImportedRules(Map importedRules) { - importRules = importedRules; - } - - /** - * Generates the data structure backing rule suggestions for unknown rules. - */ - public void generateSuggestions() { - MutableBkTree ruleSuggester = new MutableBkTree<>(new LevenshteinMetric()); - - ruleSuggester.addAll(rules.keySet()); - ruleSuggester.addAll(importRules.keySet()); - - ruleSearcher = new BkTreeSearcher<>(ruleSuggester); - } - - /** - * Generate a string from this grammar, starting from the specified rule. - * - * @param startRule - * The rule to start generating at, or null to use the initial rule - * for this grammar. - * - * @return A possible string from the grammar. - */ - public String generate(String startRule) { - return generate(startRule, new Random(), new HashMap<>()); - } - - /** - * Generate a string from this grammar, starting from the specified rule. - * - * @param startRule - * The rule to start generating at, or null to use the initial rule - * for this grammar. - * - * @param rnd - * The random number generator to use. - * - * @param vars - * The set of variables to use. - * - * @return A possible string from the grammar. - */ - public String generate(String startRule, Random rnd, Map vars) { - String fromRule = startRule; - - if (startRule == null) { - if (initialRule == null) { - throw new GrammarException("Must specify a start rule for grammars with no initial rule"); - } - - fromRule = initialRule; - } else { - if (startRule.equals("")) { - throw new GrammarException("The empty string is not a valid rule name"); - } - } - - RuleCase start = rules.get(fromRule).getCase(rnd); - - StringBuilder contents = new StringBuilder(); - - generateCase(start, new GenerationState(contents, rnd, vars)); - - String body = contents.toString(); - /* - * Collapse duplicate spaces. - */ - body = body.replaceAll("\\s+", " "); - - /* - * Remove extraneous spaces around punctutation marks. - * - * This can be done in the grammars, but it is very tedious to do so. - */ - - /* Handle 's */ - body = body.replaceAll(" 's ", "'s "); - - /* Handle opening/closing punctuation. */ - body = body.replaceAll("([(\\[]) ", " $1"); - body = body.replaceAll(" ([)\\]'\"])", "$1 "); - - /* Remove spaces around series of opening/closing punctuation. */ - body = body.replaceAll("([(\\[])\\s+([(\\[])", "$1$2"); - body = body.replaceAll("([)\\]])\\s+([)\\]])", "$1$2"); - - /* Handle inter-word punctuation. */ - body = body.replaceAll(" ([,:.!])", "$1 "); - - /* Handle intra-word punctuation. */ - body = body.replaceAll("\\s?([-/])\\s?", "$1"); - - /* - * Collapse duplicate spaces. - */ - body = body.replaceAll("\\s+", " "); - - /* - * @TODO 11/01/17 Ben Culkin :RegexRule Replace this once it is no longer - * needed. - */ - body = body.replaceAll("\\s(ish|burg|ton|ville|opolis|field|boro|dale)", "$1"); - - return body; - } - - /* Generate a rule case. */ - private void generateCase(RuleCase start, GenerationState state) { - try { - switch (start.type) { - case NORMAL: - for (CaseElement elm : start.getElements()) { - generateElement(elm, state); - - if (elm.type != CaseElement.ElementType.VARDEF) { - state.contents.append(" "); - } - } - break; - case SPACEFLATTEN: - for (CaseElement elm : start.getElements()) { - generateElement(elm, state); - } - break; - default: - String msg = String.format("Unknown case type '%s'", start.type); - throw new GrammarException(msg); - } - } catch (GrammarException gex) { - String msg = String.format("Error in generating case (%s)", start); - throw new GrammarException(msg, gex); - } - } - - /* Generate a case element. */ - private void generateElement(CaseElement elm, GenerationState state) { - try { - switch (elm.type) { - case LITERAL: { - LiteralCaseElement lit = (LiteralCaseElement)elm; - - state.contents.append(lit.val); - break; - } - case RULEREF: { - RuleCaseElement rle = (RuleCaseElement)elm; - - generateRuleReference(rle, state); - break; - } - case RANGE: { - RangeCaseElement rang = (RangeCaseElement)elm; - - int val = state.rnd.nextInt(rang.end - rang.begin); - val += rang.begin; - - state.contents.append(val); - break; - } - case VARDEF: - generateVarDef(((VariableCaseElement)elm).varName, ((VariableCaseElement)elm).varDef, state); - break; - case EXPVARDEF: - generateExpVarDef(((VariableCaseElement)elm).varName, ((VariableCaseElement)elm).varDef, state); - break; - default: - String msg = String.format("Unknown element type '%s'", elm.type); - throw new GrammarException(msg); - } - } catch (GrammarException gex) { - String msg = String.format("Error in generating case element (%s)", elm); - throw new GrammarException(msg, gex); - } - } - - /* Generate a expanding variable definition. */ - private void generateExpVarDef(String name, String defn, GenerationState state) { - GenerationState newState = new GenerationState(new StringBuilder(), state.rnd, state.vars); - - if (rules.containsKey(defn)) { - RuleCase destCase = rules.get(defn).getCase(); - - generateCase(destCase, newState); - } else if (importRules.containsKey(defn)) { - RGrammar destGrammar = importRules.get(defn); - String res = destGrammar.generate(defn, state.rnd, state.vars); - - newState.contents.append(res); - } else { - String msg = String.format("No rule '%s' defined", defn); - throw new GrammarException(msg); - } - - state.vars.put(name, newState.contents.toString()); - } - - /* Generate a variable definition. */ - private static void generateVarDef(String name, String defn, GenerationState state) { - state.vars.put(name, defn); - } - - /* Generate a rule reference. */ - private void generateRuleReference(RuleCaseElement elm, GenerationState state) { - String refersTo = elm.val; - - GenerationState newState = new GenerationState(new StringBuilder(), state.rnd, state.vars); - - if (refersTo.contains("$")) { - /* Parse variables */ - String refBody = refersTo.substring(1, refersTo.length() - 1); - - if (refBody.contains("-")) { - /* Handle dependent rule names. */ - StringBuffer nameBuffer = new StringBuffer(); - - Matcher nameMatcher = NAMEVAR_PATTERN.matcher(refBody); - - while (nameMatcher.find()) { - String var = nameMatcher.group(1); - - if (!state.vars.containsKey(var)) { - String msg = String.format("No variable '%s' defined", var); - throw new GrammarException(msg); - } - - String name = state.vars.get(var); - - if (name.contains(" ")) { - throw new GrammarException("Variables substituted into names cannot contain spaces"); - } else if (name.equals("")) { - throw new GrammarException("Variables substituted into names cannot be empty"); - } - - nameMatcher.appendReplacement(nameBuffer, name); - } - - nameMatcher.appendTail(nameBuffer); - - refersTo = "[" + nameBuffer.toString() + "]"; - } else { - /* Handle string references. */ - if (refBody.equals("$")) { - throw new GrammarException("Cannot refer to unnamed variables"); - } - - String key = refBody.substring(1); - - if (!state.vars.containsKey(key)) { - String msg = String.format("No variable '%s' defined", key); - throw new GrammarException(msg); - } - - state.contents.append(state.vars.get(key)); - - return; - } - } - - if (refersTo.startsWith("[^")) { - refersTo = "[" + refersTo.substring(2); - - RGrammar dst = importRules.get(refersTo); - - newState.contents.append(dst.generate(refersTo, state.rnd, state.vars)); - } else if (rules.containsKey(refersTo)) { - RuleCase cse = rules.get(refersTo).getCase(state.rnd); - - generateCase(cse, newState); - } else if (importRules.containsKey(refersTo)) { - RGrammar dst = importRules.get(refersTo); - - newState.contents.append(dst.generate(refersTo, state.rnd, state.vars)); - } else { - if (ruleSearcher != null) { - Set> results = ruleSearcher.search(refersTo, MAX_DISTANCE); - - String[] resArray = results.stream().map(Match::getMatch).toArray((i) -> new String[i]); - - String msg = String.format("No rule '%s' defined (perhaps you meant %s?)", refersTo, - StringUtils.toEnglishList(resArray, false)); - - throw new GrammarException(msg); - } - - String msg = String.format("No rule '%s' defined", refersTo); - throw new GrammarException(msg); - } - - if (refersTo.contains("+")) { - /* Rule names with pluses in them get space-flattened */ - state.contents.append(newState.contents.toString().replaceAll("\\s+", "")); - } else { - state.contents.append(newState.contents.toString()); - } - } - - /** - * Get the initial rule of this grammar. - * - * @return The initial rule of this grammar. - */ - public String getInitialRule() { - return initialRule; - } - - /** - * Set the initial rule of this grammar. - * - * @param initRule - * The initial rule of this grammar, or null to say there is no - * initial rule. - */ - public void setInitialRule(String initRule) { - /* Passing null, nulls our initial rule. */ - if (initRule == null) { - this.initialRule = null; - return; - } - - if (initRule.equals("")) { - throw new GrammarException("The empty string is not a valid rule name"); - } else if (!rules.containsKey(initRule)) { - String msg = String.format("No rule '%s' local to this grammar defined.", initRule); - - throw new GrammarException(msg); - } - - initialRule = initRule; - } - - /** - * Gets the rules exported by this grammar. - * - * The initial rule is exported by default if specified. - * - * @return The rules exported by this grammar. - */ - public Set getExportedRules() { - Set res = new HashSet<>(); - - for (String rname : exportRules) { - if (!rules.containsKey(rname)) { - String msg = String.format("No rule '%s' local to this grammar defined", initialRule); - - throw new GrammarException(msg); - } - - res.add(rules.get(rname)); - } - - if (initialRule != null) { - res.add(rules.get(initialRule)); - } - - return res; - } - - /** - * Set the rules exported by this grammar. - * - * @param exportedRules - * The rules exported by this grammar. - */ - public void setExportedRules(Set exportedRules) { - exportRules = exportedRules; - } - - /** - * Get all the rules in this grammar. - * - * @return All the rules in this grammar. - */ - public Map getRules() { - return rules; - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/RGrammarBuilder.java b/RGens/src/main/java/bjc/rgens/parser/RGrammarBuilder.java deleted file mode 100644 index b4cb04a..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/RGrammarBuilder.java +++ /dev/null @@ -1,246 +0,0 @@ -package bjc.rgens.parser; - -import bjc.rgens.parser.elements.CaseElement; -import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IList; - -import static bjc.rgens.parser.RuleCase.CaseType.*; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Construct randomized grammars piece by piece. - * - * @author EVE - */ -public class RGrammarBuilder { - /* The rules being built. */ - private Map rules; - /* The current set of exported rules. */ - private Set exportedRules; - /* The current initial rule. */ - private String initialRule; - - /** Create a new randomized grammar builder. */ - public RGrammarBuilder() { - rules = new HashMap<>(); - - exportedRules = new HashSet<>(); - } - - /** - * Get or create a rule by the given name. - * - * @param rName - * The name of the rule. - * - * @return - * The rule by that name, or a new one if none existed. - */ - public Rule getOrCreateRule(String rName) { - if(rName == null) - throw new NullPointerException("Rule name must not be null"); - else if(rName.equals("")) - throw new IllegalArgumentException("The empty string is not a valid rule name"); - - if(rules.containsKey(rName)) - return rules.get(rName); - else { - Rule ret = new Rule(rName); - - rules.put(rName, ret); - - return ret; - } - } - - /** - * Convert this builder into a grammar. - * - * @return - * The grammar built by this builder - */ - public RGrammar toRGrammar() { - RGrammar grammar = new RGrammar(rules); - - grammar.setInitialRule(initialRule); - - grammar.setExportedRules(exportedRules); - - return grammar; - } - - /** - * Set the initial rule of the grammar. - * - * @param init - * The initial rule of the grammar. - * - * @throws IllegalArgumentException - * If the rule is either not valid or not defined in the grammar. - */ - public void setInitialRule(String init) { - if (init == null) { - throw new NullPointerException("init must not be null"); - } else if (init.equals("")) { - throw new IllegalArgumentException("The empty string is not a valid rule name"); - } - - initialRule = init; - } - - /** - * Add an exported rule to this grammar. - * - * @param export - * The name of the rule to export. - * - * @throws IllegalArgumentException - * If the rule is either not valid or not defined in the grammar. - */ - public void addExport(String export) { - if (export == null) { - throw new NullPointerException("Export name must not be null"); - } else if (export.equals("")) { - throw new NullPointerException("The empty string is not a valid rule name"); - } - - 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)) { - String msg = String.format("Rule '%s' is not a valid rule name."); - - throw new IllegalArgumentException(msg); - } - - CaseElement element = CaseElement.createElement(suffix); - - FunctionalList newCases = new FunctionalList<>(); - - IList caseList = rules.get(ruleName).getCases(); - for (RuleCase ruleCase : caseList) { - FunctionalList newCase = new FunctionalList<>(); - - for(CaseElement elm : ruleCase.getElements()) { - newCase.add(elm); - } - - newCase.add(element); - - newCases.add(new RuleCase(NORMAL, newCase)); - } - - - for (RuleCase newCase : newCases) { - caseList.add(newCase); - } - } - - /** - * Prefix a given case element to every case of a specific rule. - * - * @param ruleName - * The rule to prefix. - * - * @param prefix - * The prefix to add. - * - * @throws IllegalArgumentException - * 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) { - 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."); - - throw new IllegalArgumentException(msg); - } - - CaseElement element = CaseElement.createElement(prefix); - - FunctionalList newCases = new FunctionalList<>(); - - IList caseList = rules.get(ruleName).getCases(); - for (RuleCase ruleCase : caseList) { - FunctionalList newCase = new FunctionalList<>(); - - newCase.add(element); - - for(CaseElement elm : ruleCase.getElements()) { - newCase.add(elm); - } - - newCases.add(new RuleCase(NORMAL, newCase)); - } - - - for (RuleCase newCase : newCases) { - caseList.add(newCase); - } - } - - public void despaceRule(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"); - } - - IList caseList = rules.get(ruleName).getCases(); - - IList newCaseList = new FunctionalList<>(); - - for(RuleCase cse : caseList) { - newCaseList.add(new RuleCase(SPACEFLATTEN, cse.getElements())); - } - - rules.get(ruleName).replaceCases(newCaseList); - } - - public void regexizeRule(String rule, String pattern) { - if (rule == null) { - throw new NullPointerException("rule must not be null"); - } else if(pattern == null) { - throw new NullPointerException("pattern must not be null"); - } else if (rule.equals("")) { - throw new IllegalArgumentException("The empty string is not a valid rule name"); - } - - IList caseList = rules.get(rule).getCases(); - - IList newCaseList = new FunctionalList<>(); - - for(RuleCase cse : caseList) { - newCaseList.add(new RegexRuleCase(cse.getElements(), pattern)); - } - - rules.get(rule).replaceCases(newCaseList); - - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/RGrammarFormatter.java b/RGens/src/main/java/bjc/rgens/parser/RGrammarFormatter.java deleted file mode 100644 index a2454dc..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/RGrammarFormatter.java +++ /dev/null @@ -1,97 +0,0 @@ -package bjc.rgens.parser; - -import bjc.rgens.parser.elements.CaseElement; -import bjc.utils.funcdata.IList; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Format randomized grammars to strings properly. - * - * @author EVE - */ -public class RGrammarFormatter { - /** - * Format a grammar into a file that represents that grammar. - * - * @param gram - * The grammar to format. - * - * @return - * The formatted grammar. - */ - public static String formatGrammar(RGrammar gram) { - StringBuilder sb = new StringBuilder(); - - Map rules = gram.getRules(); - - String initRuleName = gram.getInitialRule(); - - Set processedRules = new HashSet<>(); - - if (initRuleName != null) { - processRule(rules.get(initRuleName), sb); - - processedRules.add(initRuleName); - } - - for (Rule rule : rules.values()) { - if (!processedRules.contains(rule.name)) { - sb.append("\n\n"); - - processRule(rule, sb); - } - - processedRules.add(rule.name); - } - - return sb.toString().trim(); - } - - /* Format a rule. */ - private static void processRule(Rule rule, StringBuilder sb) { - IList cases = rule.getCases(); - - StringBuilder ruleBuilder = new StringBuilder(); - - ruleBuilder.append(rule.name); - ruleBuilder.append(" \u2192 "); - - int markerPos = ruleBuilder.length(); - - processCase(cases.first(), ruleBuilder); - - sb.append(ruleBuilder.toString().trim()); - - ruleBuilder = new StringBuilder(); - - for (RuleCase cse : cases.tail()) { - sb.append("\n\t"); - - for (int i = 8; i < markerPos; i++) { - ruleBuilder.append(" "); - } - - processCase(cse, ruleBuilder); - - sb.append(ruleBuilder.toString()); - - ruleBuilder = new StringBuilder(); - } - - } - - /* Format a case. */ - private static void processCase(RuleCase cse, StringBuilder sb) { - /* Process each element, adding a space. */ - for (CaseElement element : cse.getElements()) { - sb.append(element.toString()); - sb.append(" "); - } - - /* Remove the trailing space. */ - sb.deleteCharAt(sb.length() - 1); - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/RGrammarParser.java b/RGens/src/main/java/bjc/rgens/parser/RGrammarParser.java deleted file mode 100644 index 3a357b1..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/RGrammarParser.java +++ /dev/null @@ -1,394 +0,0 @@ -package bjc.rgens.parser; - -import bjc.rgens.parser.elements.CaseElement; -import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IList; -import bjc.utils.funcutils.TriConsumer; -import bjc.utils.ioutils.blocks.Block; -import bjc.utils.ioutils.blocks.BlockReader; -import bjc.utils.ioutils.blocks.SimpleBlockReader; - -import java.io.Reader; -import java.io.StringReader; -import java.util.HashMap; -import java.util.Map; - -/** - * Reads {@link RGrammar} from a input stream. - * - * @author student - */ -public class RGrammarParser { - /** - * Whether we are in debug mode or not. - */ - public static final boolean DEBUG = false; - - /* - * Templates for level-dependent delimiters. - */ - /* Pragma block delimiter. */ - private static final String TMPL_PRAGMA_BLOCK_DELIM = "\\R\\t{%d}(?!\\t)"; - /* Rule declaration block delimiter. */ - private static final String TMPL_RULEDECL_BLOCK_DELIM = "\\R\\t\\t{%d}"; - /* Where block delimiter. */ - private static final String TMPL_WHERE_BLOCK_DELIM = "\\R\\t{%d}(?:in|end)\\R"; - /* Top-level block delimiter. */ - private static final String TMPL_TOPLEVEL_BLOCK_DELIM = "\\R\\t{%d}\\.?\\R"; - - /* Pragma impls. */ - private static Map> pragmas; - - /* Initialize pragmas. */ - static { - pragmas = new HashMap<>(); - - pragmas.put("initial-rule", (body, build, level) -> { - int sep = body.indexOf(' '); - - if (sep != -1) { - String msg = "Initial-rule pragma takes only one argument, the name of the initial rule"; - throw new GrammarException(msg); - } - - build.setInitialRule(body); - }); - - pragmas.put("despace-rule", (body, build, level) -> { - int sep = body.indexOf(' '); - - if (sep != -1) { - String msg = "despace-rule pragma takes only one argument, the name of the rule to despace"; - throw new GrammarException(msg); - } - - build.despaceRule(body); - }); - - pragmas.put("export-rule", (body, build, level) -> { - String[] exports = body.split(" "); - - for (String export : exports) { - build.addExport(export); - } - }); - - pragmas.put("regex-rule", (body, build, level) -> { - int nameIndex = body.indexOf(" "); - - if(nameIndex == -1) { - throw new GrammarException("Regex-rule pragma takes two arguments: the name of the rule to process, then the regex to apply after the rule has been generated."); - } - - String name = body.substring(0, nameIndex).trim(); - String patt = body.substring(nameIndex + 1).trim(); - - build.regexizeRule(name, patt); - }); - - pragmas.put("suffix-with", (body, build, level) -> { - String[] parts = body.trim().split(" "); - - if (parts.length != 2) { - String msg = "Suffix-with pragma takes two arguments, the name of the rule to suffix, then what to suffix it with"; - - throw new GrammarException(msg); - } - - build.suffixWith(parts[0], parts[1]); - }); - - pragmas.put("prefix-with", (body, build, level) -> { - String[] parts = body.trim().split(" "); - - if (parts.length != 2) { - String msg = "Prefix-with pragma takes two arguments, the name of the rule to prefix, then what to prefix it with"; - - throw new GrammarException(msg); - } - - build.prefixWith(parts[0], parts[1]); - }); - } - - /** - * Read a {@link RGrammar} from an input stream. - * - * @param is - * The input stream to read from. - * - * @return - * The grammar represented by the stream. - * - * @throws GrammarException - * Thrown if the grammar has a syntax error. - */ - public static RGrammar readGrammar(Reader is) throws GrammarException { - String dlm = String.format(TMPL_TOPLEVEL_BLOCK_DELIM, 0); - - try (BlockReader reader = new SimpleBlockReader(dlm, is)) { - if (!reader.hasNextBlock()) { - throw new GrammarException("At least one top-level block must be present"); - } - - try { - RGrammarBuilder build = new RGrammarBuilder(); - - reader.forEachBlock((block) -> { - if(DEBUG) - System.err.printf("Handling top-level block (%s)\n", block); - - handleBlock(build, block.contents, 0); - }); - - return build.toRGrammar(); - } catch (GrammarException gex) { - String msg = String.format("Error in block (%s)", reader.getBlock()); - throw new GrammarException(msg, gex); - } - } catch (Exception ex) { - throw new GrammarException("Unknown error handling block", ex); - } - } - - /* Throughout these, level indicates the nesting level of that construct. */ - - /* Handles an arbitrary block. */ - private static void handleBlock(RGrammarBuilder build, String block, - int level) throws GrammarException { - /* Discard empty blocks. */ - if (block.equals("") || block.matches("\\R")) - return; - - int typeSep = block.indexOf(' '); - - if (typeSep == -1) { - throw new GrammarException( - "A block must start with a introducer, followed by a space, then the rest of the block"); - } - - String blockType = block.substring(0, typeSep).trim(); - - if (blockType.equalsIgnoreCase("pragma")) { - handlePragmaBlock(block, build, level); - } else if (blockType.startsWith("[")) { - handleRuleBlock(block, build, level); - } else if (blockType.equalsIgnoreCase("where")) { - handleWhereBlock(block, build, level); - } else if (blockType.equalsIgnoreCase("#")) { - if(DEBUG) - System.err.printf("Handled comment block (%s)\n", block); - /* - * Comment block. - * - * @TODO 10/11/17 Ben Culkin :GrammarComment - * Attach these to the grammar somehow so that they - * can be re-output during formatting. - */ - return; - } else { - String msg = String.format("Unknown block type: '%s'", blockType); - throw new GrammarException(msg); - } - } - - /* Handle reading a block of pragmas. */ - private static void handlePragmaBlock(String block, RGrammarBuilder build, - int level) throws GrammarException { - String dlm = String.format(TMPL_PRAGMA_BLOCK_DELIM, level); - try (BlockReader pragmaReader = new SimpleBlockReader(dlm, new StringReader(block))) { - try { - pragmaReader.forEachBlock((pragma) -> { - if(DEBUG) - System.err.printf("Handled pragma block (%s)\n", pragma); - - String pragmaContents = pragma.contents; - - int pragmaSep = pragmaContents.indexOf(' '); - - if (pragmaSep == -1) { - String msg = "A pragma invocation must consist of the word pragma, followed by a space, then the body of the pragma"; - - throw new GrammarException(msg); - } - - String pragmaLeader = pragmaContents.substring(0, pragmaSep); - String pragmaBody = pragmaContents.substring(pragmaSep + 1); - - if (!pragmaLeader.equalsIgnoreCase("pragma")) { - String msg = String.format("Illegal line leader in pragma block: '%s'", pragmaLeader); - - throw new GrammarException(msg); - } - - handlePragma(pragmaBody, build, level); - }); - } catch (GrammarException gex) { - Block pragma = pragmaReader.getBlock(); - String msg = String.format("Error in pragma: (%s)", pragma); - - throw new GrammarException(msg, gex); - } - } catch (Exception ex) { - throw new GrammarException("Unknown error handling pragma block", ex); - } - } - - /* Handle an individual pragma in a block. */ - private static void handlePragma(String pragma, RGrammarBuilder build, - int level) throws GrammarException { - int bodySep = pragma.indexOf(' '); - - if (bodySep == -1) - bodySep = pragma.length(); - - String pragmaName = pragma.substring(0, bodySep); - String pragmaBody = pragma.substring(bodySep + 1); - - if (pragmas.containsKey(pragmaName)) { - try { - if(DEBUG) - System.err.printf("Handled pragma '%s'\n", pragmaName); - - pragmas.get(pragmaName).accept(pragmaBody, build, level); - } catch (GrammarException gex) { - String msg = String.format("Error in pragma '%s'", pragmaName); - - throw new GrammarException(msg, gex); - } - } else { - String msg = String.format("Unknown pragma '%s'", pragmaName); - - throw new GrammarException(msg); - } - } - - /* Handle a block of a rule declaration and one or more cases. */ - private static void handleRuleBlock(String ruleBlock, RGrammarBuilder build, - int level) throws GrammarException { - String dlm = String.format(TMPL_RULEDECL_BLOCK_DELIM, level); - try (BlockReader ruleReader = new SimpleBlockReader(dlm, new StringReader(ruleBlock))) { - try { - if (ruleReader.hasNextBlock()) { - /* Rule with a declaration followed by multiple cases. */ - ruleReader.nextBlock(); - Block declBlock = ruleReader.getBlock(); - - String declContents = declBlock.contents; - Rule rl = handleRuleDecl(build, declContents); - - ruleReader.forEachBlock((block) -> { - /* Ignore comment lines. */ - if(block.contents.trim().startsWith("#")) return; - - handleRuleCase(block.contents, build, rl); - }); - } else { - /* Rule with a declaration followed by a single case. */ - handleRuleDecl(build, ruleBlock); - } - } catch (GrammarException gex) { - String msg = String.format("Error in rule case (%s)", ruleReader.getBlock()); - - throw new GrammarException(msg, gex); - } - } catch (Exception ex) { - throw new GrammarException("Unknown error handling rule block", ex); - } - } - - /* Handle a rule declaration and its initial case. */ - private static Rule handleRuleDecl(RGrammarBuilder build, String declContents) { - int declSep = declContents.indexOf("\u2192"); - - if (declSep == -1) { - /* - * @NOTE - * We should maybe remove support for the old - * syntax at some point. However, maybe we don't - * want to do so so as to make inputting grammars - * easier. - */ - declSep = declContents.indexOf(' '); - - if (declSep == -1) { - String msg = "A rule must be given at least one case in its declaration, and seperated from that case by \u2192"; - - throw new GrammarException(msg); - } - } - - String ruleName = declContents.substring(0, declSep).trim(); - String ruleBody = declContents.substring(declSep + 1).trim(); - - if (ruleName.equals("")) { - throw new GrammarException("The empty string is not a valid rule name"); - } - - Rule rul = build.getOrCreateRule(ruleName); - - handleRuleCase(ruleBody, build, rul); - - return rul; - } - - /* Handle a single case of a rule. */ - private static void handleRuleCase(String cse, RGrammarBuilder build, Rule rul) { - IList caseParts = new FunctionalList<>(); - - for (String csepart : cse.split(" ")) { - String partToAdd = csepart.trim(); - - /* Ignore empty parts */ - if (partToAdd.equals("")) - continue; - - caseParts.add(CaseElement.createElement(partToAdd)); - } - - rul.addCase(new RuleCase(RuleCase.CaseType.NORMAL, caseParts)); - } - - /* Handle a where block (a block with local rules). */ - private static void handleWhereBlock(String block, RGrammarBuilder build, - int level) throws GrammarException { - int nlIndex = block.indexOf("\\n"); - - if (nlIndex == -1) { - throw new GrammarException("Where block must be a context followed by a body"); - } - - String trimBlock = block.substring(nlIndex).trim(); - - String whereDelim = String.format(TMPL_WHERE_BLOCK_DELIM, level); - - try (BlockReader whereReader = new SimpleBlockReader(whereDelim, - new StringReader(trimBlock))) { - try { - Block whereCtx = whereReader.next(); - - StringReader ctxReader = new StringReader(whereCtx.contents.trim()); - String ctxDelim = String.format(TMPL_TOPLEVEL_BLOCK_DELIM, level + 1); - - try (BlockReader bodyReader = new SimpleBlockReader(ctxDelim, ctxReader)) { - @SuppressWarnings("unused") - Block whereBody = whereReader.next(); - - /** - * @TODO 10/11/17 Ben Culkin :WhereBlocks - * Implement where blocks. - * - * A where block has the context evaluated - * in a new context, and the body executed - * in that context. - */ - } - } catch (GrammarException gex) { - throw new GrammarException(String.format("Error in where block (%s)", - whereReader.getBlock()), gex); - } - } catch (Exception ex) { - throw new GrammarException("Unknown error in where block", ex); - } - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/RGrammarSet.java b/RGens/src/main/java/bjc/rgens/parser/RGrammarSet.java deleted file mode 100644 index 975510a..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/RGrammarSet.java +++ /dev/null @@ -1,290 +0,0 @@ -package bjc.rgens.parser; - -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; -import java.util.Set; - -/** - * Represents a set of grammars that can share rules via exports. - * - * @author EVE - */ -public class RGrammarSet { - /* Contains all the grammars in this set. */ - private Map grammars; - - /* Contains all the exported rules from grammars. */ - private Map exportedRules; - - /* Contains which export came from which grammar. */ - private Map exportFrom; - - /* Contains which file a grammar was loaded from. */ - private Map loadedFrom; - - /** Create a new set of randomized grammars. */ - public RGrammarSet() { - grammars = new HashMap<>(); - - exportedRules = new HashMap<>(); - - exportFrom = new HashMap<>(); - loadedFrom = new HashMap<>(); - } - - /** - * Add a grammar to this grammar set. - * - * @param grammarName - * The name of the grammar to add. - * - * @param gram - * The grammar to add. - * - * @throws IllegalArgumentException - * If the grammar name is invalid. - */ - public void addGrammar(String grammarName, RGrammar gram) { - /* Make sure a grammar is valid. */ - if (grammarName == null) { - throw new NullPointerException("Grammar name must not be null"); - } else if (gram == null) { - throw new NullPointerException("Grammar must not be null"); - } else if (grammarName.equals("")) { - throw new IllegalArgumentException("The empty string is not a valid grammar name"); - } - - grammars.put(grammarName, gram); - - /* Process exports from the grammar. */ - for (Rule export : gram.getExportedRules()) { - exportedRules.put(export.name, gram); - - exportFrom.put(export.name, grammarName); - } - - /* Add exports to grammar. */ - gram.setImportedRules(exportedRules); - } - - /** - * Get a grammar from this grammar set. - * - * @param grammarName - * The name of the grammar to get. - * - * @return - * The grammar with that name. - * - * @throws IllegalArgumentException - * If the grammar name is invalid or not present in this set. - */ - public RGrammar getGrammar(String grammarName) { - /* Check arguments. */ - if (grammarName == null) { - throw new NullPointerException("Grammar name must not be null"); - } else if (grammarName.equals("")) { - throw new IllegalArgumentException("The empty string is not a valid grammar name"); - } else if (!grammars.containsKey(grammarName)) { - String msg = String.format("No grammar with name '%s' found", grammarName); - - throw new IllegalArgumentException(msg); - } - - return grammars.get(grammarName); - } - - /** - * Get the grammar a rule was exported from. - * - * @param exportName - * The name of the exported rule. - * - * @return - * The grammar the exported rule came from. - * - * @throws IllegalArgumentException - * If the export name is invalid or not present in this set. - */ - public RGrammar getExportSource(String exportName) { - /* Check arguments. */ - if (exportName == null) { - throw new NullPointerException("Export name must not be null"); - } else if (exportName.equals("")) { - throw new IllegalArgumentException("The empty string is not a valid rule name"); - } else if (!exportedRules.containsKey(exportName)) { - String msg = String.format("No export with name '%s' defined", exportName); - throw new IllegalArgumentException(msg); - } - - return exportedRules.get(exportName); - } - - /** - * Get the source of an exported rule. - * - * This will often be a grammar name, but is not required to be one. - * - * @param exportName - * The name of the exported rule. - * - * @return - * The source of an exported rule. - * - * @throws IllegalArgumentException - * If the exported rule is invalid or not present in this set. - */ - public String exportedFrom(String exportName) { - /* Check arguments. */ - if (exportName == null) { - throw new NullPointerException("Export name must not be null"); - } else if (exportName.equals("")) { - throw new IllegalArgumentException("The empty string is not a valid rule name"); - } else if (!exportedRules.containsKey(exportName)) { - String msg = String.format("No export with name '%s' defined", exportName); - - throw new IllegalArgumentException(msg); - } - - return exportFrom.getOrDefault(exportName, "Unknown"); - } - - /** - * Get the source of an grammar - * - * This will often be a file name, but is not required to be one. - * - * @param grammarName - * The name of the exported grammar. - * - * @return - * The source of an exported grammar. - * - * @throws IllegalArgumentException - * If the exported grammar is invalid or not present in this set. - */ - public String loadedFrom(String grammarName) { - /* Check arguments. */ - if (grammarName == null) { - throw new NullPointerException("Grammar name must not be null"); - } else if (grammarName.equals("")) { - throw new IllegalArgumentException("The empty string is not a valid grammar name"); - } else if (grammarName.equals("unknown")) { - return grammarName; - } else if (!grammars.containsKey(grammarName)) { - String msg = String.format("No grammar with name '%s' defined", grammarName); - throw new IllegalArgumentException(msg); - } - - return loadedFrom.getOrDefault(grammarName, "Unknown"); - } - - /** - * Get the names of all the grammars in this set. - * - * @return - * The names of all the grammars in this set. - */ - public Set getGrammars() { - return grammars.keySet(); - } - - /** - * Get the names of all the exported rules in this set. - * - * @return - * The names of all the exported rules in this set. - */ - public Set getExportedRules() { - return exportedRules.keySet(); - } - - /** - * Load a grammar set from a configuration file. - * - * @param cfgFile - * The configuration file to load from. - * - * @return - * The grammar set created by the configuration file. - * - * @throws IOException - * If something goes wrong during configuration loading. - */ - public static RGrammarSet fromConfigFile(Path cfgFile) throws IOException { - /* The grammar set to hand back. */ - RGrammarSet set = new RGrammarSet(); - - /* Get the directory that contains the config file. */ - Path cfgParent = cfgFile.getParent(); - - try(Scanner scn = new Scanner(cfgFile)) { - /* Execute lines from the configuration file. */ - while (scn.hasNextLine()) { - String ln = scn.nextLine().trim(); - - /* Ignore blank/comment lines. */ - if (ln.equals("")) continue; - - if (ln.startsWith("#")) continue; - - /* Handle mixed whitespace. */ - ln = ln.replaceAll("\\s+", " "); - - /* - * Get the place where the name of the grammar - * ends. - */ - int nameIdx = ln.indexOf(" "); - if (nameIdx == -1) { - throw new GrammarException("Must specify a name for a loaded grammar"); - } - - /* Name and path of grammar. */ - String name = ln.substring(0, nameIdx); - Path path = Paths.get(ln.substring(nameIdx).trim()); - - /* - * Convert from configuration relative path to - * absolute path. - */ - Path convPath = cfgParent.resolve(path.toString()); - - //if(Files.isDirectory(convPath)) { - // /* @TODO implement subset grammars */ - // throw new GrammarException("Sub-grammar sets aren't implemented yet"); - //} else if (convPath.getFileName().endsWith(".gram")) { - /* Load grammar file. */ - try { - BufferedReader fis = Files.newBufferedReader(convPath); - RGrammar gram = RGrammarParser.readGrammar(fis); - fis.close(); - - /* Add grammar to the set. */ - set.addGrammar(name, gram); - - /* - * Mark where the grammar came - * from. - */ - set.loadedFrom.put(name, path.toString()); - } catch (GrammarException gex) { - String msg = String.format("Error loading file '%s'", path); - throw new GrammarException(msg, gex); - } - //} else { - // String msg = String.format("Unrecognized file type '%s'", convPath.getFileName()); - // throw new GrammarException(msg); - //} - } - } - - return set; - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/RGrammarTest.java b/RGens/src/main/java/bjc/rgens/parser/RGrammarTest.java deleted file mode 100644 index 4b1f283..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/RGrammarTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package bjc.rgens.parser; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * Test for new grammar syntax. - * - * @author EVE - */ -public class RGrammarTest { - /** - * Main method. - * - * @param args - * Unused CLI args. - */ - public static void main(String[] args) { - URL rsc = RGrammarTest.class.getResource("/server-config-sample.cfg"); - - try { - /* Load a grammar set. */ - Path cfgPath = Paths.get(rsc.toURI()); - RGrammarSet gramSet = RGrammarSet.fromConfigFile(cfgPath); - - /* Generate rule suggestions for all the grammars in the set. */ - for (String gramName : gramSet.getGrammars()) { - gramSet.getGrammar(gramName).generateSuggestions(); - } - - /* Generate for each exported rule. */ - for (String exportName : gramSet.getExportedRules()) { - /* Where we loaded the rule from. */ - String loadSrc = gramSet.loadedFrom(gramSet.exportedFrom(exportName)); - - System.out.println(); - System.out.printf("Generating for exported rule '%s' from file '%s'\n", exportName, loadSrc); - - RGrammar grammar = gramSet.getExportSource(exportName); - for (int i = 0; i < 100; i++) { - try { - String res = grammar.generate(exportName); - if(exportName.contains("+")) res = res.replaceAll("\\s+", ""); - - if(res.length() > 120) { - System.out.printf("\t\n\tContents: %s\n\t\n", res); - } else { - System.out.printf("\tContents: %s\n", res); - } - } catch (GrammarException gex) { - /* Print out errors with generation. */ - String fmt = "Error in exported rule '%s' (loaded from '%s')\n"; - - System.out.printf(fmt, exportName, loadSrc); - System.out.println(); - gex.printStackTrace(); - - System.out.println(); - System.out.println(); - } - } - } - } catch (IOException ioex) { - ioex.printStackTrace(); - } catch (URISyntaxException urisex) { - urisex.printStackTrace(); - } - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/RGrammars.java b/RGens/src/main/java/bjc/rgens/parser/RGrammars.java deleted file mode 100644 index f74a756..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/RGrammars.java +++ /dev/null @@ -1,67 +0,0 @@ -package bjc.rgens.parser; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URI; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; - -/** - * Get access to the included grammars. - * - * @author Ben Culkin - */ -public class RGrammars { - private static RGrammarSet gramSet; - - private static void loadSet() { - try { - URI rsc = RGrammarTest.class.getResource("/server-config-sample.cfg").toURI(); - - Map env = new HashMap<>(); - env.put("create", "true"); - @SuppressWarnings("unused") - FileSystem zipfs = FileSystems.newFileSystem(rsc, env); - - Path cfgPath = Paths.get(rsc); - - gramSet = RGrammarSet.fromConfigFile(cfgPath); - } catch (IOException | URISyntaxException ex) { - RuntimeException rtex = new RuntimeException("Could not load grammars"); - - rtex.initCause(ex); - - throw rtex; - } - } - - /** - * Generate an exported rule. - * - * @param exportName - * The rule to generate. - * @return The generated rule - * @throws GrammarException - * If something went wrong. - */ - public static String generateExport(String exportName) throws GrammarException { - if (gramSet == null) - loadSet(); - - if (!gramSet.getExportedRules().contains(exportName)) { - throw new GrammarException(String.format("No exported rule named %s", exportName)); - } - - RGrammar gram = gramSet.getExportSource(exportName); - - String res = gram.generate(exportName); - if (exportName.contains("+")) - res = res.replaceAll("\\s+", ""); - - return res; - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/RegexRuleCase.java b/RGens/src/main/java/bjc/rgens/parser/RegexRuleCase.java deleted file mode 100644 index 5e03cd6..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/RegexRuleCase.java +++ /dev/null @@ -1,32 +0,0 @@ -package bjc.rgens.parser; - -import bjc.rgens.parser.elements.CaseElement; -import bjc.utils.funcdata.IList; - -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -public class RegexRuleCase extends RuleCase { - private Pattern patt; - - public RegexRuleCase(IList elements, String pattern) { - super(RuleCase.CaseType.REGEX); - - elementList = elements; - - try { - patt = Pattern.compile(pattern); - } catch (PatternSyntaxException psex) { - IllegalArgumentException iaex = - new IllegalArgumentException("This type requires a valid regular expression parameter"); - - iaex.initCause(psex); - - throw iaex; - } - } - - public Pattern getPattern() { - return patt; - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/Rule.java b/RGens/src/main/java/bjc/rgens/parser/Rule.java deleted file mode 100644 index 7043e0f..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/Rule.java +++ /dev/null @@ -1,134 +0,0 @@ -package bjc.rgens.parser; - -import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IList; - -import java.util.Random; - -/** - * A rule in a randomized grammar. - * - * @author EVE - */ -public class Rule { - /** The name of this grammar rule. */ - public final String name; - - /* The cases for this rule. */ - private IList cases; - - /** - * Create a new grammar rule. - * - * @param ruleName - * The name of the grammar rule. - * - * @throws IllegalArgumentException - * If the rule name is invalid. - */ - public Rule(String ruleName) { - 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"); - } - - name = ruleName; - - cases = new FunctionalList<>(); - } - - /** - * Adds a case to the rule. - * - * @param cse - * The case to add. - */ - public void addCase(RuleCase cse) { - if (cse == null) { - throw new NullPointerException("Case must not be null"); - } - - cases.add(cse); - } - - /** - * Get a random case from this rule. - * - * @return - * A random case from this rule. - */ - public RuleCase getCase() { - return cases.randItem(); - } - - /** - * Get a random case from this rule. - * - * @param rnd - * The random number generator to use. - * - * @return - * A random case from this rule. - */ - public RuleCase getCase(Random rnd) { - return cases.randItem(rnd::nextInt); - } - - /** - * Get all the cases of this rule. - * - * @return - * All the cases in this rule. - */ - public IList getCases() { - return cases; - } - - /** - * Replace the current list of cases with a new one. - * - * @param cases - * The new list of cases. - */ - public void replaceCases(IList cases) { - this.cases = cases; - } - - @Override - public int hashCode() { - final int prime = 31; - - int result = 1; - result = prime * result + ((cases == null) ? 0 : cases.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - - if (obj == null) return false; - - if (!(obj instanceof Rule)) return false; - - Rule other = (Rule) obj; - - if (cases == null) { - if (other.cases != null) return false; - } else if (!cases.equals(other.cases)) return false; - - if (name == null) { - if (other.name != null) return false; - } else if (!name.equals(other.name)) return false; - - return true; - } - - @Override - public String toString() { - return String.format("Rule [ruleName='%s', ruleCases=%s]", name, cases); - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/RuleCase.java b/RGens/src/main/java/bjc/rgens/parser/RuleCase.java deleted file mode 100644 index 9c0a856..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/RuleCase.java +++ /dev/null @@ -1,88 +0,0 @@ -package bjc.rgens.parser; - -import bjc.rgens.parser.elements.CaseElement; -import bjc.utils.funcdata.IList; - -/* - * @NOTE - * If at some point we add new case types, they should go into subclasses, - * not into this class. - */ -/** - * A case in a rule in a randomized grammar. - * - * @author EVE - */ -public class RuleCase { - /** - * The possible types of a case. - * - * @author EVE - */ - public static enum CaseType { - /** A normal case, composed from a list of elements. */ - NORMAL, - /** A case that doesn't insert spaces. */ - SPACEFLATTEN, - /** A case that applies a regex after generation. */ - REGEX - } - - /** The type of this case. */ - public final CaseType type; - - /** - * The list of element values for this case. - * - *

Used For

- *
- *
NORMAL, SPACEFLATTEN
- *
Used as the list of elementList the rule is composed of.
- *
- */ - protected IList elementList; - - protected RuleCase(CaseType typ) { - type = typ; - } - - /** - * Create a new case of the specified type that takes a element list - * parameter. - * - * @param typ - * The type of case to create. - * - * @param elements - * The element list parameter of the case. - * - * @throws IllegalArgumentException - * If this type doesn't take a element list parameter. - */ - public RuleCase(CaseType typ, IList elements) { - this(typ); - - switch (typ) { - case NORMAL: - case SPACEFLATTEN: - break; - case REGEX: - throw new IllegalArgumentException("This type requires an element list and a pattern"); - default: - throw new IllegalArgumentException("This type doesn't have a element list parameter"); - } - - elementList = elements; - } - - /** - * Get the element list value of this type. - * - * @return - * The element list value of this case, or null if this type - * doesn't have one. - */ - public IList getElements() { - return elementList; - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java b/RGens/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java deleted file mode 100644 index 7229e92..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java +++ /dev/null @@ -1,7 +0,0 @@ -package bjc.rgens.parser.elements; - -public class BlankCaseElement extends LiteralCaseElement { - public BlankCaseElement() { - super(""); - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/elements/CaseElement.java b/RGens/src/main/java/bjc/rgens/parser/elements/CaseElement.java deleted file mode 100644 index d74ab52..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/elements/CaseElement.java +++ /dev/null @@ -1,147 +0,0 @@ -package bjc.rgens.parser.elements; - -import bjc.rgens.parser.GrammarException; - -/* - * @TODO 10/11/17 Ben Culkin :CaseElementSplit Split this into multiple - * subclasses based off of a value of ElementType. - */ -/** - * A element in a rule case. - * - * @author EVE - */ -public class CaseElement { - /** - * The possible types of an element. - * - * @author EVE - */ - public static enum ElementType { - /** An element that represents a literal string. */ - LITERAL, - /** An element that represents a rule reference. */ - RULEREF, - /** An element that represents a random range. */ - RANGE, - /** An element that represents a variable that stores a string. */ - VARDEF, - /** - * An element that represents a variable that stores the result of generating a - * rule. - */ - EXPVARDEF; - } - - /* Regexps for marking rule types. */ - 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 ElementType type; - - /** - * Create a new case element. - * - * @param typ - * The type of this element. - */ - protected CaseElement(ElementType typ) { - type = typ; - } - - @Override - public String toString() { - switch (type) { - default: - 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(SPECIAL_CASELEM)) { - /* Handle special cases. */ - String specialBody = csepart.substring(1, csepart.length() - 1); - - System.out.printf("\t\tTRACE: special body is '%s'\n", specialBody); - - if (specialBody.matches("\\S+:=\\S+")) { - /* Handle expanding variable definitions. */ - String[] parts = specialBody.split(":="); - - if (parts.length != 2) { - String msg = "Expanded variables must be a name and a definition, seperated by :="; - - throw new GrammarException(msg); - } - - return new ExpVariableCaseElement(parts[0], parts[1]); - } else if (specialBody.matches("\\S+=\\S+")) { - /* Handle regular variable definitions. */ - String[] parts = specialBody.split("="); - - if (parts.length != 2) { - String msg = "Variables must be a name and a definition, seperated by ="; - - throw new GrammarException(msg); - } - - return new LitVariableCaseElement(parts[0], parts[1]); - } else if (specialBody.matches("{empty}")) { - /* Literal blank, for empty cases. */ - return new BlankCaseElement(); - } else { - throw new IllegalArgumentException(String.format("Unknown special case part '%s'", specialBody)); - } - } 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)); - - return new RangeCaseElement(firstNum, secondNum); - } - - return new RuleCaseElement(csepart); - } else { - return new LiteralCaseElement(csepart); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CaseElement other = (CaseElement) obj; - if (type != other.type) - return false; - return true; - } -} \ No newline at end of file diff --git a/RGens/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java b/RGens/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java deleted file mode 100644 index 30925e2..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java +++ /dev/null @@ -1,7 +0,0 @@ -package bjc.rgens.parser.elements; - -public class ExpVariableCaseElement extends VariableCaseElement { - public ExpVariableCaseElement(String name, String def) { - super(name, def, true); - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java b/RGens/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java deleted file mode 100644 index 11035b1..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java +++ /dev/null @@ -1,7 +0,0 @@ -package bjc.rgens.parser.elements; - -public class LitVariableCaseElement extends VariableCaseElement { - public LitVariableCaseElement(String name, String def) { - super(name, def, false); - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java b/RGens/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java deleted file mode 100644 index d96a32d..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java +++ /dev/null @@ -1,7 +0,0 @@ -package bjc.rgens.parser.elements; - -public class LiteralCaseElement extends StringCaseElement { - public LiteralCaseElement(String vl) { - super(vl, true); - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java b/RGens/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java deleted file mode 100644 index d98bc61..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java +++ /dev/null @@ -1,43 +0,0 @@ -package bjc.rgens.parser.elements; - -public class RangeCaseElement extends CaseElement { - public final int begin; - public final int end; - - public RangeCaseElement(int beg, int en) { - super(ElementType.RANGE); - - begin = beg; - end = en; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + begin; - result = prime * result + end; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - RangeCaseElement other = (RangeCaseElement) obj; - if (begin != other.begin) - return false; - if (end != other.end) - return false; - return true; - } - - @Override - public String toString() { - return String.format("[%d..%d]", begin, end); - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java b/RGens/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java deleted file mode 100644 index f4d3512..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java +++ /dev/null @@ -1,7 +0,0 @@ -package bjc.rgens.parser.elements; - -public class RuleCaseElement extends StringCaseElement { - public RuleCaseElement(String vl) { - super(vl, false); - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java b/RGens/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java deleted file mode 100644 index 0e64fd3..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java +++ /dev/null @@ -1,41 +0,0 @@ -package bjc.rgens.parser.elements; - -public class StringCaseElement extends CaseElement { - public final String val; - - protected StringCaseElement(String vl, boolean isLiteral) { - super(isLiteral ? ElementType.LITERAL : ElementType.RULEREF); - - val = vl; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((val == null) ? 0 : val.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - StringCaseElement other = (StringCaseElement) obj; - if (val == null) { - if (other.val != null) - return false; - } else if (!val.equals(other.val)) - return false; - return true; - } - - @Override - public String toString() { - return val; - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java b/RGens/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java deleted file mode 100644 index 920445a..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java +++ /dev/null @@ -1,60 +0,0 @@ -package bjc.rgens.parser.elements; - -public class VariableCaseElement extends CaseElement { - /** - * The name of the variable this element defines. - */ - public final String varName; - - /** - * The definition of the variable this element defines. - */ - public final String varDef; - - public VariableCaseElement(String name, String def, boolean isExp) { - super(isExp ? ElementType.EXPVARDEF : ElementType.VARDEF); - - varName = name; - varDef = def; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((varDef == null) ? 0 : varDef.hashCode()); - result = prime * result + ((varName == null) ? 0 : varName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - VariableCaseElement other = (VariableCaseElement) obj; - if (varDef == null) { - if (other.varDef != null) - return false; - } else if (!varDef.equals(other.varDef)) - return false; - if (varName == null) { - if (other.varName != null) - return false; - } else if (!varName.equals(other.varName)) - return false; - return true; - } - - @Override - public String toString() { - if (type == ElementType.VARDEF) { - return String.format("{%s:=%s}", varName, varDef); - } else { - return String.format("{%s=%s}", varName, varDef); - } - } -} diff --git a/RGens/src/main/java/bjc/rgens/parser/new-syntax.txt b/RGens/src/main/java/bjc/rgens/parser/new-syntax.txt deleted file mode 100644 index f6578b4..0000000 --- a/RGens/src/main/java/bjc/rgens/parser/new-syntax.txt +++ /dev/null @@ -1,13 +0,0 @@ -[grammar] → ([block] ( / \n\.\n ? / [block])*) ? - -[block] → [pragma - block] -→ [rule - block] -→ [where - block] - -[pragma - block] → [pragma] ( / \n( ? !\t) / [pragma])* - -[rule - block] → [rule - decl] [rule - case] ( / \n\t / [rule - case])* - -[where - block] → where / \n\t / ([rule - block] / \n\t / ) + in / \n\t / [rule - block] - -[pragma] → pragma [pragma - name] [pragma - body] -- cgit v1.2.3