From 6dcd129a10af0034b38bfe843d223c4593deee09 Mon Sep 17 00:00:00 2001 From: Ben Culkin Date: Thu, 12 Nov 2020 20:05:01 -0500 Subject: Cleanup part 2 --- .../java/bjc/utils/parserutils/ShuntingYard.java | 25 ++-- .../java/bjc/utils/parserutils/StringDescaper.java | 2 +- .../bjc/utils/parserutils/TokenTransformer.java | 148 ------------------- .../java/bjc/utils/parserutils/TokenUtils.java | 28 +++- .../bjc/utils/parserutils/TreeConstructor.java | 156 +++++++++++++++++++-- 5 files changed, 180 insertions(+), 179 deletions(-) delete mode 100644 base/src/main/java/bjc/utils/parserutils/TokenTransformer.java (limited to 'base/src/main/java/bjc/utils/parserutils') diff --git a/base/src/main/java/bjc/utils/parserutils/ShuntingYard.java b/base/src/main/java/bjc/utils/parserutils/ShuntingYard.java index 2418517..8d61b4a 100644 --- a/base/src/main/java/bjc/utils/parserutils/ShuntingYard.java +++ b/base/src/main/java/bjc/utils/parserutils/ShuntingYard.java @@ -113,10 +113,8 @@ public class ShuntingYard { /* * Complain about trying to add an incorrect operator */ - if (operator == null) - throw new NullPointerException("Operator must not be null"); - else if (precedence == null) - throw new NullPointerException("Precedence must not be null"); + if (operator == null) throw new NullPointerException("Operator must not be null"); + else if (precedence == null) throw new NullPointerException("Precedence must not be null"); /* * Add the operator to the ones we handle @@ -141,7 +139,7 @@ public class ShuntingYard { * Get the precedence of operators */ final int rightPrecedence = operators.get(right).getPrecedence(); - final int leftPrecedence = operators.get(left).getPrecedence(); + final int leftPrecedence = operators.get(left).getPrecedence(); /* * Evaluate what we were asked @@ -165,10 +163,8 @@ public class ShuntingYard { /* * Check our input */ - if (input == null) - throw new NullPointerException("Input must not be null"); - else if (transformer == null) - throw new NullPointerException("Transformer must not be null"); + if (input == null) throw new NullPointerException("Input must not be null"); + else if (transformer == null) throw new NullPointerException("Transformer must not be null"); /* * Here's what we're handing back @@ -226,9 +222,7 @@ public class ShuntingYard { } } - for (String token : stack) { - output.add(transformer.apply(token)); - } + for (String token : stack) output.add(transformer.apply(token)); return output; } @@ -244,10 +238,7 @@ public class ShuntingYard { /* * Check if we want to remove all operators */ - if (operator == null) { - operators = new FunctionalMap<>(); - } else { - operators.remove(operator); - } + if (operator == null) operators = new FunctionalMap<>(); + else operators.remove(operator); } } diff --git a/base/src/main/java/bjc/utils/parserutils/StringDescaper.java b/base/src/main/java/bjc/utils/parserutils/StringDescaper.java index f8868e6..7052588 100644 --- a/base/src/main/java/bjc/utils/parserutils/StringDescaper.java +++ b/base/src/main/java/bjc/utils/parserutils/StringDescaper.java @@ -12,7 +12,7 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; /** - * <<<<<<< Updated upstream Customizable string escapes. + * Customizable string escapes. * * @author Benjamin Culkin */ diff --git a/base/src/main/java/bjc/utils/parserutils/TokenTransformer.java b/base/src/main/java/bjc/utils/parserutils/TokenTransformer.java deleted file mode 100644 index 6cf2da5..0000000 --- a/base/src/main/java/bjc/utils/parserutils/TokenTransformer.java +++ /dev/null @@ -1,148 +0,0 @@ -package bjc.utils.parserutils; - -import java.util.Deque; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; - -import bjc.data.IHolder; -import bjc.data.ITree; -import bjc.data.Pair; -import bjc.data.Tree; -import bjc.utils.parserutils.TreeConstructor.ConstructorState; -import bjc.utils.parserutils.TreeConstructor.QueueFlattener; - -/* - * Handle creating ASTs from tokens. - */ -final class TokenTransformer implements Consumer { - /* - * Handle operators - */ - private final class OperatorHandler - implements UnaryOperator> { - /* The handled element. */ - private final TokenType element; - - /* Create a new operator handler. */ - public OperatorHandler(final TokenType element) { - this.element = element; - } - - @Override - public ConstructorState apply(final ConstructorState pair) { - /* - * Replace the current AST with the result of handling an operator - */ - return new ConstructorState<>( - pair.bindLeft(queuedASTs -> handleOperator(queuedASTs))); - } - - private ConstructorState - handleOperator(final Deque> queuedASTs) { - /* - * The AST we're going to hand back - */ - ITree newAST; - - /* - * Handle special operators - */ - if (isSpecialOperator.test(element)) { - newAST = handleSpecialOperator.apply(element).apply(queuedASTs); - } else { - /* - * Error if we don't have enough for a binary operator - */ - if (queuedASTs.size() < 2) { - final String msg = String.format( - "Attempted to parse binary operator without enough operands\n\tProblem operator is: %s\n\tPossible operand is: %s", - element.toString(), queuedASTs.peek().toString()); - - throw new IllegalStateException(msg); - } - - /* - * Grab the two operands - */ - final ITree right = queuedASTs.pop(); - final ITree left = queuedASTs.pop(); - - /* - * Create a new AST - */ - newAST = new Tree<>(element, left, right); - } - - /* - * Stick it onto the stack - */ - queuedASTs.push(newAST); - - /* - * Hand back the state - */ - return new ConstructorState<>(queuedASTs, newAST); - } - } - - /* The initial state of the transformer. */ - private final IHolder> initialState; - - /* The predicate tot use to detect operators. */ - private final Predicate operatorPredicate; - - /* The predicate for detecting special operators. */ - private final Predicate isSpecialOperator; - /* The function for handling special operators. */ - private final Function> handleSpecialOperator; - - /** - * Create a new transformer - * - * @param initialState - * The initial state of the transformer. - * - * @param operatorPredicate - * The predicate to use to identify operators. - * - * @param isSpecialOperator - * The predicate used to identify special - * operators. - * - * @param handleSpecialOperator - * The function used for handling special - * operators. - */ - public TokenTransformer(final IHolder> initialState, - final Predicate operatorPredicate, - final Predicate isSpecialOperator, - final Function> handleSpecialOperator) { - this.initialState = initialState; - this.operatorPredicate = operatorPredicate; - this.isSpecialOperator = isSpecialOperator; - this.handleSpecialOperator = handleSpecialOperator; - } - - @Override - public void accept(final TokenType element) { - /* - * Handle operators - */ - if (operatorPredicate.test(element)) { - initialState.transform(new OperatorHandler(element)); - } else { - final ITree newAST = new Tree<>(element); - - /* - * Insert the new tree into the AST - */ - initialState.transform(pair -> new ConstructorState<>(pair.bindLeft(queue -> { - queue.push(newAST); - - return new Pair<>(queue, newAST); - }))); - } - } -} diff --git a/base/src/main/java/bjc/utils/parserutils/TokenUtils.java b/base/src/main/java/bjc/utils/parserutils/TokenUtils.java index 81a7ba0..c6fdf5e 100644 --- a/base/src/main/java/bjc/utils/parserutils/TokenUtils.java +++ b/base/src/main/java/bjc/utils/parserutils/TokenUtils.java @@ -4,11 +4,11 @@ import static bjc.utils.misc.PropertyDB.applyFormat; import static bjc.utils.misc.PropertyDB.getCompiledRegex; import static bjc.utils.misc.PropertyDB.getRegex; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import bjc.data.*; import bjc.funcdata.FunctionalList; import bjc.funcdata.IList; import bjc.utils.parserutils.splitter.TokenSplitter; @@ -316,4 +316,28 @@ public class TokenUtils { return false; } } + + /** + * Split a line into a series of space-separated arguments, including string + * literals. + * + * @param com + * The command to split from + * @return The split arguments. + */ + public static List processArguments(String com) { + List strings = new ArrayList<>(); + + BooleanToggle togg = new BooleanToggle(); + + for (String strang : removeDQuotedStrings(com)) { + if (togg.get()) { + strings.add(descapeString(strang)); + } else { + for (String strung : strang.split("\\s+")) strings.add(strung); + } + } + + return strings; + } } diff --git a/base/src/main/java/bjc/utils/parserutils/TreeConstructor.java b/base/src/main/java/bjc/utils/parserutils/TreeConstructor.java index 3c7509b..6780768 100644 --- a/base/src/main/java/bjc/utils/parserutils/TreeConstructor.java +++ b/base/src/main/java/bjc/utils/parserutils/TreeConstructor.java @@ -2,15 +2,11 @@ package bjc.utils.parserutils; import java.util.Deque; import java.util.LinkedList; -import java.util.function.Function; -import java.util.function.Predicate; - -import bjc.data.IHolder; -import bjc.data.IPair; -import bjc.data.ITree; -import bjc.data.Identity; -import bjc.data.Pair; +import java.util.function.*; + +import bjc.data.*; import bjc.funcdata.IList; +import bjc.utils.parserutils.TreeConstructor.*; /** * Creates a parse tree from a postfix expression. @@ -103,13 +99,14 @@ public class TreeConstructor { /* * Make sure our parameters are valid */ - if (tokens == null) + if (tokens == null) { throw new NullPointerException("Tokens must not be null"); - else if (isOperator == null) + } else if (isOperator == null) { throw new NullPointerException("Operator predicate must not be null"); - else if (isSpecialOperator == null) + } else if (isSpecialOperator == null) { throw new NullPointerException( "Special operator determiner must not be null"); + } final ConstructorState cstate = new ConstructorState<>(new LinkedList<>(), null); @@ -127,3 +124,140 @@ public class TreeConstructor { return initialState.unwrap(ConstructorState::getRight); } } + +/* + * Transform function on tokens + */ +class TokenTransformer implements Consumer { + /* + * Handle operators + */ + private final class OperatorHandler + implements UnaryOperator> { + /* The handled element. */ + private final TokenType element; + + /* Create a new operator handler. */ + public OperatorHandler(final TokenType element) { + this.element = element; + } + + @Override + public ConstructorState apply(final ConstructorState pair) { + /* + * Replace the current AST with the result of handling an operator + */ + return new ConstructorState<>( + pair.bindLeft(queuedASTs -> handleOperator(queuedASTs))); + } + + private ConstructorState + handleOperator(final Deque> queuedASTs) { + /* + * The AST we're going to hand back + */ + ITree newAST; + + /* + * Handle special operators + */ + if (isSpecialOperator.test(element)) { + newAST = handleSpecialOperator.apply(element).apply(queuedASTs); + } else { + /* + * Error if we don't have enough for a binary operator + */ + if (queuedASTs.size() < 2) { + final String msg = String.format( + "Attempted to parse binary operator without enough operands\n\tProblem operator is: %s\n\tPossible operand is: %s", + element.toString(), queuedASTs.peek().toString()); + + throw new IllegalStateException(msg); + } + + /* + * Grab the two operands + */ + final ITree right = queuedASTs.pop(); + final ITree left = queuedASTs.pop(); + + /* + * Create a new AST + */ + newAST = new Tree<>(element, left, right); + } + + /* + * Stick it onto the stack + */ + queuedASTs.push(newAST); + + /* + * Hand back the state + */ + return new ConstructorState<>(queuedASTs, newAST); + } + } + + /* The initial state of the transformer. */ + private final IHolder> initialState; + + /* The predicate tot use to detect operators. */ + private final Predicate operatorPredicate; + + /* The predicate for detecting special operators. */ + private final Predicate isSpecialOperator; + /* The function for handling special operators. */ + private final Function> handleSpecialOperator; + + /** + * Create a new transformer + * + * @param initialState + * The initial state of the transformer. + * + * @param operatorPredicate + * The predicate to use to identify operators. + * + * @param isSpecialOperator + * The predicate used to identify special + * operators. + * + * @param handleSpecialOperator + * The function used for handling special + * operators. + */ + public TokenTransformer(final IHolder> initialState, + final Predicate operatorPredicate, + final Predicate isSpecialOperator, + final Function> handleSpecialOperator) { + this.initialState = initialState; + this.operatorPredicate = operatorPredicate; + this.isSpecialOperator = isSpecialOperator; + this.handleSpecialOperator = handleSpecialOperator; + } + + @Override + public void accept(final TokenType element) { + /* + * Handle operators + */ + if (operatorPredicate.test(element)) { + initialState.transform(new OperatorHandler(element)); + } else { + final ITree newAST = new Tree<>(element); + + /* + * Insert the new tree into the AST + */ + initialState.transform(pair -> new ConstructorState<>( + pair.bindLeft(queue -> { + queue.push(newAST); + + return new Pair<>(queue, newAST); + }) + ) + ); + } + } +} \ No newline at end of file -- cgit v1.2.3