From 77fcc58d1facffbc3af50be8c05985350e9f1355 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Sun, 17 Apr 2016 15:01:44 -0400 Subject: Code maintenace and changes --- .../utils/parserutils/RuleBasedConfigReader.java | 116 ++++++++++++--------- .../java/bjc/utils/parserutils/ShuntingYard.java | 13 ++- .../bjc/utils/parserutils/TokenTransformer.java | 94 +++++++++++++++++ .../bjc/utils/parserutils/TreeConstructor.java | 99 ++---------------- 4 files changed, 175 insertions(+), 147 deletions(-) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java (limited to 'BJC-Utils2/src/main/java/bjc/utils/parserutils') diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java index 9bb20a5..c31066c 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java @@ -8,8 +8,8 @@ import java.util.Scanner; import java.util.function.BiConsumer; import java.util.function.Consumer; -import bjc.utils.data.experimental.IPair; -import bjc.utils.data.experimental.Pair; +import bjc.utils.data.IPair; +import bjc.utils.data.Pair; import bjc.utils.exceptions.UnknownPragmaException; import bjc.utils.funcdata.FunctionalStringTokenizer; @@ -100,58 +100,13 @@ public class RuleBasedConfigReader { // It's a comment continue; } else if (line.equals("")) { - if (ruleOpen == false) { - // Ignore blank line without an open rule - } else { - if (endRule == null) { - // Nothing happens on rule end - ruleOpen = false; - } else { - endRule.accept(state); - } - - ruleOpen = false; - } + ruleOpen = endRule(state, ruleOpen); + continue; } else if (line.startsWith("\t")) { - if (ruleOpen == false) { - throw new InputMismatchException( - "Can't continue rule with no rule currently open"); - } - - if (continueRule == null) { - throw new InputMismatchException( - "Attempted to continue rule with rule continuation disabled." - + " Check for extraneous tabs"); - } - - continueRule.accept(new FunctionalStringTokenizer( - line.substring(1), " "), state); + continueRule(state, ruleOpen, line); } else { - FunctionalStringTokenizer tokenizer = - new FunctionalStringTokenizer(line, " "); - - String nextToken = tokenizer.nextToken(); - - if (nextToken.equals("pragma")) { - String token = tokenizer.nextToken(); - - pragmas.getOrDefault(token, (tokenzer, stat) -> { - throw new UnknownPragmaException( - "Unknown pragma " + token); - }).accept(tokenizer, state); - } else { - if (ruleOpen == true) { - throw new InputMismatchException( - "Attempted to open a" - + " rule with a rule already open. Make sure rules are" - + " seperated by blank lines"); - } - - startRule.accept(tokenizer, - new Pair<>(nextToken, state)); - ruleOpen = true; - } + ruleOpen = startRule(state, ruleOpen, line); } } } @@ -159,6 +114,65 @@ public class RuleBasedConfigReader { return state; } + private boolean startRule(E state, boolean ruleOpen, String line) { + FunctionalStringTokenizer tokenizer = + new FunctionalStringTokenizer(line, " "); + + String nextToken = tokenizer.nextToken(); + + if (nextToken.equals("pragma")) { + String token = tokenizer.nextToken(); + + pragmas.getOrDefault(token, (tokenzer, stat) -> { + throw new UnknownPragmaException( + "Unknown pragma " + token); + }).accept(tokenizer, state); + } else { + if (ruleOpen == true) { + throw new InputMismatchException("Attempted to open a" + + " rule with a rule already open. Make sure rules are" + + " seperated by blank lines"); + } + + startRule.accept(tokenizer, new Pair<>(nextToken, state)); + ruleOpen = true; + } + return ruleOpen; + } + + private void continueRule(E state, boolean ruleOpen, String line) { + if (ruleOpen == false) { + throw new InputMismatchException( + "Can't continue rule with no rule currently open"); + } + + if (continueRule == null) { + throw new InputMismatchException( + "Attempted to continue rule with rule continuation disabled." + + " Check for extraneous tabs"); + } + + continueRule.accept( + new FunctionalStringTokenizer(line.substring(1), " "), + state); + } + + private boolean endRule(E state, boolean ruleOpen) { + if (ruleOpen == false) { + // Ignore blank line without an open rule + } else { + if (endRule == null) { + // Nothing happens on rule end + ruleOpen = false; + } else { + endRule.accept(state); + } + + ruleOpen = false; + } + return ruleOpen; + } + /** * Set the action to execute when continuing a rule * 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 a60cb01..9c7618b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java @@ -161,10 +161,15 @@ public class ShuntingYard { operators.put(operatorToken, precedence); } - private boolean isHigherPrec(String operator, String rightOperator) { - return (operators.containsKey(rightOperator) && operators - .get(rightOperator).getPrecedence() >= operators - .get(operator).getPrecedence()); + private boolean isHigherPrec(String leftOperator, + String rightOperator) { + boolean operatorExists = operators.containsKey(rightOperator); + + boolean hasHigherPrecedence = + operators.get(rightOperator).getPrecedence() >= operators + .get(leftOperator).getPrecedence(); + + return (operatorExists && hasHigherPrecedence); } /** diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java new file mode 100644 index 0000000..4db5e76 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenTransformer.java @@ -0,0 +1,94 @@ +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.utils.data.IHolder; +import bjc.utils.data.IPair; +import bjc.utils.data.Pair; +import bjc.utils.funcdata.ITree; +import bjc.utils.funcdata.Tree; + +final class TokenTransformer implements Consumer { + private final class OperatorHandler + implements UnaryOperator>, ITree>> { + private T element; + + public OperatorHandler(T element) { + this.element = element; + } + + @Override + public IPair>, ITree> + apply(IPair>, ITree> pair) { + return pair.bind((queuedASTs, currentAST) -> { + return handleOperator(queuedASTs); + }); + } + + private IPair>, ITree> + handleOperator(Deque> queuedASTs) { + ITree newAST; + + if (isSpecialOperator.test(element)) { + newAST = handleSpecialOperator.apply(queuedASTs); + } else { + if (queuedASTs.size() < 2) { + throw new IllegalStateException( + "Attempted to parse binary operator without enough operands.\n" + + "Problem operator is " + element + + "\nPossible operand is: \n\t" + + queuedASTs.peek()); + } + + ITree rightAST = queuedASTs.pop(); + ITree leftAST = queuedASTs.pop(); + + newAST = new Tree<>(element, leftAST, rightAST); + } + + queuedASTs.push(newAST); + + return new Pair<>(queuedASTs, newAST); + } + } + + private IHolder>, ITree>> initialState; + private Predicate operatorPredicate; + private Predicate isSpecialOperator; + private Function>, ITree> handleSpecialOperator; + + public TokenTransformer( + IHolder>, ITree>> initialState, + Predicate operatorPredicate, Predicate isSpecialOperator, + Function>, ITree> handleSpecialOperator) { + this.initialState = initialState; + this.operatorPredicate = operatorPredicate; + this.isSpecialOperator = isSpecialOperator; + this.handleSpecialOperator = handleSpecialOperator; + } + + @Override + public void accept(T element) { + if (operatorPredicate.test(element)) { + initialState.transform(new OperatorHandler(element)); + } else { + ITree newAST = new Tree<>(element); + + initialState.doWith((pair) -> { + pair.doWith((queue, currentAST) -> { + queue.push(newAST); + }); + }); + + initialState.transform((pair) -> { + return pair.bind((queue, currentAST) -> { + return new Pair<>(queue, newAST); + }); + }); + } + } +} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java index 52299bb..efd0394 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java @@ -2,18 +2,15 @@ package bjc.utils.parserutils; import java.util.Deque; import java.util.LinkedList; -import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import bjc.utils.data.experimental.IHolder; -import bjc.utils.data.experimental.IPair; -import bjc.utils.data.experimental.Identity; -import bjc.utils.data.experimental.Pair; +import bjc.utils.data.IHolder; +import bjc.utils.data.IPair; +import bjc.utils.data.Identity; +import bjc.utils.data.Pair; import bjc.utils.funcdata.IFunctionalList; import bjc.utils.funcdata.ITree; -import bjc.utils.funcdata.Tree; /** * Creates a parse tree from a postfix expression @@ -22,88 +19,6 @@ import bjc.utils.funcdata.Tree; * */ public class TreeConstructor { - private static final class TokenTransformer implements Consumer { - private final class OperatorHandler implements - UnaryOperator>, ITree>> { - private T element; - - public OperatorHandler(T element) { - this.element = element; - } - - @Override - public IPair>, ITree> apply( - IPair>, ITree> pair) { - return pair.bind((queuedASTs, currentAST) -> { - return handleOperator(queuedASTs); - }); - } - - private IPair>, ITree> handleOperator( - Deque> queuedASTs) { - ITree newAST; - - if (isSpecialOperator.test(element)) { - newAST = handleSpecialOperator.apply(queuedASTs); - } else { - if (queuedASTs.size() < 2) { - throw new IllegalStateException( - "Attempted to parse binary operator without enough operands.\n" - + "Problem operator is " + element - + "\nPossible operand is: \n\t" - + queuedASTs.peek()); - } - - ITree rightAST = queuedASTs.pop(); - ITree leftAST = queuedASTs.pop(); - - newAST = new Tree<>(element, leftAST, rightAST); - } - - queuedASTs.push(newAST); - - return new Pair<>(queuedASTs, newAST); - } - } - - private IHolder>, ITree>> initialState; - private Predicate operatorPredicate; - private Predicate isSpecialOperator; - private Function>, ITree> handleSpecialOperator; - - public TokenTransformer( - IHolder>, ITree>> initialState, - Predicate operatorPredicate, - Predicate isSpecialOperator, - Function>, ITree> handleSpecialOperator) { - this.initialState = initialState; - this.operatorPredicate = operatorPredicate; - this.isSpecialOperator = isSpecialOperator; - this.handleSpecialOperator = handleSpecialOperator; - } - - @Override - public void accept(T element) { - if (operatorPredicate.test(element)) { - initialState.transform(new OperatorHandler(element)); - } else { - ITree newAST = new Tree<>(element); - - initialState.doWith((pair) -> { - pair.doWith((queue, currentAST) -> { - queue.push(newAST); - }); - }); - - initialState.transform((pair) -> { - return pair.bind((queue, currentAST) -> { - return new Pair<>(queue, newAST); - }); - }); - } - } - } - /** * Construct a tree from a list of tokens in postfix notation * @@ -161,15 +76,15 @@ public class TreeConstructor { "Special operator determiner must not be null"); } - IHolder>, ITree>> initialState = new Identity<>( - new Pair<>(new LinkedList<>(), null)); + IHolder>, ITree>> initialState = + new Identity<>(new Pair<>(new LinkedList<>(), null)); tokens.forEach( new TokenTransformer<>(initialState, operatorPredicate, isSpecialOperator, handleSpecialOperator)); return initialState.unwrap((pair) -> { - return pair.merge((queue, currentAST) -> currentAST); + return pair.getRight(); }); } } -- cgit v1.2.3