From 555adde9f8d0253febeb1fe7c058ef12785899a6 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Wed, 30 Mar 2016 09:10:47 -0400 Subject: 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 --- .../java/bjc/utils/parserutils/ShuntingYard.java | 60 ++++++++++++++-------- 1 file changed, 39 insertions(+), 21 deletions(-) (limited to 'BJC-Utils2/src/main/java/bjc') 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 { - + + private final class TokenShunter implements Consumer { + private FunctionalList outp; + private Deque stack; + private Function transform; + + public TokenShunter(FunctionalList outp, Deque stack, + Function 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 { FunctionalList outp = new FunctionalList<>(); Deque 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())); -- cgit v1.2.3