From a8681ca6d13586cc2c07f0ab93f4804c77255ac4 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Fri, 18 Mar 2016 15:13:06 -0400 Subject: Added a thing to build ASTs from shunted (postfix) expressions --- .../bjc/utils/parserutils/TreeConstructor.java | 66 ++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java (limited to 'BJC-Utils2/src/main/java/bjc/utils/parserutils') diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java new file mode 100644 index 0000000..9c920d2 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java @@ -0,0 +1,66 @@ +package bjc.utils.parserutils; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.function.Predicate; + +import bjc.utils.data.GenHolder; +import bjc.utils.data.Pair; +import bjc.utils.funcdata.FunctionalList; + +/** + * Creates a parse tree from a postfix expression + * + * @author ben + * + * @param + * The elements of the parse tree + */ +public class TreeConstructor { + /** + * Construct a tree from a list of tokens in postfix notation + * + * Only binary operators are accepted. + * + * @param toks + * The list of tokens to build a tree from + * @param opPredicate + * The predicate to use to determine if something is a + * operator + * @return A AST from the expression + */ + public static AST constructTree(FunctionalList toks, + Predicate opPredicate) { + GenHolder>, AST>> initState = new GenHolder<>( + new Pair<>(new LinkedList<>(), null)); + + toks.forEach((ele) -> { + if (opPredicate.test(ele)) { + initState.transform((par) -> { + Deque> lft = par.merge((deq, ast) -> deq); + + AST mergedAST = par.merge((deq, ast) -> { + AST right = deq.pop(); + AST left = deq.pop(); + + AST newAST = new AST(ele, left, right); + + deq.push(newAST); + + return newAST; + }); + + Pair>, AST> newPair = new Pair<>(lft, + mergedAST); + + return newPair; + }); + } else { + initState.doWith((par) -> par + .doWith((deq, ast) -> deq.push(new AST<>(ele)))); + } + }); + + return initState.unwrap((par) -> par.merge((deq, ast) -> ast)); + } +} -- cgit v1.2.3