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)); } }