diff options
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/parserutils')
3 files changed, 63 insertions, 59 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java index 636bf31..2ea23c6 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java @@ -16,10 +16,10 @@ import bjc.utils.funcutils.StringUtils; * * @author ben * - * @param <E> + * @param <TokenType> * The type of tokens being shunted */ -public class ShuntingYard<E> { +public class ShuntingYard<TokenType> { /** * A enum representing the fundamental operator types * @@ -32,17 +32,18 @@ public class ShuntingYard<E> { */ ADD(1), /** - * Represents division + * Represents subtraction */ - DIVIDE(4), + SUBTRACT(2), + /** * Represents multiplication */ MULTIPLY(3), /** - * Represents subtraction + * Represents division */ - SUBTRACT(2); + DIVIDE(4); private final int precedence; @@ -62,12 +63,13 @@ public class ShuntingYard<E> { } private final class TokenShunter implements Consumer<String> { - private IFunctionalList<E> output; - private Deque<String> stack; - private Function<String, E> transform; + private IFunctionalList<TokenType> output; + private Deque<String> stack; + private Function<String, TokenType> transform; - public TokenShunter(IFunctionalList<E> outpt, Deque<String> stack, - Function<String, E> transform) { + public TokenShunter(IFunctionalList<TokenType> outpt, + Deque<String> stack, + Function<String, TokenType> transform) { this.output = outpt; this.stack = stack; this.transform = transform; @@ -159,11 +161,10 @@ public class ShuntingYard<E> { return false; } - boolean hasHigherPrecedence = operators.get(rightOperator) - .getPrecedence() >= operators.get(leftOperator) - .getPrecedence(); + int rightPrecedence = operators.get(rightOperator).getPrecedence(); + int leftPrecedence = operators.get(leftOperator).getPrecedence(); - return hasHigherPrecedence; + return rightPrecedence >= leftPrecedence; } /** @@ -175,15 +176,16 @@ public class ShuntingYard<E> { * The function to use to transform strings to tokens * @return A list of tokens in postfix notation */ - public IFunctionalList<E> postfix(IFunctionalList<String> input, - Function<String, E> tokenTransformer) { + public IFunctionalList<TokenType> postfix( + IFunctionalList<String> input, + Function<String, TokenType> tokenTransformer) { if (input == null) { throw new NullPointerException("Input must not be null"); } else if (tokenTransformer == null) { throw new NullPointerException("Transformer must not be null"); } - IFunctionalList<E> output = new FunctionalList<>(); + IFunctionalList<TokenType> output = new FunctionalList<>(); Deque<String> stack = new LinkedList<>(); @@ -199,14 +201,14 @@ public class ShuntingYard<E> { /** * Remove an operator from the list of shuntable operators * - * @param tok + * @param token * The token representing the operator */ - public void removeOp(String tok) { - if (tok == null) { + public void removeOp(String token) { + if (token == null) { throw new NullPointerException("Token must not be null"); } - operators.remove(tok); + operators.remove(token); } }
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java index 4727124..9fb64cf 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java @@ -12,26 +12,26 @@ import bjc.utils.data.Pair; import bjc.utils.funcdata.ITree; import bjc.utils.funcdata.Tree; -final class TokenTransformer<T> implements Consumer<T> { - private final class OperatorHandler - implements UnaryOperator<IPair<Deque<ITree<T>>, ITree<T>>> { - private T element; +final class TokenTransformer<TokenType> implements Consumer<TokenType> { + private final class OperatorHandler implements + UnaryOperator<IPair<Deque<ITree<TokenType>>, ITree<TokenType>>> { + private TokenType element; - public OperatorHandler(T element) { + public OperatorHandler(TokenType element) { this.element = element; } @Override - public IPair<Deque<ITree<T>>, ITree<T>> apply( - IPair<Deque<ITree<T>>, ITree<T>> pair) { - return pair.bind((queuedASTs, currentAST) -> { + public IPair<Deque<ITree<TokenType>>, ITree<TokenType>> apply( + IPair<Deque<ITree<TokenType>>, ITree<TokenType>> pair) { + return pair.bindLeft((queuedASTs) -> { return handleOperator(queuedASTs); }); } - private IPair<Deque<ITree<T>>, ITree<T>> handleOperator( - Deque<ITree<T>> queuedASTs) { - ITree<T> newAST; + private IPair<Deque<ITree<TokenType>>, ITree<TokenType>> + handleOperator(Deque<ITree<TokenType>> queuedASTs) { + ITree<TokenType> newAST; if (isSpecialOperator.test(element)) { newAST = handleSpecialOperator.apply(element) @@ -45,8 +45,8 @@ final class TokenTransformer<T> implements Consumer<T> { + queuedASTs.peek()); } - ITree<T> rightAST = queuedASTs.pop(); - ITree<T> leftAST = queuedASTs.pop(); + ITree<TokenType> rightAST = queuedASTs.pop(); + ITree<TokenType> leftAST = queuedASTs.pop(); newAST = new Tree<>(element, leftAST, rightAST); } @@ -57,15 +57,18 @@ final class TokenTransformer<T> implements Consumer<T> { } } - private IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState; - private Predicate<T> operatorPredicate; - private Predicate<T> isSpecialOperator; - private Function<T, Function<Deque<ITree<T>>, ITree<T>>> handleSpecialOperator; + private IHolder<IPair<Deque<ITree<TokenType>>, ITree<TokenType>>> initialState; + + private Predicate<TokenType> operatorPredicate; + + private Predicate<TokenType> isSpecialOperator; + private Function<TokenType, Function<Deque<ITree<TokenType>>, ITree<TokenType>>> handleSpecialOperator; public TokenTransformer( - IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState, - Predicate<T> operatorPredicate, Predicate<T> isSpecialOperator, - Function<T, Function<Deque<ITree<T>>, ITree<T>>> handleSpecialOperator) { + IHolder<IPair<Deque<ITree<TokenType>>, ITree<TokenType>>> initialState, + Predicate<TokenType> operatorPredicate, + Predicate<TokenType> isSpecialOperator, + Function<TokenType, Function<Deque<ITree<TokenType>>, ITree<TokenType>>> handleSpecialOperator) { this.initialState = initialState; this.operatorPredicate = operatorPredicate; this.isSpecialOperator = isSpecialOperator; @@ -73,20 +76,16 @@ final class TokenTransformer<T> implements Consumer<T> { } @Override - public void accept(T element) { + public void accept(TokenType element) { if (operatorPredicate.test(element)) { initialState.transform(new OperatorHandler(element)); } else { - ITree<T> newAST = new Tree<>(element); + ITree<TokenType> newAST = new Tree<>(element); - initialState.doWith((pair) -> { - pair.doWith((queue, currentAST) -> { + initialState.transform((pair) -> { + return pair.bindLeft((queue) -> { queue.push(newAST); - }); - }); - initialState.transform((pair) -> { - return pair.bind((queue, currentAST) -> { return new Pair<>(queue, newAST); }); }); 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 2d2a69e..283d16e 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java @@ -24,7 +24,7 @@ public class TreeConstructor { * * Only binary operators are accepted. * - * @param <T> + * @param <TokenType> * The elements of the parse tree * @param tokens * The list of tokens to build a tree from @@ -33,8 +33,9 @@ public class TreeConstructor { * operator * @return A AST from the expression */ - public static <T> ITree<T> constructTree(IFunctionalList<T> tokens, - Predicate<T> operatorPredicate) { + public static <TokenType> ITree<TokenType> constructTree( + IFunctionalList<TokenType> tokens, + Predicate<TokenType> operatorPredicate) { return constructTree(tokens, operatorPredicate, (op) -> false, null); } @@ -45,7 +46,7 @@ public class TreeConstructor { * Only binary operators are accepted by default. Use the last two * parameters to handle non-binary operators * - * @param <T> + * @param <TokenType> * The elements of the parse tree * @param tokens * The list of tokens to build a tree from @@ -63,9 +64,11 @@ public class TreeConstructor { * interface. Maybe there's a better way to express how that * works */ - public static <T> ITree<T> constructTree(IFunctionalList<T> tokens, - Predicate<T> operatorPredicate, Predicate<T> isSpecialOperator, - Function<T, Function<Deque<ITree<T>>, ITree<T>>> handleSpecialOperator) { + public static <TokenType> ITree<TokenType> constructTree( + IFunctionalList<TokenType> tokens, + Predicate<TokenType> operatorPredicate, + Predicate<TokenType> isSpecialOperator, + Function<TokenType, Function<Deque<ITree<TokenType>>, ITree<TokenType>>> handleSpecialOperator) { if (tokens == null) { throw new NullPointerException("Tokens must not be null"); } else if (operatorPredicate == null) { @@ -76,8 +79,8 @@ public class TreeConstructor { "Special operator determiner must not be null"); } - IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState = new Identity<>( - new Pair<>(new LinkedList<>(), null)); + IHolder<IPair<Deque<ITree<TokenType>>, ITree<TokenType>>> initialState = + new Identity<>(new Pair<>(new LinkedList<>(), null)); tokens.forEach( new TokenTransformer<>(initialState, operatorPredicate, |
