summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/rgens/parser/elements/CaseElement.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/bjc/rgens/parser/elements/CaseElement.java')
-rwxr-xr-x[-rw-r--r--]src/main/java/bjc/rgens/parser/elements/CaseElement.java143
1 files changed, 85 insertions, 58 deletions
diff --git a/src/main/java/bjc/rgens/parser/elements/CaseElement.java b/src/main/java/bjc/rgens/parser/elements/CaseElement.java
index d74ab52..a44ef6c 100644..100755
--- a/src/main/java/bjc/rgens/parser/elements/CaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/CaseElement.java
@@ -1,17 +1,16 @@
package bjc.rgens.parser.elements;
+import bjc.utils.funcutils.StringUtils;
+
+import bjc.rgens.parser.GenerationState;
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 {
+public abstract class CaseElement {
/**
* The possible types of an element.
*
@@ -19,27 +18,27 @@ public class CaseElement {
*/
public static enum ElementType {
/** An element that represents a literal string. */
- LITERAL,
+ LITERAL(true),
/** An element that represents a rule reference. */
- RULEREF,
+ RULEREF(true),
/** An element that represents a random range. */
- RANGE,
+ RANGE(true),
/** 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;
- }
+ VARIABLE(false);
- /* 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+\\]";
+ public final boolean spacing;
+
+ private ElementType(boolean spacing) {
+ this.spacing = spacing;
+ }
+ }
/** The type of this element. */
- public final ElementType type;
+ public boolean spacing;
+
+ protected CaseElement() {
+ this(true);
+ }
/**
* Create a new case element.
@@ -47,17 +46,17 @@ public class CaseElement {
* @param typ
* The type of this element.
*/
- protected CaseElement(ElementType typ) {
- type = typ;
+ protected CaseElement(boolean spacing) {
+ this.spacing = spacing;
}
- @Override
- public String toString() {
- switch (type) {
- default:
- return String.format("Unknown type '%s'", type);
- }
- }
+ /**
+ * Generate this case element.
+ *
+ * @param state
+ * The current state of generation.
+ */
+ public abstract void generate(GenerationState state);
/**
* Create a case element from a string.
@@ -72,52 +71,80 @@ public class CaseElement {
throw new NullPointerException("Case part cannot be null");
}
- if (csepart.matches(SPECIAL_CASELEM)) {
- /* Handle special cases. */
+ if (csepart.matches("\\(\\S+\\)")) {
+ return createElement(csepart.substring(1, csepart.length() - 1));
+ } else 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=\\S+")) {
+ String[] parts = StringUtils.levelSplit(specialBody, "=").toArray(new String[0]);
- if (specialBody.matches("\\S+:=\\S+")) {
- /* Handle expanding variable definitions. */
- String[] parts = specialBody.split(":=");
+ if(parts.length != 2) {
+ throw new GrammarException("Colon variables must have a name and a definition");
+ }
+
+ String varName = parts[0];
+
+ char op = varName.charAt(varName.length() - 1);
+
+ System.err.printf("\t\tTRACE: Colon definition w/ op %d", (int)op);
- if (parts.length != 2) {
- String msg = "Expanded variables must be a name and a definition, seperated by :=";
+ // Remove the colon, plus any tacked on operator
+ varName = varName.substring(0, varName.length() - 2);
- throw new GrammarException(msg);
+ return VariableDefCaseElement.parseVariable(varName, parts[1], op, true);
+ } else if (specialBody.matches("\\S+:=\\S+")) {
+ String[] parts = StringUtils.levelSplit(specialBody, "=").toArray(new String[0]);
+
+ if(parts.length != 2) {
+ throw new GrammarException("Colon variables must have a name and a definition");
}
- return new ExpVariableCaseElement(parts[0], parts[1]);
- } else if (specialBody.matches("\\S+=\\S+")) {
- /* Handle regular variable definitions. */
- String[] parts = specialBody.split("=");
+ String varName = parts[0];
- if (parts.length != 2) {
- String msg = "Variables must be a name and a definition, seperated by =";
+ varName = varName.substring(0, varName.length() - 1);
- throw new GrammarException(msg);
+ return VariableDefCaseElement.parseVariable(varName, parts[1], ' ', true);
+ } else if (specialBody.matches("\\S+=\\S+")) {
+ String[] parts = specialBody.split("=");
+ if(parts.length != 2) {
+ throw new GrammarException("Variables must have a name and a definition");
}
- return new LitVariableCaseElement(parts[0], parts[1]);
- } else if (specialBody.matches("{empty}")) {
+ // Non-colon variables can't take an operator
+ return VariableDefCaseElement.parseVariable(parts[0], parts[1], (char)0, false);
+ } 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);
+ } else if (csepart.matches("\\[\\S+\\]")) {
+ String rawCase = csepart.substring(1, csepart.length() - 1);
- int firstNum = Integer.parseInt(rawRange.substring(0, rawRange.indexOf('.')));
- int secondNum = Integer.parseInt(rawRange.substring(rawRange.lastIndexOf('.') + 1));
+ if (rawCase.matches("\\d+\\.{2}\\d+")) {
+ int firstNum = Integer.parseInt(rawCase.substring(0, rawCase.indexOf('.')));
+ int secondNum = Integer.parseInt(rawCase.substring(rawCase.lastIndexOf('.') + 1));
return new RangeCaseElement(firstNum, secondNum);
- }
+ } else if(rawCase.contains("||")) {
+ String[] elms = StringUtils.levelSplit(rawCase, "||").toArray(new String[0]);
- return new RuleCaseElement(csepart);
+ return new InlineRuleCaseElement(elms);
+ } else if(rawCase.contains("|")) {
+ throw new GrammarException("\t\tERROR: Inline rule using | found, they use || now");
+
+ // String[] elms = StringUtils.levelSplit(rawCase, "|").toArray(new String[0]);
+ // return new InlineRuleCaseElement(elms);
+ } else {
+ return new RuleCaseElement(rawCase);
+ }
+ } else if(csepart.startsWith("%") && !csepart.equals("%")) {
+ return new RuleCaseElement(csepart);
} else {
return new LiteralCaseElement(csepart);
}
@@ -127,7 +154,7 @@ public 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;
}
@@ -140,8 +167,8 @@ public class CaseElement {
if (getClass() != obj.getClass())
return false;
CaseElement other = (CaseElement) obj;
- if (type != other.type)
+ if (spacing != other.spacing)
return false;
return true;
}
-} \ No newline at end of file
+}