summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/rgens/parser/elements
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/bjc/rgens/parser/elements')
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/BlankCaseElement.java7
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/CaseElement.java147
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java7
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java7
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java7
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/RangeCaseElement.java43
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/RuleCaseElement.java7
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/StringCaseElement.java41
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/VariableCaseElement.java60
9 files changed, 326 insertions, 0 deletions
diff --git a/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java b/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java
new file mode 100755
index 0000000..7229e92
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java
@@ -0,0 +1,7 @@
+package bjc.rgens.parser.elements;
+
+public class BlankCaseElement extends LiteralCaseElement {
+ public BlankCaseElement() {
+ super("");
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/CaseElement.java b/src/main/java/bjc/rgens/parser/elements/CaseElement.java
new file mode 100755
index 0000000..d74ab52
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/CaseElement.java
@@ -0,0 +1,147 @@
+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/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java
new file mode 100755
index 0000000..30925e2
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java
@@ -0,0 +1,7 @@
+package bjc.rgens.parser.elements;
+
+public class ExpVariableCaseElement extends VariableCaseElement {
+ public ExpVariableCaseElement(String name, String def) {
+ super(name, def, true);
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java
new file mode 100755
index 0000000..11035b1
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java
@@ -0,0 +1,7 @@
+package bjc.rgens.parser.elements;
+
+public class LitVariableCaseElement extends VariableCaseElement {
+ public LitVariableCaseElement(String name, String def) {
+ super(name, def, false);
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java b/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java
new file mode 100755
index 0000000..d96a32d
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java
@@ -0,0 +1,7 @@
+package bjc.rgens.parser.elements;
+
+public class LiteralCaseElement extends StringCaseElement {
+ public LiteralCaseElement(String vl) {
+ super(vl, true);
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java b/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java
new file mode 100755
index 0000000..d98bc61
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/RangeCaseElement.java
@@ -0,0 +1,43 @@
+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/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java b/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java
new file mode 100755
index 0000000..f4d3512
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java
@@ -0,0 +1,7 @@
+package bjc.rgens.parser.elements;
+
+public class RuleCaseElement extends StringCaseElement {
+ public RuleCaseElement(String vl) {
+ super(vl, false);
+ }
+}
diff --git a/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java b/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java
new file mode 100755
index 0000000..0e64fd3
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java
@@ -0,0 +1,41 @@
+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/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java
new file mode 100755
index 0000000..920445a
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java
@@ -0,0 +1,60 @@
+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);
+ }
+ }
+}