diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-03-30 09:10:47 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-03-30 09:10:47 -0400 |
| commit | 555adde9f8d0253febeb1fe7c058ef12785899a6 (patch) | |
| tree | ad0c8755f5fd2c940a32eb5e2193bae4545c7b4c /BJC-Utils2/src/main/java/bjc/utils/parserutils | |
| parent | 7c4d9b7d6dba55c77fd1fd24beedcb6147d46cae (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/parserutils')
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java | 60 |
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())); |
