summaryrefslogtreecommitdiff
path: root/src/main/java/bjc
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2018-10-30 05:12:54 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2018-10-30 05:12:54 -0400
commite3bc4bcf923665555aa587a82a7eba803799e423 (patch)
tree37909d39716fe46fcb0269fefb3ca0017fdbf3f7 /src/main/java/bjc
parent112a000e535ad26fe792655e5c0ad42d5cad78cc (diff)
Finish directive sequencing
Diffstat (limited to 'src/main/java/bjc')
-rw-r--r--src/main/java/bjc/inflexion/InflectionString.java75
-rw-r--r--src/main/java/bjc/inflexion/QueuedIterator.java171
2 files changed, 220 insertions, 26 deletions
diff --git a/src/main/java/bjc/inflexion/InflectionString.java b/src/main/java/bjc/inflexion/InflectionString.java
index 8b47b8e..4bb024a 100644
--- a/src/main/java/bjc/inflexion/InflectionString.java
+++ b/src/main/java/bjc/inflexion/InflectionString.java
@@ -18,6 +18,7 @@ import static bjc.inflexion.InflectionString.InflectionDirective.literal;
import static bjc.inflexion.InflectionString.InflectionDirective.noun;
import static bjc.inflexion.InflectionString.InflectionDirective.numeric;
import static bjc.inflexion.InflectionString.InflectionDirective.variable;
+import static java.util.Arrays.asList;
import java.util.ArrayList;
import java.util.HashMap;
@@ -426,7 +427,7 @@ public class InflectionString {
* The directives contained in a sequence.
*/
public List<InflectionDirective> listDir;
-
+
/**
* Create a new inflection directive.
*
@@ -489,14 +490,14 @@ public class InflectionString {
}
}
-
+
/**
* Create a new inflection directive.
*
* @param type
* The type of the directive.
- * @param num
- * The number value for the directive.
+ * @param listDir
+ * The directive list value for the directive.
*/
public InflectionDirective(DirectiveType type, List<InflectionDirective> listDir) {
this.type = type;
@@ -507,7 +508,8 @@ public class InflectionString {
break;
default:
throw new IllegalArgumentException(
- "Unhandled or wrong arguments (1 list of directives) for directive type " + type);
+ "Unhandled or wrong arguments (1 list of directives) for directive type "
+ + type);
}
}
@@ -572,14 +574,28 @@ public class InflectionString {
return new InflectionDirective(DirectiveType.NOUN, strang);
}
+ /**
+ * Create a sequenced set of directives.
+ *
+ * @param list
+ * The directives to sequence.
+ * @return A sequence directive.
+ */
public static InflectionDirective seq(List<InflectionDirective> list) {
- return new InflectionDirective(DirectiveType.SEQ, list);
+ return new InflectionDirective(DirectiveType.SEQ, list);
}
-
- public static InflectionDirective seq(InflectionDirective arr) {
- return new InflectionDirective(DirectiveType.SEQ, Arrays.asList(arr));
+
+ /**
+ * Create a sequenced set of directives.
+ *
+ * @param arr
+ * The directives to sequence.
+ * @return A sequence directive.
+ */
+ public static InflectionDirective seq(InflectionDirective... arr) {
+ return new InflectionDirective(DirectiveType.SEQ, asList(arr));
}
-
+
/**
* Set the numeric options for this directive.
*
@@ -631,7 +647,7 @@ public class InflectionString {
* String we were formed from.
*/
private String rawString;
-
+
/**
* Create a new empty inflection string.
*/
@@ -649,7 +665,7 @@ public class InflectionString {
this();
rawString = inp;
-
+
int curPos = 0;
List<String> parseErrors = new ArrayList<>();
@@ -769,8 +785,10 @@ public class InflectionString {
boolean pendingAn = false;
List<String> anVals = new ArrayList<>();
-
- for (InflectionDirective dir : dirs) {
+
+ QueuedIterator<InflectionDirective> itrDirs = new QueuedIterator<>(dirs);
+ Iterable<InflectionDirective> itrb = () -> itrDirs;
+ for (InflectionDirective dir : itrb) {
switch (dir.type) {
case LITERAL:
sb.append(dir.litString);
@@ -784,8 +802,8 @@ public class InflectionString {
throw new IllegalArgumentException("Unbound variable " + vName);
}
- break;
}
+ break;
case NUMERIC: {
int actNum;
@@ -816,7 +834,7 @@ public class InflectionString {
}
if (opts.zeroNo && curNum == 0) rep = "no";
-
+
if (opts.article && curNum == 1) {
anNum += 1;
rep = "{an" + anNum + "}";
@@ -861,11 +879,11 @@ public class InflectionString {
sb.append(rep);
}
- break;
}
+ break;
case NOUN: {
String actNoun;
-
+
if (dir.isVRef) {
Object val = vars.get(dir.litString);
@@ -877,7 +895,7 @@ public class InflectionString {
} else {
actNoun = dir.litString;
}
-
+
final Noun noun = nounDB.getNoun(actNoun);
String nounVal;
@@ -900,29 +918,34 @@ public class InflectionString {
}
}
break;
+ case SEQ:
+ itrDirs.before(dir.listDir);
+ break;
default:
throw new IllegalArgumentException("Unhandled directive type " + dir.type);
}
}
String res = sb.toString();
-
+
StringBuffer work = new StringBuffer();
-
+
Matcher anMat = AN_MARKER.matcher(res);
-
+
Iterator<String> anItr = anVals.iterator();
while (anMat.find()) {
anMat.appendReplacement(work, anItr.next());
}
anMat.appendTail(work);
-
+
return work.toString();
}
-
+
@Override
public String toString() {
- if (rawString != null) return rawString;
- else return super.toString();
+ if (rawString != null)
+ return rawString;
+ else
+ return super.toString();
}
}
diff --git a/src/main/java/bjc/inflexion/QueuedIterator.java b/src/main/java/bjc/inflexion/QueuedIterator.java
new file mode 100644
index 0000000..cbc9a00
--- /dev/null
+++ b/src/main/java/bjc/inflexion/QueuedIterator.java
@@ -0,0 +1,171 @@
+package bjc.inflexion;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
+
+/**
+ * An iterator that supports queuing elements after/before the current iterator;
+ *
+ * @author bjculkin
+ *
+ * @param <E>
+ */
+public class QueuedIterator<E> implements Iterator<E> {
+ private Iterator<E> cur;
+
+ private Deque<Iterator<E>> pending;
+
+ /**
+ * Static method for constructing iterators.
+ *
+ * @return A queued iterator.
+ */
+ public static <E> QueuedIterator<E> queued() {
+ return new QueuedIterator<>();
+ }
+
+ /**
+ * Static method for constructing iterators.
+ *
+ * @param itrs
+ * The iterators to use.
+ * @return A queued iterator over the provided iterators.
+ */
+ @SafeVarargs
+ public static <E> QueuedIterator<E> queued(Iterator<E>... itrs) {
+ return new QueuedIterator<>(itrs);
+ }
+
+ /**
+ * Static method for constructing iterators.
+ *
+ * @param itrs
+ * The iterables to use.
+ * @return A queued iterator over the provided iterables.
+ */
+ @SafeVarargs
+ public static <E> QueuedIterator<E> queued(Iterable<E>... itrs) {
+ return new QueuedIterator<>(itrs);
+ }
+
+ /**
+ * Create a new queued iterator that starts blank.
+ */
+ public QueuedIterator() {
+ pending = new ArrayDeque<>();
+ }
+
+ /**
+ * Create a new queued iterator with a set of initial sources.
+ *
+ * @param inits
+ * The set of initial iterators to use.
+ */
+ @SafeVarargs
+ public QueuedIterator(Iterator<E>... inits) {
+ this();
+
+ for (Iterator<E> init : inits) {
+ pending.add(init);
+ }
+ }
+
+ /**
+ * Create a new queued iterator with a set of initial sources.
+ *
+ * @param inits
+ * The set of initial iterables to use.
+ */
+ @SafeVarargs
+ public QueuedIterator(Iterable<E>... inits) {
+ this();
+
+ for (Iterable<E> init : inits) {
+ pending.add(init.iterator());
+ }
+ }
+
+ /**
+ * Add a new iterator who we will iterate through first.
+ *
+ * @param itr
+ * The iterator to go through first.
+ */
+ public void before(Iterator<E> itr) {
+ pending.push(cur);
+
+ cur = itr;
+ }
+
+ /**
+ * Add a new iterable who we will iterate through first.
+ *
+ * @param itr
+ * The iterable to go through first.
+ */
+ public void before(Iterable<E> itr) {
+ before(itr.iterator());
+ }
+
+ /**
+ * Add a new iterator who we will iterate through next.
+ *
+ * @param itr
+ * The iterator to go through next.
+ */
+ public void after(Iterator<E> itr) {
+ pending.push(itr);
+ }
+ /**
+ * Add a new iterable who we will iterate through next.
+ *
+ * @param itr
+ * The iterable to go through next.
+ */
+ public void after(Iterable<E> itr) {
+ after(itr.iterator());
+ }
+
+ /**
+ * Add a new iterator who we will iterate through last.
+ *
+ * @param itr
+ * The iterator to go through last.
+ */
+ public void last(Iterator<E> itr) {
+ pending.add(itr);
+ }
+
+ /**
+ * Add a new iterable who we will iterate through last.
+ *
+ * @param itr
+ * The iterable to go through last.
+ */
+ public void last(Iterable<E> itr) {
+ last(itr.iterator());
+ }
+ @Override
+ public boolean hasNext() {
+ while (cur == null || !cur.hasNext()) {
+ if (pending.isEmpty()) return false;
+
+ cur = pending.pop();
+ }
+
+ return cur.hasNext();
+ }
+
+ @Override
+ public E next() {
+ while (cur == null || !cur.hasNext()) {
+ if (pending.isEmpty()) return null;
+
+ cur = pending.pop();
+ }
+
+ return cur.next();
+ }
+
+}