summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/rgens/parser
diff options
context:
space:
mode:
authorBenjamin J. Culkin <bjculkin@mix.wvu.edu>2018-06-07 20:37:51 -0300
committerBenjamin J. Culkin <bjculkin@mix.wvu.edu>2018-06-07 20:37:51 -0300
commit44a8d9d2d56a311293ec86ea40df7126748300a1 (patch)
treecc53c34a97a403ddb4a8d112f09124ee42c4507a /src/main/java/bjc/rgens/parser
parent7422af49fa5c4da57323abe676a99468d401c44b (diff)
Refactoring
The main refactoring here is removing the type field from the various classes, but there are a few other smaller ones. This also contains the grounds for a refactoring on variable use
Diffstat (limited to 'src/main/java/bjc/rgens/parser')
-rw-r--r--src/main/java/bjc/rgens/parser/ConfigLoader.java216
-rw-r--r--src/main/java/bjc/rgens/parser/FlatRuleCase.java6
-rw-r--r--src/main/java/bjc/rgens/parser/NormalRuleCase.java8
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammar.java111
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammarBuilder.java28
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammarFormatter.java2
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammarParser.java50
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RegexRuleCase.java31
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RuleCase.java73
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/CaseElement.java49
-rw-r--r--src/main/java/bjc/rgens/parser/elements/ChanceCaseElement.java20
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java14
-rw-r--r--src/main/java/bjc/rgens/parser/elements/InlineRuleCaseElement.java31
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/RangeCaseElement.java2
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/RuleCaseElement.java13
-rw-r--r--src/main/java/bjc/rgens/parser/elements/SerialCaseElement.java4
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/StringCaseElement.java2
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/VariableCaseElement.java11
-rw-r--r--src/main/java/bjc/rgens/parser/elements/vars/ARefVariableElement.java35
-rw-r--r--src/main/java/bjc/rgens/parser/elements/vars/LiteralVariableElement.java15
-rw-r--r--src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java35
-rw-r--r--src/main/java/bjc/rgens/parser/elements/vars/TRefVariableElement.java43
-rw-r--r--src/main/java/bjc/rgens/parser/elements/vars/VRefVariableElement.java29
-rw-r--r--src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java59
-rw-r--r--src/main/java/bjc/rgens/parser/templates/GrammarTemplate.java2
-rw-r--r--src/main/java/bjc/rgens/parser/templates/LiteralTemplateElement.java2
-rw-r--r--src/main/java/bjc/rgens/parser/templates/LiveTemplateElement.java4
-rw-r--r--src/main/java/bjc/rgens/parser/templates/TemplateElement.java18
28 files changed, 564 insertions, 349 deletions
diff --git a/src/main/java/bjc/rgens/parser/ConfigLoader.java b/src/main/java/bjc/rgens/parser/ConfigLoader.java
index 4cad368..6e9da16 100644
--- a/src/main/java/bjc/rgens/parser/ConfigLoader.java
+++ b/src/main/java/bjc/rgens/parser/ConfigLoader.java
@@ -70,9 +70,9 @@ public class ConfigLoader {
throw new GrammarException("Unknown config line type " + type);
}
} catch(GrammarException gex) {
- System.out.printf("ERROR: Line %s of grammar set %s\n", lno, cfgFile);
+ System.out.printf("ERROR: Line %s of config set %s\n", lno, cfgFile);
- System.err.printf("ERROR: Line %s of grammar set %s\n", lno, cfgFile);
+ System.err.printf("ERROR: Line %s of config set %s\n", lno, cfgFile);
gex.printStackTrace();
System.out.println();
@@ -117,62 +117,7 @@ public class ConfigLoader {
switch(tag) {
case "template":
- {
- Path path = Paths.get(ln);
-
- /*
- * Convert from configuration relative path to
- * absolute path.
- */
- Path convPath = cfgParent.resolve(path.toString());
-
- if(Files.isDirectory(convPath)) {
- throw new GrammarException("Can't load grammar from directory" + convPath.toString());
- } else {
- /* Load template file. */
- try {
- long startFileTime = System.nanoTime();
-
- BufferedReader fis = Files.newBufferedReader(convPath);
- GrammarTemplate template = GrammarTemplate.readTemplate(fis);
- template.belongsTo = cfgSet;
-
- if(template.name == null) {
- System.err.printf("\tINFO: Naming unnamed template loaded from %s off config name '%s'\n",
- convPath, name);
-
- template.name = name;
- }
-
- fis.close();
-
- long endFileTime = System.nanoTime();
-
- long fileTime = endFileTime - startFileTime;
-
- System.err.printf("\tPERF: Read template %s (from %s) in %d ns (%f s)\n",
- template.name, convPath, fileTime, fileTime / 1000000000.0);
-
- /* Add grammar to the set. */
- cfgSet.templates.put(name, template);
-
- /*
- * @NOTE
- *
- * Do we need to do this
- * for templates?
- *
- * Mark where the
- * template 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);
- }
- }
- }
+ loadTemplate(name, ln, cfgSet, set, cfgParent);
break;
case "subset":
{
@@ -181,58 +126,117 @@ public class ConfigLoader {
}
case "gram":
case "grammar":
- {
- Path path = Paths.get(ln);
-
- /*
- * Convert from configuration relative path to
- * absolute path.
- */
- Path convPath = cfgParent.resolve(path.toString());
-
- if(Files.isDirectory(convPath)) {
- throw new GrammarException("Can't load grammar from directory" + convPath.toString());
- } else {
- /* Load grammar file. */
- try {
- long startFileTime = System.nanoTime();
-
- BufferedReader fis = Files.newBufferedReader(convPath);
- RGrammar gram = RGrammarParser.readGrammar(fis);
- if(gram.name == null) {
- System.err.printf("\tINFO: Naming unnamed grammar loaded from %s off config name '%s'\n",
- convPath, name);
-
- gram.name = name;
- }
-
- fis.close();
-
- long endFileTime = System.nanoTime();
-
- long fileTime = endFileTime - startFileTime;
-
- System.err.printf("\tPERF: Read grammar %s (from %s) in %d ns (%f s)\n",
- gram.name, convPath, fileTime, fileTime / 1000000000.0);
-
- /* 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);
- }
- }
- }
+ loadGrammar(name, ln, cfgSet, set, cfgParent);
break;
default:
String msg = String.format("Unrecognized tag type '%s'", tag);
throw new GrammarException(msg);
}
}
+
+ private static void loadTemplate(String name, String ln, ConfigSet cfgSet, RGrammarSet set, Path cfgParent) throws IOException {
+ Path path = Paths.get(ln);
+
+ /*
+ * Convert from configuration relative path to
+ * absolute path.
+ */
+ Path convPath = cfgParent.resolve(path.toString());
+
+ if(Files.isDirectory(convPath)) {
+ throw new GrammarException("Can't load grammar from directory" + convPath.toString());
+ } else {
+ /* Load template file. */
+ try {
+ long startFileTime = System.nanoTime();
+
+ BufferedReader fis = Files.newBufferedReader(convPath);
+ GrammarTemplate template = GrammarTemplate.readTemplate(fis);
+ template.belongsTo = cfgSet;
+
+ if(template.name == null) {
+ System.err.printf("\tINFO: Naming unnamed template loaded from %s off config name '%s'\n",
+ convPath, name);
+
+ template.name = name;
+ }
+
+ fis.close();
+
+ long endFileTime = System.nanoTime();
+
+ long fileTime = endFileTime - startFileTime;
+
+ System.err.printf("\tPERF: Read template %s (from %s) in %d ns (%f s)\n",
+ template.name, convPath, fileTime, fileTime / 1000000000.0);
+
+ /* Add grammar to the set. */
+ cfgSet.templates.put(name, template);
+
+ /*
+ * @NOTE
+ *
+ * Do we need to do this
+ * for templates?
+ *
+ * Mark where the
+ * template came
+ * from.
+ */
+ //set.loadedFrom.put(name, path.toString());
+ } catch (GrammarException gex) {
+ String msg = String.format("Error loading template file '%s'", path);
+ throw new GrammarException(msg, gex);
+ }
+ }
+ }
+
+ private static void loadGrammar(String name, String ln, ConfigSet cfgSet, RGrammarSet set, Path cfgParent) throws IOException {
+ Path path = Paths.get(ln);
+
+ /*
+ * Convert from configuration relative path to
+ * absolute path.
+ */
+ Path convPath = cfgParent.resolve(path.toString());
+
+ if(Files.isDirectory(convPath)) {
+ throw new GrammarException("Can't load grammar from directory" + convPath.toString());
+ } else {
+ /* Load grammar file. */
+ try {
+ long startFileTime = System.nanoTime();
+
+ BufferedReader fis = Files.newBufferedReader(convPath);
+ RGrammar gram = RGrammarParser.readGrammar(fis);
+ if(gram.name == null) {
+ System.err.printf("\tINFO: Naming unnamed grammar loaded from %s off config name '%s'\n",
+ convPath, name);
+
+ gram.name = name;
+ }
+
+ fis.close();
+
+ long endFileTime = System.nanoTime();
+
+ long fileTime = endFileTime - startFileTime;
+
+ System.err.printf("\tPERF: Read grammar %s (from %s) in %d ns (%f s)\n",
+ gram.name, convPath, fileTime, fileTime / 1000000000.0);
+
+ /* 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 template '%s'", path);
+ throw new GrammarException(msg, gex);
+ }
+ }
+ }
}
diff --git a/src/main/java/bjc/rgens/parser/FlatRuleCase.java b/src/main/java/bjc/rgens/parser/FlatRuleCase.java
index 58f3d54..4bbd1cc 100644
--- a/src/main/java/bjc/rgens/parser/FlatRuleCase.java
+++ b/src/main/java/bjc/rgens/parser/FlatRuleCase.java
@@ -6,7 +6,7 @@ import bjc.rgens.parser.elements.CaseElement;
public class FlatRuleCase extends RuleCase {
public FlatRuleCase(IList<CaseElement> elms) {
- super(CaseType.SPACEFLATTEN, elms);
+ super(elms);
}
@Override
@@ -15,5 +15,9 @@ public class FlatRuleCase extends RuleCase {
elm.generate(state);
}
}
+
+ public FlatRuleCase withElements(IList<CaseElement> elms) {
+ return new FlatRuleCase(elms);
+ }
}
diff --git a/src/main/java/bjc/rgens/parser/NormalRuleCase.java b/src/main/java/bjc/rgens/parser/NormalRuleCase.java
index 19fa8af..c8891a2 100644
--- a/src/main/java/bjc/rgens/parser/NormalRuleCase.java
+++ b/src/main/java/bjc/rgens/parser/NormalRuleCase.java
@@ -6,7 +6,7 @@ import bjc.rgens.parser.elements.CaseElement;
public class NormalRuleCase extends RuleCase {
public NormalRuleCase(IList<CaseElement> elms) {
- super(CaseType.NORMAL, elms);
+ super(elms);
}
@Override
@@ -14,9 +14,13 @@ public class NormalRuleCase extends RuleCase {
for(CaseElement elm : elementList) {
elm.generate(state);
- if(elm.type.spacing) {
+ if(elm.spacing) {
state.contents.append(" ");
}
}
}
+
+ public NormalRuleCase withElements(IList<CaseElement> elms) {
+ return new NormalRuleCase(elms);
+ }
}
diff --git a/src/main/java/bjc/rgens/parser/RGrammar.java b/src/main/java/bjc/rgens/parser/RGrammar.java
index d523479..e537781 100755
--- a/src/main/java/bjc/rgens/parser/RGrammar.java
+++ b/src/main/java/bjc/rgens/parser/RGrammar.java
@@ -10,8 +10,11 @@ import bjc.rgens.parser.elements.RangeCaseElement;
import bjc.rgens.parser.elements.RuleCaseElement;
import bjc.rgens.parser.elements.VariableCaseElement;
+import java.util.Arrays;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
@@ -25,6 +28,8 @@ import edu.gatech.gtri.bktree.BkTreeSearcher.Match;
import edu.gatech.gtri.bktree.Metric;
import edu.gatech.gtri.bktree.MutableBkTree;
+import static bjc.utils.data.IPair.pair;
+
/**
* Represents a randomized grammar.
*
@@ -35,6 +40,11 @@ public class RGrammar {
public String name;
+ public List<IPair<String, String>> postprocs;
+
+ private static final List<IPair<String, String>> builtinPostprocs;
+ public boolean useBuiltinPostprocs = true;
+
/* The max distance between possible alternate rules. */
private static final int MAX_DISTANCE = 6;
@@ -67,6 +77,43 @@ public class RGrammar {
/* The tree to use for finding rule suggestions. */
private BkTreeSearcher<String> ruleSearcher;
+ static {
+ /* Collapse duplicate spaces */
+ IPair<String, String> collapseDupSpaces = pair("\\s+", " ");
+
+ /* Built-in post-processing steps */
+ builtinPostprocs = Arrays.asList(
+ collapseDupSpaces,
+
+ /*
+ * Remove extraneous spaces around punctuation
+ * marks, forced by the way the language syntax
+ * works.
+ *
+ * This can be done in grammars, but it is quite
+ * tedious to do so.
+ */
+
+
+ /* Handle 's */
+ pair(" 's ", "'s "),
+ /* Handle opening/closing punctuation. */
+ pair("([(\\[]) ", " $1"),
+ pair(" ([)\\]'\"])", "$1 "),
+ /* Remove spaces around series of opening/closing punctuation. */
+ pair("([(\\[])\\s+([(\\[])", "$1$2"),
+ pair("([)\\]])\\s+([)\\]])", "$1$2"),
+ /* Handle inter-word punctuation. */
+ pair(" ([,:.!])", "$1 "),
+ /* Handle intra-word punctuation. */
+ pair("\\s?([-/])\\s?", "$1"),
+
+ collapseDupSpaces,
+
+ /* Replace this once it is no longer needed. */
+ pair("\\s(ish|burg|ton|ville|opolis|field|boro|dale)", "$1")
+ );
+ }
/**
* Create a new randomized grammar using the specified set of rules.
*
@@ -79,6 +126,8 @@ public class RGrammar {
for(Rule rl : ruls.values()) {
rl.belongsTo = this;
}
+
+ postprocs = new ArrayList<>();
}
/**
@@ -150,6 +199,10 @@ public class RGrammar {
* The generation state.
*/
public String generate(String startRule, GenerationState state) {
+ return generate(startRule, state, true);
+ }
+
+ public String generate(String startRule, GenerationState state, boolean doPostprocess) {
String fromRule = startRule;
if (startRule == null) {
@@ -175,53 +228,27 @@ public class RGrammar {
rl.generate(state);
- /*
- * @NOTE
- *
- * :Postprocessing
- *
- * Do we want to perform this post-processing here, or elsewhere?
- */
- return postprocessRes(state.contents.toString());
- }
-
- private String postprocessRes(String strang) {
- String body = strang.replaceAll("\\s+", " ");
+ String body = state.contents.toString();
- /*
- * 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");
+ if(doPostprocess) {
+ body = postprocessRes(body);
+ }
- /* Handle inter-word punctuation. */
- body = body.replaceAll(" ([,:.!])", "$1 ");
+ return body;
+ }
- /* Handle intra-word punctuation. */
- body = body.replaceAll("\\s?([-/])\\s?", "$1");
+ private String postprocessRes(String strang) {
+ String body = strang;
- /*
- * Collapse duplicate spaces.
- */
- body = body.replaceAll("\\s+", " ");
+ if(useBuiltinPostprocs) {
+ for(IPair<String, String> par : builtinPostprocs) {
+ body = body.replaceAll(par.getLeft(), par.getRight());
+ }
+ }
- /*
- * @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");
+ for(IPair<String, String> par : postprocs) {
+ body = body.replaceAll(par.getLeft(), par.getRight());
+ }
return body.trim();
}
diff --git a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
index 453be05..8f0a2d1 100755
--- a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
+++ b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java
@@ -9,8 +9,6 @@ import bjc.utils.funcdata.IList;
import bjc.utils.funcutils.ListUtils;
import bjc.utils.funcutils.SetUtils;
-import static bjc.rgens.parser.RuleCase.CaseType.*;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -166,10 +164,12 @@ public class RGrammarBuilder {
IList<IPair<Integer, RuleCase>> caseList = rules.get(ruleName).getCases();
for (IPair<Integer, RuleCase> ruleCase : caseList) {
+ RuleCase cas = ruleCase.getRight();
+
for(List<CaseElement> suffixList : suffixLists) {
FunctionalList<CaseElement> newCase = new FunctionalList<>();
- for(CaseElement elm : ruleCase.getRight().getElements()) {
+ for(CaseElement elm : cas.elementList) {
newCase.add(elm);
}
@@ -177,13 +177,7 @@ public class RGrammarBuilder {
newCase.add(element);
}
- /*
- * @NOTE :AffixCasing
- *
- * Is this correct, or should we be mirroring the
- * existing case type?
- */
- newCases.add(new Pair<>(ruleCase.getLeft(), new NormalRuleCase(newCase)));
+ newCases.add(new Pair<>(ruleCase.getLeft(), cas.withElements(newCase)));
}
}
@@ -228,6 +222,8 @@ public class RGrammarBuilder {
IList<IPair<Integer, RuleCase>> caseList = rules.get(ruleName).getCases();
for (IPair<Integer, RuleCase> ruleCase : caseList) {
+ RuleCase cas = ruleCase.getRight();
+
for(List<CaseElement> prefixList : prefixLists) {
FunctionalList<CaseElement> newCase = new FunctionalList<>();
@@ -235,17 +231,11 @@ public class RGrammarBuilder {
newCase.add(elm);
}
- for(CaseElement elm : ruleCase.getRight().getElements()) {
+ for(CaseElement elm :cas.elementList) {
newCase.add(elm);
}
- /*
- * @NOTE :AffixCasing
- *
- * Is this correct, or should we be mirroring the
- * existing case type?
- */
- newCases.add(new Pair<>(ruleCase.getLeft(), new NormalRuleCase(newCase)));
+ newCases.add(new Pair<>(ruleCase.getLeft(), cas.withElements(newCase)));
}
}
@@ -269,7 +259,7 @@ public class RGrammarBuilder {
IList<IPair<Integer, RuleCase>> newCaseList = new FunctionalList<>();
for(IPair<Integer, RuleCase> cse : caseList) {
- newCaseList.add(new Pair<>(cse.getLeft(), new FlatRuleCase(cse.getRight().getElements())));
+ newCaseList.add(new Pair<>(cse.getLeft(), new FlatRuleCase(cse.getRight().elementList)));
}
System.err.printf("\t\tTRACE: Despacing %d cases of rule %s\n", caseList.getSize(), ruleName);
diff --git a/src/main/java/bjc/rgens/parser/RGrammarFormatter.java b/src/main/java/bjc/rgens/parser/RGrammarFormatter.java
index 7e058b0..c571cb7 100755
--- a/src/main/java/bjc/rgens/parser/RGrammarFormatter.java
+++ b/src/main/java/bjc/rgens/parser/RGrammarFormatter.java
@@ -89,7 +89,7 @@ public class RGrammarFormatter {
/* Format a case. */
private static void processCase(RuleCase cse, StringBuilder sb) {
/* Process each element, adding a space. */
- for (CaseElement element : cse.getElements()) {
+ for (CaseElement element : cse.elementList) {
sb.append(element.toString());
sb.append(" ");
}
diff --git a/src/main/java/bjc/rgens/parser/RGrammarParser.java b/src/main/java/bjc/rgens/parser/RGrammarParser.java
index c807f5f..a869179 100755
--- a/src/main/java/bjc/rgens/parser/RGrammarParser.java
+++ b/src/main/java/bjc/rgens/parser/RGrammarParser.java
@@ -1,7 +1,6 @@
package bjc.rgens.parser;
-import bjc.rgens.parser.elements.CaseElement;
-import bjc.rgens.parser.elements.SerialCaseElement;
+import bjc.rgens.parser.elements.*;
import bjc.utils.data.IPair;
import bjc.utils.data.Pair;
@@ -475,7 +474,9 @@ public class RGrammarParser {
int serialLower = -1;
int serialUpper = -1;
+ int chance = -1;
boolean doSerial = false;
+ boolean doChance = false;
for (String csepart : cses) {
String partToAdd = csepart.trim();
@@ -493,6 +494,34 @@ public class RGrammarParser {
serialUpper = Integer.parseInt(partToAdd.substring(partToAdd.lastIndexOf(".") + 1, partToAdd.length() - 1));
doSerial = true;
+ } else if(partToAdd.matches("\\<\\?\\d+\\>")) {
+ chance = Integer.parseInt(partToAdd.substring(2, partToAdd.length() - 1));
+
+ doChance = true;
+ } else if (partToAdd.matches("\\<\\<\\>")) {
+ CaseElement elm = caseParts.popLast();
+
+ if(repCount == 0) {
+ /* Skip no-reps */
+ } else {
+ if(doChance) {
+ elm = new ChanceCaseElement(elm, chance);
+
+ doChance = false;
+ }
+
+ if(doSerial) {
+ elm = new SerialCaseElement(elm, serialLower, serialUpper);
+
+ doSerial = false;
+ }
+
+ for(int i = 1; i <= repCount; i++) {
+ caseParts.add(elm);
+ }
+
+ repCount = 1;
+ }
} else if(partToAdd.matches("\\<[^\\>]+\\>")) {
throw new GrammarException("Unknown parser meta-rule " + partToAdd);
} else {
@@ -500,14 +529,23 @@ public class RGrammarParser {
if(repCount == 0) {
/* Skip no-reps */
- } else if(doSerial) {
- caseParts.add(new SerialCaseElement(elm, serialLower, serialUpper));
-
- doSerial = false;
} else {
+ if(doChance) {
+ elm = new ChanceCaseElement(elm, chance);
+
+ doChance = false;
+ }
+
+ if(doSerial) {
+ elm = new SerialCaseElement(elm, serialLower, serialUpper);
+
+ doSerial = false;
+ }
+
for(int i = 1; i <= repCount; i++) {
caseParts.add(elm);
}
+
}
repCount = 1;
diff --git a/src/main/java/bjc/rgens/parser/RegexRuleCase.java b/src/main/java/bjc/rgens/parser/RegexRuleCase.java
index 3a8a8ad..3c57489 100755
--- a/src/main/java/bjc/rgens/parser/RegexRuleCase.java
+++ b/src/main/java/bjc/rgens/parser/RegexRuleCase.java
@@ -6,31 +6,22 @@ import bjc.utils.funcdata.IList;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
+/*
+ * @TODO
+ *
+ * Actually implement this
+ */
public class RegexRuleCase extends RuleCase {
- private Pattern patt;
+ public RegexRuleCase(IList<CaseElement> elements) {
+ super(elements);
- public RegexRuleCase(IList<CaseElement> elements, String pattern) {
- super(CaseType.REGEX, elements);
-
- 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;
}
public void generate(GenerationState state) {
}
+
+ public RegexRuleCase withElements(IList<CaseElement> elements) {
+ return new RegexRuleCase(elements);
+ }
}
diff --git a/src/main/java/bjc/rgens/parser/RuleCase.java b/src/main/java/bjc/rgens/parser/RuleCase.java
index 369c588..33aea0c 100755
--- a/src/main/java/bjc/rgens/parser/RuleCase.java
+++ b/src/main/java/bjc/rgens/parser/RuleCase.java
@@ -20,91 +20,34 @@ public abstract class RuleCase {
private static int nextSerial = 0;
- /**
- * 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;
-
public Rule belongsTo;
- /**
- * The list of element values for this case.
- *
- * <h2>Used For</h2>
- * <dl>
- * <dt>NORMAL, SPACEFLATTEN</dt>
- * <dd>Used as the list of elementList the rule is composed of.</dd>
- * </dl>
- */
- protected IList<CaseElement> elementList;
-
- protected RuleCase(CaseType typ) {
- serial = nextSerial;
-
- type = typ;
-
- nextSerial += 1;
- }
+ public IList<CaseElement> elementList;
/**
* 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<CaseElement> 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");
- }
-
+ protected RuleCase(IList<CaseElement> elements) {
elementList = elements;
+
+ serial = nextSerial;
+ nextSerial += 1;
}
public abstract void generate(GenerationState state);
- /**
- * 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<CaseElement> getElements() {
- return elementList;
- }
+ public abstract RuleCase withElements(IList<CaseElement> elements);
public String toString() {
if(debugName != null) {
- return String.format("Case %d (%s) of %s", serial, debugName, belongsTo);
+ return String.format("Case %s (#%d) of %s", debugName, serial, belongsTo);
} else {
- return String.format("Case %d (%s-%d) of %s", serial, belongsTo, serial, belongsTo);
+ return String.format("Case #%d of %s", serial, belongsTo, serial, belongsTo);
}
}
diff --git a/src/main/java/bjc/rgens/parser/elements/CaseElement.java b/src/main/java/bjc/rgens/parser/elements/CaseElement.java
index 68f5368..d799dbe 100755
--- a/src/main/java/bjc/rgens/parser/elements/CaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/CaseElement.java
@@ -1,5 +1,7 @@
package bjc.rgens.parser.elements;
+import bjc.utils.funcutils.StringUtils;
+
import bjc.rgens.parser.GenerationState;
import bjc.rgens.parser.GrammarException;
@@ -32,7 +34,11 @@ public abstract class CaseElement {
}
/** The type of this element. */
- public final ElementType type;
+ public boolean spacing;
+
+ protected CaseElement() {
+ this(true);
+ }
/**
* Create a new case element.
@@ -40,13 +46,8 @@ public abstract class CaseElement {
* @param typ
* The type of this element.
*/
- protected CaseElement(ElementType typ) {
- type = typ;
- }
-
- @Override
- public String toString() {
- return String.format("Unknown type '%s'", type);
+ protected CaseElement(boolean spacing) {
+ this.spacing = spacing;
}
/**
@@ -70,15 +71,13 @@ public abstract class CaseElement {
throw new NullPointerException("Case part cannot be null");
}
- if (csepart.matches("\\{[^}]+\\}")) {
+ if (csepart.matches("\\{\\S+\\}")) {
/*
* Handle special case elements.
*
*/
String specialBody = csepart.substring(1, csepart.length() - 1);
- //System.out.printf("\t\tTRACE: special body is '%s'\n", specialBody);
-
if (specialBody.matches("\\S+:=\\S+")) {
String[] parts = specialBody.split(":=");
if(parts.length != 2) {
@@ -99,7 +98,7 @@ public abstract class CaseElement {
} else {
throw new IllegalArgumentException(String.format("Unknown special case part '%s'", specialBody));
}
- } else if (csepart.matches("\\[[^\\]]+\\]")) {
+ } else if (csepart.matches("\\[\\S+\\]")) {
String rawCase = csepart.substring(1, csepart.length() - 1);
if (rawCase.matches("\\d+\\.\\.\\d+")) {
@@ -107,23 +106,17 @@ public abstract class CaseElement {
int secondNum = Integer.parseInt(rawCase.substring(rawCase.lastIndexOf('.') + 1));
return new RangeCaseElement(firstNum, secondNum);
- } else if(rawCase.contains("|")) {
- String[] elms = rawCase.split("\\|");
+ } else if(rawCase.contains("||")) {
+ String[] elms = StringUtils.levelSplit(rawCase, "||").toArray(new String[0]);
+ //String[] elms = rawCase.split("\\|\\|");
- System.err.printf("\t\tTRACE: Split inline cases %s to ", rawCase);
- for(String elm : elms) {
- System.err.printf("%s, ", elm);
- }
- System.err.println();
+ return new InlineRuleCaseElement(elms);
+ } else if(rawCase.contains("|")) {
+ System.err.println("\t\tWARN: Inline rule using | found, they use || now");
+ String[] elms = StringUtils.levelSplit(rawCase, "|").toArray(new String[0]);
return new InlineRuleCaseElement(elms);
} else if(csepart.contains("$")) {
- /*
- * @NOTE
- *
- * Once the rule element execution has been refactored,
- * pass rawCase instead.
- */
if(csepart.contains("-")) {
return new DependantRuleReference(csepart);
}
@@ -135,7 +128,7 @@ public abstract class CaseElement {
} else {
return new NormalRuleReference(csepart);
}
- } else if(csepart.startsWith("%")) {
+ } else if(csepart.startsWith("%") && !csepart.equals("%")) {
String rName = String.format("[%s]", csepart.substring(1));
System.err.printf("\t\tTRACE: short ref to %s (%s)\n", rName, csepart);
@@ -150,7 +143,7 @@ public abstract class CaseElement {
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((type == null) ? 0 : type.hashCode());
+ result = prime * result + (spacing ? 0 : 2);
return result;
}
@@ -163,7 +156,7 @@ public abstract class CaseElement {
if (getClass() != obj.getClass())
return false;
CaseElement other = (CaseElement) obj;
- if (type != other.type)
+ if (spacing != other.spacing)
return false;
return true;
}
diff --git a/src/main/java/bjc/rgens/parser/elements/ChanceCaseElement.java b/src/main/java/bjc/rgens/parser/elements/ChanceCaseElement.java
new file mode 100644
index 0000000..483a103
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/ChanceCaseElement.java
@@ -0,0 +1,20 @@
+package bjc.rgens.parser.elements;
+
+import bjc.rgens.parser.GenerationState;
+
+public class ChanceCaseElement extends CaseElement {
+ public final CaseElement elm;
+
+ public int chance;
+
+ public ChanceCaseElement(CaseElement elm, int chance) {
+ super(elm.spacing);
+
+ this.elm = elm;
+ this.chance = chance;
+ }
+
+ public void generate(GenerationState state) {
+ if(state.rnd.nextInt(chance) == 0) elm.generate(state);
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java
index 3972e7a..198b0db 100755
--- a/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java
@@ -23,16 +23,12 @@ public class ExpVariableCaseElement extends VariableCaseElement {
if(rl != null) {
RGrammar destGrammar = rl.belongsTo;
newState.swapGrammar(destGrammar);
- String res = destGrammar.generate(varDef, state);
-
- /*
- * @NOTE
- *
- * :Postprocessing
- *
- * This is because generate() returns a processed
- * string, but modifies the passed in StringBuilder.
+ /*
+ * Don't post-process the string, we should only do that
+ * once.
*/
+ String res = destGrammar.generate(varDef, state, false);
+
newState.contents = new StringBuilder(res);
} else {
String msg = String.format("No rule '%s' defined", varDef);
diff --git a/src/main/java/bjc/rgens/parser/elements/InlineRuleCaseElement.java b/src/main/java/bjc/rgens/parser/elements/InlineRuleCaseElement.java
index 6cb0ce3..ea22bb4 100644
--- a/src/main/java/bjc/rgens/parser/elements/InlineRuleCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/InlineRuleCaseElement.java
@@ -3,23 +3,38 @@ package bjc.rgens.parser.elements;
import bjc.rgens.parser.GenerationState;
import bjc.rgens.parser.RGrammarParser;
+import bjc.utils.data.IPair;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.IList;
+import bjc.utils.gen.WeightedRandom;
public class InlineRuleCaseElement extends CaseElement {
- public final IList<CaseElement> elements;
+ public final WeightedRandom<CaseElement> elements;
- public InlineRuleCaseElement(String... elements) {
- this(RGrammarParser.parseElementString(elements).getLeft());
- }
+ public InlineRuleCaseElement(String... parts) {
+ super(true);
+
+ this.elements = new WeightedRandom<>();
+
+ for(String part : parts) {
+ String[] partArr;
+
+ if(part.contains("|")) {
+ partArr = part.split("\\|");
+ } else {
+ partArr = new String[] {part};
+ }
- public InlineRuleCaseElement(IList<CaseElement> elements) {
- super(ElementType.RULEREF);
+ IPair<IList<CaseElement>, Integer> par = RGrammarParser.parseElementString(partArr);
+ int prob = par.getRight();
- this.elements = elements;
+ for(CaseElement elm :par.getLeft()) {
+ elements.addProbability(prob, elm);
+ }
+ }
}
public void generate(GenerationState state) {
- elements.randItem(state.rnd::nextInt).generate(state);
+ elements.generateValue(state.rnd).generate(state);
}
}
diff --git a/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java b/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java
index cf8f161..e877dd1 100755
--- a/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java
@@ -7,7 +7,7 @@ public class RangeCaseElement extends CaseElement {
public final int end;
public RangeCaseElement(int beg, int en) {
- super(ElementType.RANGE);
+ super(true);
begin = beg;
end = en;
diff --git a/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java b/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java
index e0c847a..6aa50fc 100755
--- a/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java
@@ -39,16 +39,11 @@ public abstract class RuleCaseElement extends StringCaseElement {
if(rl != null) {
RGrammar destGrammar = rl.belongsTo;
newState.swapGrammar(destGrammar);
- String res = destGrammar.generate(actName, newState);
-
- /*
- * @NOTE
- *
- * :Postprocessing
- *
- * This is because generate() returns a processed
- * string, but modifies the passed in StringBuilder.
+ /*
+ * Don't postprocess the string, we should only do that
+ * once.
*/
+ String res = destGrammar.generate(actName, newState, false);
newState.contents = new StringBuilder(res);
} else {
/*
diff --git a/src/main/java/bjc/rgens/parser/elements/SerialCaseElement.java b/src/main/java/bjc/rgens/parser/elements/SerialCaseElement.java
index 594595e..348cfbb 100644
--- a/src/main/java/bjc/rgens/parser/elements/SerialCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/SerialCaseElement.java
@@ -9,7 +9,7 @@ public class SerialCaseElement extends CaseElement {
public final int upper;
public SerialCaseElement(CaseElement rep, int lower, int upper) {
- super(rep.type);
+ super(rep.spacing);
this.rep = rep;
@@ -23,7 +23,7 @@ public class SerialCaseElement extends CaseElement {
for(int i = 0; i < num; i++) {
rep.generate(state);
- if(rep.type.spacing)
+ if(rep.spacing)
state.contents.append(" ");
}
}
diff --git a/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java b/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java
index 61ad48a..57e2cc7 100755
--- a/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java
@@ -4,7 +4,7 @@ public abstract class StringCaseElement extends CaseElement {
public final String val;
protected StringCaseElement(String vl, boolean isLiteral) {
- super(isLiteral ? ElementType.LITERAL : ElementType.RULEREF);
+ super(true);
val = vl;
}
diff --git a/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java
index a2c15a7..63701e0 100755
--- a/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java
@@ -21,7 +21,7 @@ public abstract class VariableCaseElement extends CaseElement {
public final VariableType varType;
public VariableCaseElement(String name, String def, VariableType varType) {
- super(ElementType.VARIABLE);
+ super(false);
varName = name;
varDef = def;
@@ -60,15 +60,6 @@ public abstract class VariableCaseElement extends CaseElement {
return true;
}
- @Override
- public String toString() {
- if (type == ElementType.VARIABLE) {
- return String.format("{$%s:=%s}", varName, varDef);
- } else {
- return String.format("{$%s=%s}", varName, varDef);
- }
- }
-
public static CaseElement parseVariable(String varName, String varDef, boolean colon) {
if(varName.startsWith("$")) {
// Handle normal/expanding variable definitions
diff --git a/src/main/java/bjc/rgens/parser/elements/vars/ARefVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/ARefVariableElement.java
new file mode 100644
index 0000000..7a8910c
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/vars/ARefVariableElement.java
@@ -0,0 +1,35 @@
+package bjc.rgens.parser.elements.vars;
+
+import bjc.rgens.parser.GenerationState;
+import bjc.rgens.parser.GrammarException;
+import bjc.rgens.parser.Rule;
+
+public class ARefVariableElement extends VariableElement {
+ public String value;
+
+ private boolean forbidSpaces;
+
+ public ARefVariableElement(boolean forbidSpaces, String val) {
+ value = val;
+ }
+
+ public void generate(GenerationState state) {
+ if(!state.rlVars.containsKey(value)) {
+ throw new GrammarException("No rule variable named " + value);
+ }
+
+ Rule rl = state.rlVars.get(value);
+
+ GenerationState newState = state.newBuf();
+
+ rl.generate(newState);
+
+ String res = newState.contents.toString();
+
+ if(forbidSpaces && res.contains(" ")) {
+ throw new GrammarException("Spaces not allowed in this context (rule-var %s)");
+ }
+
+ state.contents.append(res);
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/vars/LiteralVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/LiteralVariableElement.java
new file mode 100644
index 0000000..080f849
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/vars/LiteralVariableElement.java
@@ -0,0 +1,15 @@
+package bjc.rgens.parser.elements.vars;
+
+import bjc.rgens.parser.GenerationState;
+
+public class LiteralVariableElement extends VariableElement {
+ public String val;
+
+ public LiteralVariableElement(String val) {
+ this.val = val;
+ }
+
+ public void generate(GenerationState state) {
+ state.contents.append(val);
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java
new file mode 100644
index 0000000..6bf332f
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java
@@ -0,0 +1,35 @@
+package bjc.rgens.parser.elements.vars;
+
+import bjc.rgens.parser.GenerationState;
+import bjc.rgens.parser.GrammarException;
+import bjc.rgens.parser.Rule;
+
+public class RRefVariableElement extends VariableElement {
+ public String value;
+
+ private boolean forbidSpaces;
+
+ public RRefVariableElement(boolean forbidSpaces, String val) {
+ value = val;
+ }
+
+ public void generate(GenerationState state) {
+ if(!state.rlVars.containsKey(value)) {
+ throw new GrammarException("No rule variable named " + value);
+ }
+
+ Rule rl = state.findRule(value, true);
+
+ GenerationState newState = state.newBuf();
+
+ rl.generate(newState);
+
+ String res = newState.contents.toString();
+
+ if(forbidSpaces && res.contains(" ")) {
+ throw new GrammarException("Spaces not allowed in this context (rule-reference %s)");
+ }
+
+ state.contents.append(res);
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/vars/TRefVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/TRefVariableElement.java
new file mode 100644
index 0000000..b10af87
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/vars/TRefVariableElement.java
@@ -0,0 +1,43 @@
+package bjc.rgens.parser.elements.vars;
+
+import bjc.rgens.parser.GenerationState;
+import bjc.rgens.parser.GrammarException;
+import bjc.rgens.parser.templates.GrammarTemplate;
+
+/*
+ * @TODO
+ *
+ * finish when template vars are implemented.
+ */
+public class TRefVariableElement extends VariableElement {
+ /*
+ public String value;
+
+ private boolean forbidSpaces;
+
+ public TRefVariableElement(boolean forbidSpaces, String val) {
+ value = val;
+ }*/
+
+ public void generate(GenerationState state) {
+ /*
+ if(!state.rlVars.containsKey(val)) {
+ throw new GrammarException("No rule variable named " + val);
+ }
+
+ Rule rl = state.rlVars.get(val);
+
+ GenerationState newState = state.newBuf();
+
+ rl.generate(newState);
+
+ String res = newState.contents.toString();
+
+ if(forbidSpaces && res.contains(" ")) {
+ throw new GrammarException("Spaces not allowed in this context (rule-var %s)");
+ }
+
+ return res;
+ */
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/vars/VRefVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/VRefVariableElement.java
new file mode 100644
index 0000000..c6921ba
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/vars/VRefVariableElement.java
@@ -0,0 +1,29 @@
+package bjc.rgens.parser.elements.vars;
+
+import bjc.rgens.parser.GenerationState;
+import bjc.rgens.parser.GrammarException;
+
+public class VRefVariableElement extends VariableElement {
+ public final String nam;
+
+ private final boolean forbidSpaces;
+
+ public VRefVariableElement(boolean forbidSpaces, String nam) {
+ this.nam = nam;
+
+ this.forbidSpaces = forbidSpaces;
+ }
+
+ public void generate(GenerationState state) {
+ if (!state.vars.containsKey(nam)) {
+ throw new GrammarException(String.format("No variable '%s' defined", nam));
+ }
+
+ String strang = state.vars.get(nam);
+ if(forbidSpaces && strang.contains(" ")) {
+ throw new GrammarException(String.format("Cannot include variable %s w/ spaces in body in rule name", nam));
+ }
+
+ state.contents.append(strang);
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java
new file mode 100644
index 0000000..7a4260f
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java
@@ -0,0 +1,59 @@
+package bjc.rgens.parser.elements.vars;
+
+import bjc.rgens.parser.GenerationState;
+import bjc.rgens.parser.GrammarException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class VariableElement {
+ public abstract void generate(GenerationState state);
+
+ public static List<VariableElement> parseVariableElements(String varElm) {
+ boolean forbidSpaces = varElm.contains("-");
+
+ String[] parts;
+
+ if(forbidSpaces) {
+ parts = varElm.split("(?<=[+-])|(?=[+-])");
+ } else {
+ parts = new String[] { varElm };
+ }
+
+ return parseVariableElements(forbidSpaces, parts);
+ }
+
+ public static List<VariableElement> parseVariableElements(boolean forbidSpaces, String... parts) {
+ List<VariableElement> elms = new ArrayList<>(parts.length);
+
+ VariableElement prevElement = null;
+
+ for (String part : parts) {
+ VariableElement elm = null;
+
+ if(part.startsWith("$")) {
+ elm = new VRefVariableElement(forbidSpaces, part.substring(1));
+ } else if (part.startsWith("@")) {
+ elm = new ARefVariableElement(forbidSpaces, part.substring(1));
+ } else if (part.startsWith("%")) {
+ elm = new RRefVariableElement(forbidSpaces, part.substring(1));
+ } else if (part.startsWith("/")) {
+ throw new GrammarException("Template variables aren't implemented yet");
+ } else {
+ if(prevElement instanceof LiteralVariableElement) {
+ /* Aggregate chain literals together */
+ ((LiteralVariableElement)prevElement).val += elm;
+ } else {
+ elm = new LiteralVariableElement(part);
+ }
+ }
+
+ if(elm != null) {
+ elms.add(elm);
+ prevElement = elm;
+ }
+ }
+
+ return elms;
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/templates/GrammarTemplate.java b/src/main/java/bjc/rgens/parser/templates/GrammarTemplate.java
index a257fbd..fa634a5 100644
--- a/src/main/java/bjc/rgens/parser/templates/GrammarTemplate.java
+++ b/src/main/java/bjc/rgens/parser/templates/GrammarTemplate.java
@@ -25,7 +25,7 @@ public class GrammarTemplate {
for(TemplateElement element : elements) {
element.generate(state);
- if(doSpacing && element.type.spacing)
+ if(doSpacing && element.spacing)
state.contents.append("\n");
}
}
diff --git a/src/main/java/bjc/rgens/parser/templates/LiteralTemplateElement.java b/src/main/java/bjc/rgens/parser/templates/LiteralTemplateElement.java
index 19ebbc2..36cdb12 100644
--- a/src/main/java/bjc/rgens/parser/templates/LiteralTemplateElement.java
+++ b/src/main/java/bjc/rgens/parser/templates/LiteralTemplateElement.java
@@ -6,7 +6,7 @@ public class LiteralTemplateElement extends TemplateElement {
public final String val;
public LiteralTemplateElement(String val) {
- super(ElementType.LITERAL);
+ super(true);
this.val = val;
}
diff --git a/src/main/java/bjc/rgens/parser/templates/LiveTemplateElement.java b/src/main/java/bjc/rgens/parser/templates/LiveTemplateElement.java
index 2487c83..154ea68 100644
--- a/src/main/java/bjc/rgens/parser/templates/LiveTemplateElement.java
+++ b/src/main/java/bjc/rgens/parser/templates/LiveTemplateElement.java
@@ -20,7 +20,7 @@ public class LiveTemplateElement extends TemplateElement {
public final List<List<CaseElement>> elements;
public LiveTemplateElement(String val) {
- super(ElementType.TEMPLATE);
+ super(true);
elements = new ArrayList<>();
@@ -52,7 +52,7 @@ public class LiveTemplateElement extends TemplateElement {
for(CaseElement elm : elmList) {
elm.generate(state);
- if(doSpacing && elm.type.spacing)
+ if(doSpacing && elm.spacing)
state.contents.append(" ");
}
}
diff --git a/src/main/java/bjc/rgens/parser/templates/TemplateElement.java b/src/main/java/bjc/rgens/parser/templates/TemplateElement.java
index dc123f3..2d0724b 100644
--- a/src/main/java/bjc/rgens/parser/templates/TemplateElement.java
+++ b/src/main/java/bjc/rgens/parser/templates/TemplateElement.java
@@ -3,24 +3,12 @@ package bjc.rgens.parser.templates;
import bjc.rgens.parser.GenerationState;
public abstract class TemplateElement {
- public static enum ElementType {
- LITERAL(true),
- TEMPLATE(true),
- PRAGMA(false);
-
- public final boolean spacing;
-
- private ElementType(boolean spacing) {
- this.spacing = spacing;
- }
- }
-
- public final ElementType type;
+ public boolean spacing;
public GrammarTemplate belongsTo;
- protected TemplateElement(ElementType type) {
- this.type = type;
+ protected TemplateElement(boolean spacing) {
+ this.spacing = spacing;
}
public abstract void generate(GenerationState state);