diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-03-18 15:12:33 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-03-18 15:12:33 -0400 |
| commit | b0a2bcf9d3e49e8fb8859cf492eb65d1f62b3a6b (patch) | |
| tree | 2a758d3822ad792384375de883ed383d891aa98c /BJC-Utils2/src/main/java/bjc/utils | |
| parent | 6f86a0063d6510ccf63064e141ea74fc90d01428 (diff) | |
Added simple implementation of an AST
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils')
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java new file mode 100644 index 0000000..bcb56eb --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java @@ -0,0 +1,154 @@ +package bjc.utils.parserutils; + +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.BinaryOperator; +import java.util.function.Consumer; +import java.util.function.Function; + +import bjc.utils.funcdata.ITreePart.TreeLinearizationMethod; + +/** + * A simple binary tree meant for use as an AST + * + * @author ben + * + * @param <T> + * The type of token in this AST + */ +public class AST<T> { + private T token; + + private AST<T> left; + private AST<T> right; + + /** + * Create a new leaf AST node + * + * @param tokn + * The token in this node + */ + public AST(T tokn) { + token = tokn; + + left = null; + right = null; + } + + /** + * Create a new AST node with the specified data and children + * + * @param tokn + * The token in this node + * @param left + * The left child of this AST + * @param right + * The right child of this AST + */ + public AST(T tokn, AST<T> lft, AST<T> rght) { + token = tokn; + + left = lft; + right = rght; + } + + public void traverse(TreeLinearizationMethod tlm, Consumer<T> con) { + switch (tlm) { + case INORDER: + left.traverse(tlm, con); + con.accept(token); + right.traverse(tlm, con); + break; + case POSTORDER: + left.traverse(tlm, con); + right.traverse(tlm, con); + con.accept(token); + break; + case PREORDER: + con.accept(token); + left.traverse(tlm, con); + right.traverse(tlm, con); + break; + default: + throw new IllegalArgumentException( + "Got a invalid tree linearizer " + tlm + ". WAT"); + } + } + + /** + * Collapse this tree into a single node + * + * @param tokenTransform + * The function to transform nodes into data + * @param nodeTransform + * A map of functions for operator collapsing + * @param resultTransform + * The function for transforming the result + * @return The collapsed value of the tree + */ + public <E, T2> E collapse(Function<T, T2> tokenTransform, + Map<T, BinaryOperator<T2>> nodeTransform, + Function<T2, E> resultTransform) { + return resultTransform + .apply(internalCollapse(tokenTransform, nodeTransform)); + } + + /* + * Internal recursive collapser + */ + private <T2> T2 internalCollapse(Function<T, T2> tokenTransform, + Map<T, BinaryOperator<T2>> nodeTransform) { + if (left == null && right == null) { + return tokenTransform.apply(token); + } else { + T2 leftCollapsed = left.internalCollapse(tokenTransform, + nodeTransform); + T2 rightCollapsed = right.internalCollapse(tokenTransform, + nodeTransform); + + return nodeTransform.get(token).apply(leftCollapsed, + rightCollapsed); + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + internalToString(sb, -1); + + return sb.toString(); + } + + private void internalToString(StringBuilder sb, int indentLevel) { + indentNLevels(sb, indentLevel); + + if (left == null && right == null) { + sb.append("Node: "); + sb.append(token.toString()); + sb.append("\n"); + } else { + sb.append("Node: "); + sb.append(token.toString()); + sb.append("\n"); + + // indentNLevels(sb, indentLevel + 2); + // + // sb.append("Left: \n"); + + left.internalToString(sb, indentLevel + 2); + // + // indentNLevels(sb, indentLevel + 2); + // + // sb.append("Right: \n"); + + right.internalToString(sb, indentLevel + 2); + } + } + + private void indentNLevels(StringBuilder sb, int n) { + for (int i = 0; i <= n; i++) { + sb.append("\t"); + } + } +} |
