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 --- .../bjc/utils/parserutils/TreeConstructor.java | 151 ++++++++++++++------- 1 file changed, 103 insertions(+), 48 deletions(-) (limited to 'BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java') diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java index 42d5a9d..28ca1e3 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java @@ -2,10 +2,12 @@ package bjc.utils.parserutils; import java.util.Deque; import java.util.LinkedList; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import bjc.utils.data.GenHolder; +import bjc.utils.data.IPair; import bjc.utils.data.Pair; import bjc.utils.funcdata.FunctionalList; @@ -16,6 +18,89 @@ import bjc.utils.funcdata.FunctionalList; * */ public class TreeConstructor { + private static final class TokenTransformer implements Consumer { + private final class OperatorHandler implements + Function>, AST>, IPair>, AST>> { + private T element; + + public OperatorHandler(T element) { + this.element = element; + } + + @Override + public IPair>, AST> + apply(IPair>, AST> pair) { + Deque> queuedASTs = + pair.merge((queue, currentAST) -> queue); + + AST mergedAST = pair.merge((queue, currentAST) -> { + AST newAST; + + if (isSpecialOperator.test(element)) { + newAST = handleSpecialOperator.apply(queue); + } else { + if (queue.size() < 2) { + throw new IllegalStateException( + "Attempted to parse binary operator without enough operands"); + } + + AST rightAST = queue.pop(); + AST leftAST = queue.pop(); + + newAST = new AST<>(element, leftAST, rightAST); + } + + queue.push(newAST); + return newAST; + }); + + Pair>, AST> newPair = + new Pair<>(queuedASTs, mergedAST); + + return newPair; + } + } + + private GenHolder>, AST>> initialState; + private Predicate operatorPredicate; + private Predicate isSpecialOperator; + private Function>, AST> handleSpecialOperator; + + public TokenTransformer( + GenHolder>, AST>> initialState, + Predicate operatorPredicate, + Predicate isSpecialOperator, + Function>, AST> handleSpecialOperator) { + this.initialState = initialState; + this.operatorPredicate = operatorPredicate; + this.isSpecialOperator = isSpecialOperator; + this.handleSpecialOperator = handleSpecialOperator; + } + + @Override + public void accept(T element) { + if (operatorPredicate.test(element)) { + initialState.transform(new OperatorHandler(element)); + } else { + AST newAST = new AST<>(element); + + initialState.doWith((pair) -> { + pair.doWith((queue, currentAST) -> { + queue.push(newAST); + }); + }); + + initialState.transform((pair) -> { + return pair.apply((Deque> queue) -> { + return queue; + }, (AST currentAST) -> { + return newAST; + }); + }); + } + } + } + /** * Construct a tree from a list of tokens in postfix notation * @@ -29,10 +114,6 @@ public class TreeConstructor { * The predicate to use to determine if something is a * operator * @return A AST from the expression - * - * @deprecated Use - * {@link TreeConstructor#constructTree(FunctionalList, Predicate, Predicate, Function)} - * instead */ public static AST constructTree(FunctionalList tokens, Predicate operatorPredicate) { @@ -43,7 +124,8 @@ public class TreeConstructor { /** * Construct a tree from a list of tokens in postfix notation * - * Only binary operators are accepted. + * Only binary operators are accepted by default. Use the last two + * parameters to handle non-binary operators * * @param * The elements of the parse tree @@ -66,52 +148,25 @@ public class TreeConstructor { public static AST constructTree(FunctionalList tokens, Predicate operatorPredicate, Predicate isSpecialOperator, Function>, AST> handleSpecialOperator) { - GenHolder>, AST>> initialState = - new GenHolder<>(new Pair<>(new LinkedList<>(), null)); - - tokens.forEach((element) -> { - if (operatorPredicate.test(element)) { - initialState.transform((pair) -> { - Deque> queuedASTs = - pair.merge((queue, currentAST) -> queue); - - AST mergedAST = pair.merge((queue, currentAST) -> { - AST newAST; - - if (isSpecialOperator.test(element)) { - newAST = handleSpecialOperator.apply(queue); - } else { - AST rightAST = queue.pop(); - AST leftAST = queue.pop(); - - newAST = new AST<>(element, leftAST, rightAST); - } + if (tokens == null) { + throw new NullPointerException("Tokens must not be null"); + } else if (operatorPredicate == null) { + throw new NullPointerException( + "Operator predicate must not be null"); + } else if (isSpecialOperator == null) { + throw new NullPointerException( + "Special operator determiner must not be null"); + } - queue.push(newAST); - return newAST; - }); - - Pair>, AST> newPair = - new Pair<>(queuedASTs, mergedAST); - - return newPair; - }); - } else { - AST newAST = new AST<>(element); + GenHolder>, AST>> initialState = + new GenHolder<>(new Pair<>(new LinkedList<>(), null)); - initialState.doWith( - (pair) -> pair.doWith((queue, currentAST) -> { - queue.push(newAST); - })); + tokens.forEach( + new TokenTransformer<>(initialState, operatorPredicate, + isSpecialOperator, handleSpecialOperator)); - initialState.transform((pair) -> { - return (Pair>, AST>) pair.apply( - (queue) -> queue, (currentAST) -> newAST); - }); - } + return initialState.unwrap((pair) -> { + return pair.merge((queue, currentAST) -> currentAST); }); - - return initialState.unwrap( - (pair) -> pair.merge((queue, currentAST) -> currentAST)); } } -- cgit v1.2.3