diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2018-10-30 05:12:54 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2018-10-30 05:12:54 -0400 |
| commit | e3bc4bcf923665555aa587a82a7eba803799e423 (patch) | |
| tree | 37909d39716fe46fcb0269fefb3ca0017fdbf3f7 | |
| parent | 112a000e535ad26fe792655e5c0ad42d5cad78cc (diff) | |
Finish directive sequencing
| -rw-r--r-- | src/main/java/bjc/inflexion/InflectionString.java | 75 | ||||
| -rw-r--r-- | src/main/java/bjc/inflexion/QueuedIterator.java | 171 |
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(); + } + +} |
