summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-04-11 09:32:59 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-04-11 09:32:59 -0400
commitf9283a20abd9eaed0b0436bc54c60576233121f4 (patch)
treecec1323fb3faf1a4dcee2394a114b821c2366166 /BJC-Utils2/src
parent275a627719fc2231b16caea41130ff09f0f2b6a1 (diff)
Added new method to pairs and holders
Diffstat (limited to 'BJC-Utils2/src')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/GenHolder.java5
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java11
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/IPair.java18
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/Pair.java6
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java93
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java19
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java20
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java19
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java22
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java62
10 files changed, 221 insertions, 54 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/GenHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/GenHolder.java
index e042554..bd87f07 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/GenHolder.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/GenHolder.java
@@ -105,4 +105,9 @@ public class GenHolder<T> implements IHolder<T> {
return heldValue.toString();
}
+
+ @Override
+ public <E> IHolder<E> bind(Function<T, IHolder<E>> binder) {
+ return binder.apply(heldValue);
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java
index 6290d5f..a4f4013 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java
@@ -56,4 +56,15 @@ public interface IHolder<T> {
* @return The mapped value outside of a GenHolder
*/
public <E> E unwrap(Function<T, E> unwrapper);
+
+ /**
+ * Bind the value in this holder to a new value
+ *
+ * @param <E>
+ * The new type of the held value
+ * @param binder
+ * The function to do the binding with
+ * @return The bound value
+ */
+ public <E> IHolder<E> bind(Function<T, IHolder<E>> binder);
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java
index e2ee6a4..a20ff36 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java
@@ -14,7 +14,7 @@ import java.util.function.Function;
* @param <R>
* The type stored in the right side of the pair
*/
-public interface IPair<L, R> {
+public interface IPair<L, R> {
/**
* Create a new pair by applying the given functions to the left/right.
@@ -35,6 +35,22 @@ public interface IPair<L, R> {
Function<R, R2> rightTransformer);
/**
+ * Apply a function to the two internal values that returns a new pair.
+ *
+ * Is a monadic bind.
+ *
+ * @param <L2>
+ * The new left pair type
+ * @param <R2>
+ * The new right pair type
+ * @param binder
+ * The function to use as a bind
+ * @return The new pair
+ */
+ public <L2, R2> IPair<L2, R2>
+ bind(BiFunction<L, R, IPair<L2, R2>> binder);
+
+ /**
* Execute an action with the values of this pair. Has no effect on the
* internal contents
*
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java
index f721a9a..d0397f7 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java
@@ -97,4 +97,10 @@ public class Pair<L, R> implements IPair<L, R> {
public String toString() {
return "pair[l=" + leftValue.toString() + ", r=" + rightValue.toString() + "]";
}
+
+ @Override
+ public <L2, R2> IPair<L2, R2>
+ bind(BiFunction<L, R, IPair<L2, R2>> binder) {
+ return binder.apply(leftValue, rightValue);
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java
index 2ad8dbf..9f9dc4a 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java
@@ -21,34 +21,100 @@ import bjc.utils.funcdata.IFunctionalList;
* The type of the data being held
*/
public class LazyHolder<T> implements IHolder<T>, ILazy {
- private final class LazyHolderSupplier<NewT>
+ private static final class LazyHolderHolder<T2>
+ implements IHolder<T2> {
+ private Supplier<IHolder<T2>> holderSource;
+
+ private IHolder<T2> holder;
+
+ private IFunctionalList<Function<T2, T2>> actions = new FunctionalList<>();
+
+ public LazyHolderHolder(Supplier<IHolder<T2>> source) {
+
+ holderSource = source;
+ }
+
+ @Override
+ public void doWith(Consumer<T2> action) {
+ actions.add((val) -> {
+ action.accept(val);
+
+ return val;
+ });
+ }
+
+ @Override
+ public <NewT> IHolder<NewT> map(Function<T2, NewT> transformer) {
+ // TODO implement me
+ throw new UnsupportedOperationException(
+ "Mapping is not yet supported on bound holders");
+ }
+
+ @Override
+ public IHolder<T2> transform(Function<T2, T2> transformer) {
+ actions.add(transformer);
+
+ return this;
+ }
+
+ @Override
+ public <E> E unwrap(Function<T2, E> unwrapper) {
+ if (holder == null) {
+ holder = holderSource.get();
+ }
+
+ if (!actions.isEmpty()) {
+ actions.forEach((transform) -> {
+ holder.transform(transform);
+ });
+ }
+
+ return holder.unwrap(unwrapper);
+ }
+
+ @Override
+ public <E> IHolder<E> bind(Function<T2, IHolder<E>> binder) {
+ return new LazyHolderHolder<>(() -> {
+ return binder.apply(unwrap((val) -> val));
+ });
+ }
+
+ }
+
+ private static final class LazyHolderSupplier<NewT, T2>
implements Supplier<NewT> {
- private IFunctionalList<Function<T, T>> pendingActions;
- private Function<T, NewT> pendingTransform;
+ private IFunctionalList<Function<T2, T2>> pendingActions;
+ private Function<T2, NewT> pendingTransform;
+
+ private T2 heldValue;
+ private Supplier<T2> heldSource;
- public LazyHolderSupplier(IFunctionalList<Function<T, T>> actons,
- Function<T, NewT> transform) {
+ public LazyHolderSupplier(IFunctionalList<Function<T2, T2>> actons,
+ Function<T2, NewT> transform, T2 heldValue,
+ Supplier<T2> heldSource) {
// Resolve latent bug I just realized. After a map, adding new
// actions to the original holder could've resulted in changes
// to all unactualized mapped values from that holder
pendingActions = new FunctionalList<>();
- for (Function<T, T> action : actons.toIterable()) {
+ for (Function<T2, T2> action : actons.toIterable()) {
pendingActions.add(action);
}
this.pendingTransform = transform;
+ this.heldValue = heldValue;
+ this.heldSource = heldSource;
}
@Override
public NewT get() {
if (heldValue == null) {
return pendingActions.reduceAux(heldSource.get(),
- Function<T, T>::apply, pendingTransform::apply);
+ Function<T2, T2>::apply, pendingTransform::apply);
}
return pendingActions.reduceAux(heldValue,
- Function<T, T>::apply, pendingTransform::apply);
+ Function<T2, T2>::apply, pendingTransform::apply);
}
}
@@ -114,8 +180,8 @@ public class LazyHolder<T> implements IHolder<T>, ILazy {
}
// Don't actually map until we need to
- return new LazyHolder<>(
- new LazyHolderSupplier<>(actions, transform));
+ return new LazyHolder<>(new LazyHolderSupplier<>(actions,
+ transform, heldValue, heldSource));
}
@Override
@@ -179,4 +245,11 @@ public class LazyHolder<T> implements IHolder<T>, ILazy {
heldValue = action.apply(heldValue);
});
}
+
+ @Override
+ public <T2> IHolder<T2> bind(Function<T, IHolder<T2>> binder) {
+ return new LazyHolderHolder<>(() -> {
+ return binder.apply(unwrap((val) -> val));
+ });
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java
index e08c8fb..7ba7ee7 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java
@@ -98,9 +98,9 @@ public class LazyPair<L, R> implements IPair<L, R>, ILazy {
throw new NullPointerException("Transforms must be non-null");
}
- IHolder<IPair<L2, R2>> newPair =
- delegatePair.map((currentPair) -> currentPair
- .apply(leftTransform, rightTransform));
+ IHolder<IPair<L2, R2>> newPair = delegatePair
+ .map((currentPair) -> currentPair.apply(leftTransform,
+ rightTransform));
return new LazyPair<>(newPair, materialized, true);
}
@@ -169,4 +169,17 @@ public class LazyPair<L, R> implements IPair<L, R>, ILazy {
materialized = true;
pendingActions = false;
}
+
+ @Override
+ public <L2, R2> IPair<L2, R2> bind(
+ BiFunction<L, R, IPair<L2, R2>> binder) {
+ // TODO Auto-generated method stub
+ IHolder<IPair<L2, R2>> newDelegate = delegatePair
+ .map((pairVal) -> {
+ return pairVal.bind(binder);
+ });
+
+ return new LazyPair<>(newDelegate, isMaterialized(),
+ hasPendingActions());
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java
index a73292c..ac36d15 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java
@@ -37,4 +37,24 @@ public class StringUtils {
return input.matches("\\A(?:" + regex + ")+\\Z");
}
+ /**
+ * Checks if the given expression contains the specified operator in a
+ * situation that indicates its use as an infix operator.
+ *
+ * @param expression
+ * The expression to check
+ * @param operator
+ * The operator to see if it is contained
+ * @return Whether or not the given expression contains the specified
+ * operator as a infix operator
+ */
+ public static boolean containsInfixOperator(String expression,
+ String operator) {
+ // Bit annoying to have to use a full class name, but what are you
+ // going to do?
+ return org.apache.commons.lang3.StringUtils
+ .countMatches(expression, operator) == 1
+ && !expression.equalsIgnoreCase(operator)
+ && !expression.startsWith(operator);
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java
index 37f31b0..8d31576 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java
@@ -368,16 +368,19 @@ public class WeightedGrammar<E> {
newRule.add(newCase);
}
- newRule.forEach(
- (list) -> newResults
- .add(new Pair<>(
- pair.merge((left, right) -> left)
- + additionalProbability,
- list)));
+ newRule.forEach((list) -> {
+ Integer currentProb = pair.merge((left, right) -> left);
+
+ newResults.add(new Pair<>(
+ currentProb + additionalProbability, list));
+ });
});
- newResults.forEach((pair) -> pair
- .doWith((left, right) -> addCase(ruleName, left, right)));
+ newResults.forEach((pair) -> {
+ pair.doWith((left, right) -> {
+ addCase(ruleName, left, right);
+ });
+ });
}
/**
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java
index 88b4862..b6c4d8c 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java
@@ -361,4 +361,26 @@ public class AST<T> {
action.accept(token);
}
}
+
+ /**
+ * Change the type of nodes in the tree without changing the structure
+ *
+ * @param <E>
+ * The new node type
+ * @param nodeTransform
+ * The transform to apply to leaf nodes
+ * @param operatorTransform
+ * The transform to apply to operator nodes
+ * @return An AST with the node types transformed
+ */
+ public <E> AST<E> rebuildTree(Function<T, E> nodeTransform,
+ Function<T, E> operatorTransform) {
+ return collapse((leafNode) -> {
+ E transformedNode = nodeTransform.apply(leafNode);
+ return new AST<>(transformedNode);
+ }, (operator) -> (AST<E> newLeft, AST<E> newRight) -> {
+ return new AST<>(operatorTransform.apply(operator), newLeft,
+ newRight);
+ }, (resultValue) -> resultValue);
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java
index 46e4da4..68ec70e 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java
@@ -28,40 +28,38 @@ public class TreeConstructor {
}
@Override
- public IPair<Deque<AST<T>>, AST<T>>
- apply(IPair<Deque<AST<T>>, AST<T>> pair) {
- Deque<AST<T>> queuedASTs =
- pair.merge((queue, currentAST) -> queue);
-
- AST<T> mergedAST = pair.merge((queue, currentAST) -> {
- AST<T> newAST;
-
- if (isSpecialOperator.test(element)) {
- newAST = handleSpecialOperator.apply(queue);
- } else {
- if (queue.size() < 2) {
- throw new IllegalStateException(
- "Attempted to parse binary operator without enough operands.\n"
- + "Problem operator is "
- + element
- + "\nPossible operand is: \n\t"
- + queue.peek());
- }
-
- AST<T> rightAST = queue.pop();
- AST<T> leftAST = queue.pop();
-
- newAST = new AST<>(element, leftAST, rightAST);
+ public IPair<Deque<AST<T>>, AST<T>> apply(
+ IPair<Deque<AST<T>>, AST<T>> pair) {
+ return pair.bind((queuedASTs, currentAST) -> {
+ return handleOperator(queuedASTs);
+ });
+ }
+
+ private IPair<Deque<AST<T>>, AST<T>> handleOperator(
+ Deque<AST<T>> queuedASTs) {
+ AST<T> newAST;
+
+ if (isSpecialOperator.test(element)) {
+ newAST = handleSpecialOperator.apply(queuedASTs);
+ } else {
+ if (queuedASTs.size() < 2) {
+ throw new IllegalStateException(
+ "Attempted to parse binary operator without enough operands.\n"
+ + "Problem operator is "
+ + element
+ + "\nPossible operand is: \n\t"
+ + queuedASTs.peek());
}
- queue.push(newAST);
- return newAST;
- });
+ AST<T> rightAST = queuedASTs.pop();
+ AST<T> leftAST = queuedASTs.pop();
+
+ newAST = new AST<>(element, leftAST, rightAST);
+ }
- Pair<Deque<AST<T>>, AST<T>> newPair =
- new Pair<>(queuedASTs, mergedAST);
+ queuedASTs.push(newAST);
- return newPair;
+ return new Pair<>(queuedASTs, newAST);
}
}
@@ -162,8 +160,8 @@ public class TreeConstructor {
"Special operator determiner must not be null");
}
- GenHolder<IPair<Deque<AST<T>>, AST<T>>> initialState =
- new GenHolder<>(new Pair<>(new LinkedList<>(), null));
+ GenHolder<IPair<Deque<AST<T>>, AST<T>>> initialState = new GenHolder<>(
+ new Pair<>(new LinkedList<>(), null));
tokens.forEach(
new TokenTransformer<>(initialState, operatorPredicate,