From b0a2bcf9d3e49e8fb8859cf492eb65d1f62b3a6b Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Fri, 18 Mar 2016 15:12:33 -0400 Subject: Added simple implementation of an AST --- .../src/main/java/bjc/utils/parserutils/AST.java | 154 +++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 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 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 + * The type of token in this AST + */ +public class AST { + private T token; + + private AST left; + private AST 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 lft, AST rght) { + token = tokn; + + left = lft; + right = rght; + } + + public void traverse(TreeLinearizationMethod tlm, Consumer 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 collapse(Function tokenTransform, + Map> nodeTransform, + Function resultTransform) { + return resultTransform + .apply(internalCollapse(tokenTransform, nodeTransform)); + } + + /* + * Internal recursive collapser + */ + private T2 internalCollapse(Function tokenTransform, + Map> 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"); + } + } +} -- cgit v1.2.3