summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-03-30 09:10:47 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-03-30 09:10:47 -0400
commit555adde9f8d0253febeb1fe7c058ef12785899a6 (patch)
treead0c8755f5fd2c940a32eb5e2193bae4545c7b4c /BJC-Utils2/src/main/java/bjc/utils
parent7c4d9b7d6dba55c77fd1fd24beedcb6147d46cae (diff)
Adjusted shunting yard for multiple nesting levels.
Basically, you can now repeat a parenthesis to make new nesting levels. For example, while ( still matches with ), (( will now only match with )), so you have as many levels of nesting as you want, and won't get confused about which closing paren matches which opening one
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java60
1 files changed, 39 insertions, 21 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 e607a1a..3ce7da0 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java
@@ -4,10 +4,12 @@ import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
+import java.util.function.Consumer;
import java.util.function.Function;
import bjc.utils.data.IPrecedent;
import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcutils.StringUtils;
/**
* Utility to run the shunting yard algorithm on a bunch of tokens
@@ -18,7 +20,42 @@ import bjc.utils.funcdata.FunctionalList;
* The type of tokens being shunted
*/
public class ShuntingYard<E> {
-
+
+ private final class TokenShunter implements Consumer<String> {
+ private FunctionalList<E> outp;
+ private Deque<String> stack;
+ private Function<String, E> transform;
+
+ public TokenShunter(FunctionalList<E> outp, Deque<String> stack,
+ Function<String, E> transform) {
+ this.outp = outp;
+ this.stack = stack;
+ this.transform = transform;
+ }
+
+ @Override
+ public void accept(String token) {
+ if (ops.containsKey(token)) {
+ while (!stack.isEmpty()
+ && isHigherPrec(token, stack.peek())) {
+ outp.add(transform.apply(stack.pop()));
+ }
+
+ stack.push(token);
+ } else if (StringUtils.containsOnly(token, "\\(")) {
+ stack.push(token);
+ } else if (StringUtils.containsOnly(token, "\\)")) {
+ while (stack.peek().equals(token.replace(')', '('))) {
+ outp.add(transform.apply(stack.pop()));
+ }
+
+ stack.pop();
+ } else {
+ outp.add(transform.apply(token));
+ }
+ }
+ }
+
/**
* A enum representing the fundamental operator types
*
@@ -120,26 +157,7 @@ public class ShuntingYard<E> {
FunctionalList<E> outp = new FunctionalList<>();
Deque<String> stack = new LinkedList<>();
- inp.forEach((token) -> {
- if (ops.containsKey(token)) {
- while (!stack.isEmpty()
- && isHigherPrec(token, stack.peek())) {
- outp.add(transform.apply(stack.pop()));
- }
-
- stack.push(token);
- } else if (token.equals("(")) {
- stack.push(token);
- } else if (token.equals(")")) {
- while (!stack.peek().equals("(")) {
- outp.add(transform.apply(stack.pop()));
- }
-
- stack.pop();
- } else {
- outp.add(transform.apply(token));
- }
- });
+ inp.forEach(new TokenShunter(outp, stack, transform));
while (!stack.isEmpty()) {
outp.add(transform.apply(stack.pop()));