summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java
diff options
context:
space:
mode:
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java46
1 files changed, 35 insertions, 11 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 c1cd5c7..99e3e60 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java
@@ -76,12 +76,15 @@ public class ShuntingYard<TokenType> {
@Override
public void accept(String token) {
+ // Handle operators
if (operators.containsKey(token)) {
+ // Pop operators while there isn't a higher precedence one
while (!stack.isEmpty()
&& isHigherPrec(token, stack.peek())) {
output.add(transform.apply(stack.pop()));
}
+ // Put this operator onto the stack
stack.push(token);
} else if (StringUtils.containsOnly(token, "\\(")) {
// Handle groups of parenthesis for multiple nesting levels
@@ -90,12 +93,15 @@ public class ShuntingYard<TokenType> {
// Handle groups of parenthesis for multiple nesting levels
String swappedToken = token.replace(')', '(');
+ // Remove tokens up to a matching parenthesis
while (!stack.peek().equals(swappedToken)) {
output.add(transform.apply(stack.pop()));
}
+ // Remove the parenthesis
stack.pop();
} else {
+ // Just add the transformed token
output.add(transform.apply(token));
}
}
@@ -115,6 +121,7 @@ public class ShuntingYard<TokenType> {
public ShuntingYard(boolean configureBasics) {
operators = new FunctionalMap<>();
+ // Add basic operators if we're configured to do so
if (configureBasics) {
operators.put("+", Operator.ADD);
operators.put("-", Operator.SUBTRACT);
@@ -132,8 +139,10 @@ public class ShuntingYard<TokenType> {
* The precedence of the operator to add
*/
public void addOp(String operatorToken, int precedence) {
- this.addOp(operatorToken,
- IPrecedent.newSimplePrecedent(precedence));
+ // Create the precedence marker
+ IPrecedent prec = IPrecedent.newSimplePrecedent(precedence);
+
+ this.addOp(operatorToken, prec);
}
/**
@@ -145,24 +154,31 @@ public class ShuntingYard<TokenType> {
* The precedence of the operator
*/
public void addOp(String operatorToken, IPrecedent precedence) {
+ // Complain about trying to add an incorrect operator
if (operatorToken == 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
operators.put(operatorToken, precedence);
}
- private boolean isHigherPrec(String leftOperator,
- String rightOperator) {
+ private boolean isHigherPrec(String leftOperator, String rightOperator) {
+ // Check if the right operator exists
boolean operatorExists = operators.containsKey(rightOperator);
+ // If it doesn't, the left is higher precedence.
if (!operatorExists) {
return false;
}
+ // Get the precedence of operators
int rightPrecedence = operators.get(rightOperator).getPrecedence();
int leftPrecedence = operators.get(leftOperator).getPrecedence();
+ // Evaluate what we were asked
return rightPrecedence >= leftPrecedence;
}
@@ -177,20 +193,26 @@ public class ShuntingYard<TokenType> {
*/
public IList<TokenType> postfix(IList<String> input,
Function<String, TokenType> tokenTransformer) {
+ // Check our input
if (input == null) {
throw new NullPointerException("Input must not be null");
} else if (tokenTransformer == null) {
throw new NullPointerException("Transformer must not be null");
}
+ // Here's what we're handing back
IList<TokenType> output = new FunctionalList<>();
+ // The stack to put operators on
Deque<String> stack = new LinkedList<>();
+ // Shunt the tokens
input.forEach(new TokenShunter(output, stack, tokenTransformer));
- stack.forEach(
- (token) -> output.add(tokenTransformer.apply(token)));
+ // Transform any resulting tokens
+ stack.forEach((token) -> {
+ output.add(tokenTransformer.apply(token));
+ });
return output;
}
@@ -199,13 +221,15 @@ public class ShuntingYard<TokenType> {
* Remove an operator from the list of shuntable operators
*
* @param token
- * The token representing the operator
+ * The token representing the operator. If null, remove all
+ * operators
*/
public void removeOp(String token) {
+ // Check if we want to remove all operators
if (token == null) {
- throw new NullPointerException("Token must not be null");
+ operators = new FunctionalMap<>();
+ } else {
+ operators.remove(token);
}
-
- operators.remove(token);
}
-} \ No newline at end of file
+}