From 1c8bc7132d980c1ff2dbd6b9af579c3b2fd8c63e Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Sun, 3 Apr 2016 19:22:48 -0400 Subject: General code refactoring and maintenance --- .../src/main/java/bjc/utils/parserutils/AST.java | 179 +++++++++++++-------- 1 file changed, 115 insertions(+), 64 deletions(-) (limited to 'BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java') 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 4bfb469..d5ae3f2 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java @@ -17,11 +17,26 @@ import bjc.utils.funcdata.bst.ITreePart.TreeLinearizationMethod; * The type of token in this AST */ public class AST { - private T token; + /** + * Indent a string n levels + * + * @param builder + * The string to indent + * @param levels + * The number of levels to indent + */ + protected static void indentNLevels(StringBuilder builder, + int levels) { + for (int i = 0; i <= levels; i++) { + builder.append("\t"); + } + } private AST left; private AST right; + private T token; + /** * Create a new leaf AST node * @@ -52,43 +67,6 @@ public class AST { right = rght; } - /** - * Traverse an AST - * - * @param linearizationMethod - * The way to traverse the tree - * @param action - * The function to call on each traversed element - */ - public void traverse(TreeLinearizationMethod linearizationMethod, - Consumer action) { - if (left != null && right != null) { - switch (linearizationMethod) { - case INORDER: - left.traverse(linearizationMethod, action); - action.accept(token); - right.traverse(linearizationMethod, action); - break; - case POSTORDER: - left.traverse(linearizationMethod, action); - right.traverse(linearizationMethod, action); - action.accept(token); - break; - case PREORDER: - action.accept(token); - left.traverse(linearizationMethod, action); - right.traverse(linearizationMethod, action); - break; - default: - throw new IllegalArgumentException( - "Got a invalid tree linearizer " - + linearizationMethod + ". WAT"); - } - } else { - action.accept(token); - } - } - /** * Collapse this tree into a single node * @@ -104,11 +82,44 @@ public class AST { * The function for transforming the result * @return The collapsed value of the tree */ + @SuppressWarnings("unchecked") public E collapse(Function tokenTransformer, Function> nodeTransformer, Function resultTransformer) { - return resultTransformer.apply( - internalCollapse(tokenTransformer, nodeTransformer)); + if (tokenTransformer == null) { + throw new NullPointerException( + "Token transformer must not be null"); + } else if (nodeTransformer == null) { + throw new NullPointerException( + "Node transformer must not be null"); + } + + if (resultTransformer != null) { + return resultTransformer.apply( + internalCollapse(tokenTransformer, nodeTransformer)); + } else { + // This is valid because if the user passes null as the last + // parameter, E will be inferred as Object, but will actually + // be T2 + return (E) internalCollapse(tokenTransformer, nodeTransformer); + } + } + + /** + * Expand the nodes in an AST + * + * @param expander + * The function to use for expanding nodes + * @return The expanded AST + */ + public AST expand(Function> expander) { + if (expander == null) { + throw new NullPointerException("Expander must not be null"); + } + + return collapse(expander, (operator) -> (leftAST, rightAST) -> { + return new AST<>(operator, leftAST, rightAST); + }, null); } /* @@ -129,6 +140,7 @@ public class AST { } T2 rightCollapsed; + if (right == null) { rightCollapsed = null; } else { @@ -141,15 +153,6 @@ public class AST { } } - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - - internalToString(builder, -1); - - return builder.toString(); - } - /** * Internal version of toString for proper rendering * @@ -186,21 +189,6 @@ public class AST { } } - /** - * Indent a string n levels - * - * @param builder - * The string to indent - * @param levels - * The number of levels to indent - */ - protected static void indentNLevels(StringBuilder builder, - int levels) { - for (int i = 0; i <= levels; i++) { - builder.append("\t"); - } - } - /** * Execute a transform on selective nodes of the tree * @@ -211,6 +199,12 @@ public class AST { */ public void selectiveTransform(Predicate transformerPredicate, UnaryOperator transformer) { + if (transformerPredicate == null) { + throw new NullPointerException("Predicate must not be null"); + } else if (transformer == null) { + throw new NullPointerException("Transformer must not be null"); + } + if (transformerPredicate.test(token)) { token = transformer.apply(token); } @@ -224,6 +218,15 @@ public class AST { } } + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + + internalToString(builder, -1); + + return builder.toString(); + } + /** * Transmute the tokens in an AST into a different sort of token * @@ -235,6 +238,10 @@ public class AST { * @return The AST with transformed tokens */ public AST transmuteAST(Function tokenTransformer) { + if (tokenTransformer == null) { + throw new NullPointerException("Transformer must not be null"); + } + AST leftBranch = null; AST rightBranch = null; @@ -249,4 +256,48 @@ public class AST { return new AST<>(tokenTransformer.apply(token), leftBranch, rightBranch); } + + /** + * Traverse an AST + * + * @param linearizationMethod + * The way to traverse the tree + * @param action + * The function to call on each traversed element + */ + public void traverse(TreeLinearizationMethod linearizationMethod, + Consumer action) { + if (linearizationMethod == null) { + throw new NullPointerException( + "Linearization method must not be null"); + } else if (action == null) { + throw new NullPointerException("Action must not be null"); + } + + if (left != null && right != null) { + switch (linearizationMethod) { + case INORDER: + left.traverse(linearizationMethod, action); + action.accept(token); + right.traverse(linearizationMethod, action); + break; + case POSTORDER: + left.traverse(linearizationMethod, action); + right.traverse(linearizationMethod, action); + action.accept(token); + break; + case PREORDER: + action.accept(token); + left.traverse(linearizationMethod, action); + right.traverse(linearizationMethod, action); + break; + default: + throw new IllegalArgumentException( + "Got a invalid tree linearizer " + + linearizationMethod + ". WAT"); + } + } else { + action.accept(token); + } + } } -- cgit v1.2.3