diff options
| author | bjculkin <bjculkin@mix.wvu.edu> | 2017-04-07 16:06:18 -0400 |
|---|---|---|
| committer | bjculkin <bjculkin@mix.wvu.edu> | 2017-04-07 16:06:18 -0400 |
| commit | f4baa925b0b5590bc8b12ba5f32e0218384c8efc (patch) | |
| tree | 6c8f0eceaeaabc807e8cfd17e13bba86b8981970 /BJC-Utils2/src | |
| parent | 7692fa077a84972231948354d3f0de99f27a9ad7 (diff) | |
Add simple toggle values
Diffstat (limited to 'BJC-Utils2/src')
14 files changed, 372 insertions, 282 deletions
diff --git a/BJC-Utils2/src/examples/java/bjc/utils/examples/DelimSplitterTest.java b/BJC-Utils2/src/examples/java/bjc/utils/examples/DelimSplitterTest.java index 5f4ef92..8e2a98d 100644 --- a/BJC-Utils2/src/examples/java/bjc/utils/examples/DelimSplitterTest.java +++ b/BJC-Utils2/src/examples/java/bjc/utils/examples/DelimSplitterTest.java @@ -1,6 +1,8 @@ package bjc.utils.examples; import bjc.utils.data.ITree; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IList; import bjc.utils.funcutils.StringUtils; import bjc.utils.parserutils.delims.DelimiterException; import bjc.utils.parserutils.delims.DelimiterGroup; @@ -8,7 +10,7 @@ import bjc.utils.parserutils.delims.RegexCloser; import bjc.utils.parserutils.delims.RegexOpener; import bjc.utils.parserutils.delims.SequenceDelimiter; import bjc.utils.parserutils.delims.StringDelimiter; -import bjc.utils.parserutils.splitter.SimpleTokenSplitter; +import bjc.utils.parserutils.splitterv2.ConfigurableTokenSplitter; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -28,7 +30,7 @@ import java.util.Scanner; * */ public class DelimSplitterTest { - private SimpleTokenSplitter split; + private ConfigurableTokenSplitter split; private StringDelimiter dlm; @@ -46,7 +48,7 @@ public class DelimSplitterTest { groups = new HashMap<>(); - split = new SimpleTokenSplitter(); + split = new ConfigurableTokenSplitter(true); dlm = new StringDelimiter(); @@ -141,27 +143,21 @@ public class DelimSplitterTest { } break; case "splitter-add": - split.addDelimiter(argArray); + split.addSimpleDelimiters(argArray); if(verbose) { System.out.println("Added delimiters " + StringUtils.toEnglishList(argArray, true)); } break; case "splitter-addmulti": - split.addMultiDelimiter(argArray); + split.addMultiDelimiters(argArray); if(verbose) { System.out.println( "Added multi-delimiters " + StringUtils.toEnglishList(argArray, true)); } break; - case "splitter-addnon": - split.addNonMatcher(argArray); - if(verbose) { - System.out.println("Added non-splitters " + StringUtils.toEnglishList(argArray, true)); - } - break; case "splitter-addmatch": for(String arg : argArray) { - split.addDelimiter(arg, mirrored.get(arg)); + split.addSimpleDelimiters(arg, mirrored.get(arg)); } if(verbose) { System.out.println("Added matched delimiters " @@ -172,7 +168,7 @@ public class DelimSplitterTest { System.out.println(split.toString()); break; case "splitter-reset": - split = new SimpleTokenSplitter(); + split = new ConfigurableTokenSplitter(true); if(verbose) { System.out.println("Reset splitter"); } @@ -393,14 +389,14 @@ public class DelimSplitterTest { for(int i = 0; i < argArray.length; i++) { String arg = argArray[i]; - String[] res = split.split(arg); + IList<String> strangs = split.split(arg); - System.out.printf("%d '%s' %s\n", i, arg, Arrays.deepToString(res)); + System.out.printf("%d '%s' %s\n", i, arg, strangs); } } private void handleTest(String inp, boolean splitWS) { - String[] strings; + IList<String> strings; try { strings = split.split(inp); @@ -409,7 +405,7 @@ public class DelimSplitterTest { return; } - System.out.println("Split tokens: " + Arrays.deepToString(strings)); + System.out.println("Split tokens: " + strings); if(splitWS) { List<String> tks = new LinkedList<>(); @@ -418,10 +414,10 @@ public class DelimSplitterTest { tks.addAll(Arrays.asList(strang.split(" "))); } - strings = tks.toArray(new String[0]); + strings = new FunctionalList<>(tks); } try { - ITree<String> delim = dlm.delimitSequence(strings); + ITree<String> delim = dlm.delimitSequence(strings.toArray(new String[0])); printDelimSeq(delim); } catch(DelimiterException dex) { @@ -437,17 +433,6 @@ public class DelimSplitterTest { System.out.println(); System.out.println(); - /* - * ITree<String> transform = - * delim.topDownTransform(this::pickNode, this::transformNode); - * System.out.println("Transformed tree:\n" + - * transform.getChild(1)); System.out.println(); - * System.out.println(); - * - * System.out.print("Transformed expr: "); - * printDelimTree(transform); - */ - System.out.println(); } @@ -498,19 +483,6 @@ public class DelimSplitterTest { } } - /* - * private TopDownTransformResult pickNode(String node) { - * if(groups.containsKey(node) || node.equals("subgroup")) return - * TopDownTransformResult.PUSHDOWN; else return - * TopDownTransformResult.PASSTHROUGH; } - * - * private ITree<String> transformNode(ITree<String> tree) { - * if(groups.containsKey(tree.getHead())) { - * - * } - * - * return tree; } - */ /** * Main method * diff --git a/BJC-Utils2/src/examples/java/bjc/utils/examples/TreeConstructTest.java b/BJC-Utils2/src/examples/java/bjc/utils/examples/TreeConstructTest.java deleted file mode 100644 index a8f8134..0000000 --- a/BJC-Utils2/src/examples/java/bjc/utils/examples/TreeConstructTest.java +++ /dev/null @@ -1,129 +0,0 @@ -package bjc.utils.examples; - -import bjc.utils.data.IPair; -import bjc.utils.data.ITree; -import bjc.utils.data.Pair; -import bjc.utils.data.Tree; -import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.FunctionalStringTokenizer; -import bjc.utils.funcdata.IList; -import bjc.utils.funcdata.IMap; -import bjc.utils.funcutils.ListUtils; -import bjc.utils.funcutils.StringUtils; -import bjc.utils.parserutils.ShuntingYard; -import bjc.utils.parserutils.TreeConstructor; -import bjc.utils.parserutils.TreeConstructor.QueueFlattener; - -import java.util.Deque; -import java.util.LinkedList; -import java.util.Scanner; -import java.util.function.Predicate; - -/** - * Test of tree constructor - * - * @author ben - * - */ -public class TreeConstructTest { - private static final class OperatorPicker implements Predicate<String> { - @Override - public boolean test(String token) { - if(StringUtils.containsOnly(token, "\\[")) return true; - else if(StringUtils.containsOnly(token, "\\]")) return true; - - switch(token) { - case "+": - case "-": - case "*": - case "/": - return true; - default: - return false; - } - } - } - - /** - * Main method - * - * @param args - * Unused CLI args - */ - @SuppressWarnings({ "resource", "deprecation" }) - public static void main(String[] args) { - Scanner inputSource = new Scanner(System.in); - - System.out.print("Enter a expression to parse: "); - String line = inputSource.nextLine(); - - IList<String> tokens = new FunctionalStringTokenizer(line).toList(); - - ShuntingYard<String> yard = new ShuntingYard<>(true); - - Deque<IPair<String, String>> ops = new LinkedList<>(); - - ops.add(new Pair<>("+", "\\+")); - ops.add(new Pair<>("-", "-")); - ops.add(new Pair<>("*", "\\*")); - ops.add(new Pair<>("/", "/")); - ops.add(new Pair<>(":=", ":=")); - ops.add(new Pair<>("=>", "=>")); - - IList<String> semiExpandedTokens = ListUtils.splitTokens(tokens, ops); - - ops = new LinkedList<>(); - ops.add(new Pair<>("(", "\\(")); - ops.add(new Pair<>(")", "\\)")); - ops.add(new Pair<>("[", "\\[")); - ops.add(new Pair<>("]", "\\]")); - - IList<String> fullyExpandedTokens = ListUtils.deAffixTokens(semiExpandedTokens, ops); - fullyExpandedTokens.removeIf((strang) -> strang.equals("")); - - IList<String> shuntedTokens = yard.postfix(fullyExpandedTokens, (token) -> token); - - System.out.println("Shunted: " + shuntedTokens.toString()); - - Predicate<String> specialPicker = (operator) -> { - if(StringUtils.containsOnly(operator, "\\[")) return true; - else if(StringUtils.containsOnly(operator, "\\]")) return true; - - return false; - }; - - IMap<String, QueueFlattener<String>> operators - = new FunctionalMap<>(); - - operators.put("[", (queuedTrees) -> { - return null; - }); - - operators.put("[", (queuedTrees) -> { - Tree<String> openTree = new Tree<>("["); - - queuedTrees.push(openTree); - - return openTree; - }); - - operators.put("]", (queuedTrees) -> { - ITree<String> arrayTree = new Tree<>("[]"); - - while(!queuedTrees.peek().getHead().equals("[")) { - arrayTree.addChild(queuedTrees.pop()); - } - - queuedTrees.push(arrayTree); - - return arrayTree; - }); - - ITree<String> constructedTree = TreeConstructor.constructTree(shuntedTokens, - new OperatorPicker(), specialPicker, operators::get); - - System.out.println("AST: " + constructedTree.toString()); - - inputSource.close(); - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/PropertyDB.java b/BJC-Utils2/src/main/java/bjc/utils/PropertyDB.java index 3f2c078..daaf423 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/PropertyDB.java +++ b/BJC-Utils2/src/main/java/bjc/utils/PropertyDB.java @@ -15,11 +15,13 @@ import java.util.regex.Pattern; * */ public class PropertyDB { - private static SimpleProperties regexes; - private static Map<String, Pattern> compiledRegexes; + private static SimpleProperties regexes; + private static Map<String, Pattern> compiledRegexes; private static SimpleProperties formats; + private static final boolean LOGLOAD = false; + /* * The lock to use to ensure a read can't happen during a reload */ @@ -37,20 +39,27 @@ public class PropertyDB { */ public static void reloadProperties() { loadLock.write(() -> { - System.out.println("Reading regex properties:"); + if(LOGLOAD) { + System.out.println("Reading regex properties:"); + } regexes = new SimpleProperties(); regexes.loadFrom(PropertyDB.class.getResourceAsStream("/regexes.sprop"), false); - System.out.println(); + if(LOGLOAD) { + regexes.outputProperties(); + System.out.println(); + } compiledRegexes = new HashMap<>(); - System.out.println("Reading format properties:"); + if(LOGLOAD) { + System.out.println("Reading format properties:"); + } formats = new SimpleProperties(); formats.loadFrom(PropertyDB.class.getResourceAsStream("/formats.sprop"), false); - System.out.println(); - - if (regexes.equals(formats)) - System.out.println("WAT"); + if(LOGLOAD) { + formats.outputProperties(); + System.out.println(); + } }); } @@ -58,13 +67,13 @@ public class PropertyDB { * Retrieve a persisted regular expression. * * @param key - * The name of the regular expression. + * The name of the regular expression. * * @return The regular expression with that name. */ public static String getRegex(String key) { return loadLock.read(() -> { - if (!regexes.containsKey(key)) { + if(!regexes.containsKey(key)) { String msg = String.format("No regular expression named '%s' found", key); throw new NoSuchElementException(msg); @@ -79,13 +88,13 @@ public class PropertyDB { * expression. * * @param key - * The name of the regular expression. + * The name of the regular expression. * * @return The regular expression with that name. */ public static Pattern getCompiledRegex(String key) { return loadLock.read(() -> { - if (!regexes.containsKey(key)) { + if(!regexes.containsKey(key)) { String msg = String.format("No regular expression named '%s' found", key); throw new NoSuchElementException(msg); @@ -101,13 +110,13 @@ public class PropertyDB { * Retrieve a persisted format string. * * @param key - * The name of the format string. + * The name of the format string. * * @return The format string with that name. */ public static String getFormat(String key) { return loadLock.read(() -> { - if (!formats.containsKey(key)) { + if(!formats.containsKey(key)) { String msg = String.format("No format string named '%s' found", key); throw new NoSuchElementException(msg); @@ -118,13 +127,14 @@ public class PropertyDB { } /** - * Retrieve a persisted format string, and apply it to a set of arguments. + * Retrieve a persisted format string, and apply it to a set of + * arguments. * * @param key - * The name of the format string. + * The name of the format string. * * @param objects - * The parameters to the format string. + * The parameters to the format string. * * @return The format string with that name. */ diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BooleanToggle.java b/BJC-Utils2/src/main/java/bjc/utils/data/BooleanToggle.java new file mode 100644 index 0000000..68399a0 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/BooleanToggle.java @@ -0,0 +1,76 @@ +package bjc.utils.data; + +/** + * A simple {@link ValueToggle} that swaps between true and false. + * + * @author EVE + * + */ +public class BooleanToggle implements Toggle<Boolean> { + private boolean val; + + /** + * Create a new, initially false, flip-flop. + */ + public BooleanToggle() { + this(false); + } + + /** + * Create a flip-flop with the specified initial value. + * + * @param initial + * The initial value of the flip-flop. + */ + public BooleanToggle(boolean initial) { + val = initial; + } + + @Override + public Boolean get() { + boolean res = val; + + val = !res; + + return res; + } + + @Override + public Boolean peek() { + return val; + } + + @Override + public void set(boolean vl) { + val = vl; + } + + @Override + public int hashCode() { + final int prime = 31; + + int result = 1; + + result = prime * result + (val ? 1231 : 1237); + + return result; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + if(obj == null) return false; + if(!(obj instanceof BooleanToggle)) return false; + + BooleanToggle other = (BooleanToggle) obj; + + if(val != other.val) return false; + + return true; + } + + @Override + public String toString() { + return String.format("BooleanToggle [val=%s]", val); + } +}
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Toggle.java b/BJC-Utils2/src/main/java/bjc/utils/data/Toggle.java new file mode 100644 index 0000000..8ebc4d8 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/Toggle.java @@ -0,0 +1,35 @@ +package bjc.utils.data; + +/** + * A stateful holder that swaps between two values of the same type. + * + * @author EVE + * + * @param <E> + * The value stored in the toggle. + */ +public interface Toggle<E> { + /** + * Retrieve the currently-aligned value of this toggle, and swap the + * alignment. + * + * @return The previously-aligned value. + */ + E get(); + + /** + * Retrieve the currently-aligned value without altering the alignment. + * + * @return The currently-aligned value. + */ + E peek(); + + /** + * Change the alignment of the toggle. + * + * @param isLeft + * Whether the toggle should be left-aligned or not. + */ + void set(boolean isLeft); + +}
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/ValueToggle.java b/BJC-Utils2/src/main/java/bjc/utils/data/ValueToggle.java new file mode 100644 index 0000000..5b5cb83 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/ValueToggle.java @@ -0,0 +1,58 @@ +package bjc.utils.data; + +/** + * A simple implementation of {@link Toggle}. + * + * @author EVE + * + * @param <E> + * The type of value to toggle between. + */ +public class ValueToggle<E> implements Toggle<E> { + private final E lft; + private final E rght; + + private BooleanToggle alignment; + + /** + * Create a new toggle. + * + * All toggles start right-aligned. + * + * @param left + * The value when the toggle is left-aligned. + * + * @param right + * The value when the toggle is right-aligned. + */ + public ValueToggle(E left, E right) { + lft = left; + + rght = right; + + alignment = new BooleanToggle(); + } + + @Override + public E get() { + if(alignment.get()) { + return lft; + } else { + return rght; + } + } + + @Override + public E peek() { + if(alignment.peek()) { + return lft; + } else { + return rght; + } + } + + @Override + public void set(boolean isLeft) { + alignment.set(isLeft); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java index cf60ed6..d92d564 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java @@ -42,6 +42,28 @@ public interface IList<ContainedType> extends Iterable<ContainedType> { } /** + * Add all of the elements in the provided array to this list. + * + * @param items + * The array of items to add. + * + * @return True if every item was successfully added to the list, false + * otherwise. + */ + @SuppressWarnings("unchecked") + default boolean addAll(ContainedType... items) { + boolean succ = true; + + for(ContainedType item : items) { + boolean addSucc = add(item); + + succ = succ ? addSucc : false; + } + + return succ; + } + + /** * Check if all of the elements of this list match the specified * predicate. * @@ -238,6 +260,19 @@ public interface IList<ContainedType> extends Iterable<ContainedType> { void prepend(ContainedType item); /** + * Prepend an array of items to the list. + * + * @param items + * The items to prepend to the list. + */ + @SuppressWarnings("unchecked") + default void prependAll(ContainedType... items) { + for(ContainedType item : items) { + prepend(item); + } + } + + /** * Select a random item from the list, using a default random number * generator * diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java index 27666dd..ad0f565 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java @@ -1,11 +1,9 @@ package bjc.utils.funcutils; -import bjc.utils.data.IPair; import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.IList; import java.util.ArrayList; -import java.util.Deque; import java.util.Iterator; import java.util.function.Function; import java.util.function.Supplier; @@ -29,40 +27,38 @@ public class ListUtils { * @return The collapsed string of tokens */ public static String collapseTokens(IList<String> input) { - if (input == null) - throw new NullPointerException("Input must not be null"); + if(input == null) throw new NullPointerException("Input must not be null"); return collapseTokens(input, ""); } /** * Collapse a string of tokens into a single string, adding the desired - * seperator after each token + * separator after each token * * @param input * The list of tokens to collapse * @param seperator - * The seperator to use for seperating tokens + * The separator to use for separating tokens * @return The collapsed string of tokens */ public static String collapseTokens(IList<String> input, String seperator) { - if (input == null) + if(input == null) throw new NullPointerException("Input must not be null"); - else if (seperator == null) - throw new NullPointerException("Seperator must not be null"); + else if(seperator == null) throw new NullPointerException("Seperator must not be null"); - if (input.getSize() < 1) + if(input.getSize() < 1) return ""; - else if (input.getSize() == 1) + else if(input.getSize() == 1) return input.first(); else { StringBuilder state = new StringBuilder(); int i = 1; - for (String itm : input.toIterable()) { + for(String itm : input.toIterable()) { state.append(itm); - if (i != input.getSize()) { + if(i != input.getSize()) { state.append(seperator); } @@ -74,22 +70,6 @@ public class ListUtils { } /** - * Split off affixes from tokens - * - * @param input - * The tokens to deaffix - * @param operators - * The affixes to remove - * @return The tokens that have been deaffixed - * - * @deprecated Replaced by SimpleTokenSplitter. - */ - @Deprecated - public static IList<String> deAffixTokens(IList<String> input, Deque<IPair<String, String>> operators) { - return null; - } - - /** * Select a number of random items from the list without replacement * * @param <E> @@ -113,7 +93,7 @@ public class ListUtils { Iterator<E> itr = list.toIterable().iterator(); E element = null; - for (int index = 0; itr.hasNext(); element = itr.next()) { + for(int index = 0; itr.hasNext(); element = itr.next()) { // n - m int winningChance = number - selected.getSize(); @@ -121,7 +101,7 @@ public class ListUtils { int totalChance = total - (index - 1); // Probability of selecting the t+1'th element - if (NumberUtils.isProbable(winningChance, totalChance, rng)) { + if(NumberUtils.isProbable(winningChance, totalChance, rng)) { selected.add(element); } } @@ -147,7 +127,7 @@ public class ListUtils { public static <E> IList<E> drawWithReplacement(IList<E> list, int number, Function<Integer, Integer> rng) { IList<E> selected = new FunctionalList<>(new ArrayList<>(number)); - for (int i = 0; i < number; i++) { + for(int i = 0; i < number; i++) { selected.add(list.randItem(rng)); } @@ -173,11 +153,11 @@ public class ListUtils { */ public static <E> IList<IList<E>> groupPartition(IList<E> input, Function<E, Integer> counter, int partitionSize) { - if (input == null) + if(input == null) throw new NullPointerException("Input list must not be null"); - else if (counter == null) + else if(counter == null) throw new NullPointerException("Counter must not be null"); - else if (partitionSize < 1 || partitionSize > input.getSize()) { + else if(partitionSize < 1 || partitionSize > input.getSize()) { String fmt = "%d is not a valid partition size. Must be between 1 and %d"; String msg = String.format(fmt, partitionSize, input.getSize()); @@ -199,13 +179,13 @@ public class ListUtils { /* * Run up to a certain number of passes */ - for (int numberOfIterations = 0; numberOfIterations < MAX_NTRIESPART + for(int numberOfIterations = 0; numberOfIterations < MAX_NTRIESPART && !rejected.isEmpty(); numberOfIterations++) { input.forEach(it); - if (rejected.isEmpty()) // Nothing was rejected, so - // we're - // done + if(rejected.isEmpty()) // Nothing was rejected, so + // we're + // done return returned; } @@ -229,8 +209,8 @@ public class ListUtils { public static <E> IList<E> mergeLists(IList<E>... lists) { IList<E> returned = new FunctionalList<>(); - for (IList<E> list : lists) { - for (E itm : list.toIterable()) { + for(IList<E> list : lists) { + for(E itm : list.toIterable()) { returned.add(itm); } } @@ -260,22 +240,22 @@ public class ListUtils { IList<E> returned = new FunctionalList<>(); - for (E itm : list.toIterable()) { + for(E itm : list.toIterable()) { count += counter.apply(itm); returned.add(itm); } - if (count % size != 0) { + if(count % size != 0) { // We need to pad int needed = count % size; int threshold = 0; - while (needed > 0 && threshold <= MAX_NTRIESPART) { + while(needed > 0 && threshold <= MAX_NTRIESPART) { E val = padder.get(); int newCount = counter.apply(val); - if (newCount <= needed) { + if(newCount <= needed) { returned.add(val); threshold = 0; @@ -286,31 +266,11 @@ public class ListUtils { } } - if (threshold > MAX_NTRIESPART) + if(threshold > MAX_NTRIESPART) throw new IllegalArgumentException("Heuristic (more than " + MAX_NTRIESPART + " iterations of attempting to pad) detected unpaddable list "); } return returned; } - - /** - * Split tokens in a list of tokens into multiple tokens. - * - * The intended use is for expression parsers so that you can enter - * something like 1+1 instead of 1 + 1. - * - * @param input - * The tokens to split - * @param operators - * Pairs of operators to split on and regexes that match - * those operators - * @return A list of tokens split on all the operators - * - * @deprecated Use SimpleTokenSplitter now - */ - @Deprecated - public static IList<String> splitTokens(IList<String> input, Deque<IPair<String, String>> operators) { - return null; - } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/RegexStringEditor.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/RegexStringEditor.java index 2825346..4f66a99 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/RegexStringEditor.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/RegexStringEditor.java @@ -1,7 +1,12 @@ package bjc.utils.ioutils; +import bjc.utils.data.Toggle; +import bjc.utils.data.ValueToggle; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IList; import bjc.utils.functypes.ID; +import java.util.function.BiFunction; import java.util.function.UnaryOperator; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -13,6 +18,8 @@ import java.util.regex.Pattern; * */ public class RegexStringEditor { + private static final UnaryOperator<String> SID = ID.id(); + /** * Replace every occurrence of the pattern with the result of applying * the action to the string matched by the pattern. @@ -29,7 +36,7 @@ public class RegexStringEditor { * @return The string, with matches replaced with the action. */ public static String onOccurances(String input, Pattern patt, UnaryOperator<String> action) { - return occurances(input, patt, ID.id(), action); + return reduceOccurances(input, patt, SID, action); } /** @@ -49,7 +56,7 @@ public class RegexStringEditor { * the action. */ public static String betweenOccurances(String input, Pattern patt, UnaryOperator<String> action) { - return occurances(input, patt, action, ID.id()); + return reduceOccurances(input, patt, action, SID); } /** @@ -58,7 +65,7 @@ public class RegexStringEditor { * @param input * The input string. * - * @param patt + * @param rPatt * The pattern to match against the string. * * @param betweenAction @@ -69,11 +76,59 @@ public class RegexStringEditor { * * @return The string, with both actions applied. */ - public static String occurances(String input, Pattern patt, UnaryOperator<String> betweenAction, + public static String reduceOccurances(String input, Pattern rPatt, UnaryOperator<String> betweenAction, UnaryOperator<String> onAction) { - Matcher matcher = patt.matcher(input); + IList<String> occurances = listOccurances(input, rPatt); + + Toggle<UnaryOperator<String>> actions = new ValueToggle<>(onAction, betweenAction); + BiFunction<String, StringBuilder, StringBuilder> reducer = (strang, state) -> { + return state.append(actions.get().apply(strang)); + }; + + return occurances.reduceAux(new StringBuilder(), reducer, StringBuilder::toString); + } + + /** + * Execute actions between and on matches of a regular expression. + * + * @param input + * The input string. + * + * @param rPatt + * The pattern to match against the string. + * + * @param betweenAction + * The function to execute between matches of the string. + * + * @param onAction + * The function to execute on matches of the string. + * + * @return The string, with both actions applied. + */ + public static IList<String> mapOccurances(String input, Pattern rPatt, UnaryOperator<String> betweenAction, + UnaryOperator<String> onAction) { + IList<String> occurances = listOccurances(input, rPatt); + Toggle<UnaryOperator<String>> actions = new ValueToggle<>(onAction, betweenAction); + + return occurances.map(strang -> actions.get().apply(strang)); + } + + /** + * Separate a string into match/non-match segments. + * + * @param input + * The string to separate. + * + * @param rPatt + * The pattern to use for separation. + * + * @return The string, as a list of match/non-match segments, + * starting/ending with a non-match segment. + */ + public static IList<String> listOccurances(String input, Pattern rPatt) { + IList<String> res = new FunctionalList<>(); - StringBuffer res = new StringBuffer(); + Matcher matcher = rPatt.matcher(input); StringBuffer work = new StringBuffer(); @@ -82,17 +137,17 @@ public class RegexStringEditor { matcher.appendReplacement(work, ""); - res.append(betweenAction.apply(matcher.toString())); - res.append(onAction.apply(match)); + res.add(work.toString()); + res.add(match); work = new StringBuffer(); } matcher.appendTail(work); - res.append(betweenAction.apply(work.toString())); + res.add(work.toString()); - return res.toString(); + return res; } /** diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/SimpleProperties.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/SimpleProperties.java index a43b16a..531e8b8 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/SimpleProperties.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/SimpleProperties.java @@ -32,27 +32,25 @@ public class SimpleProperties implements Map<String, String> { * All leading/trailing spaces from the name & body are removed. * * @param is - * The stream to read from. + * The stream to read from. * * @param allowDuplicates - * Whether or not duplicate keys should be allowed. + * Whether or not duplicate keys should be allowed. */ public void loadFrom(InputStream is, boolean allowDuplicates) { - try (Scanner scn = new Scanner(is)) { - while (scn.hasNextLine()) { + try(Scanner scn = new Scanner(is)) { + while(scn.hasNextLine()) { String ln = scn.nextLine().trim(); /* * Skip blank lines/comments */ - if (ln.equals("")) - continue; - if (ln.startsWith("#")) - continue; + if(ln.equals("")) continue; + if(ln.startsWith("#")) continue; int sepIdx = ln.indexOf(' '); - if (sepIdx == -1) { + if(sepIdx == -1) { String fmt = "Properties must be a name, a space, then the body.\n\tOffending line is '%s'"; String msg = String.format(fmt, ln); @@ -62,7 +60,7 @@ public class SimpleProperties implements Map<String, String> { String name = ln.substring(0, sepIdx).trim(); String body = ln.substring(sepIdx).trim(); - if (!allowDuplicates && containsKey(name)) { + if(!allowDuplicates && containsKey(name)) { String msg = String.format("Duplicate key '%s'", name); throw new IllegalStateException(msg); @@ -71,13 +69,19 @@ public class SimpleProperties implements Map<String, String> { put(name, body); } } + } + /** + * Output the set of read properties. + */ + public void outputProperties() { System.out.println("Read properties:"); - for (Entry<String, String> entry : entrySet()) { + + for(Entry<String, String> entry : entrySet()) { System.out.printf("\t'%s'\t'%s'\n", entry.getKey(), entry.getValue()); } - System.out.println(); + System.out.println(); } @Override diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenUtils.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenUtils.java index 1d31522..39e0c4e 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenUtils.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TokenUtils.java @@ -1,5 +1,9 @@ package bjc.utils.parserutils; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IList; +import bjc.utils.parserutils.splitterv2.TokenSplitter; + import java.util.LinkedList; import java.util.List; import java.util.regex.Matcher; @@ -17,6 +21,17 @@ import static bjc.utils.PropertyDB.applyFormat; * TODO add support for user defined escapes. */ public class TokenUtils { + /** + * @author EVE + * + */ + public static class StringTokenSplitter implements TokenSplitter { + @Override + public IList<String> split(String input) { + return new FunctionalList<>(TokenUtils.removeDQuotedStrings(input)); + } + } + /* * Patterns and pattern parts. */ diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/SimpleTokenSplitter.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/SimpleTokenSplitter.java index 170c619..ccc823d 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/SimpleTokenSplitter.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/SimpleTokenSplitter.java @@ -1,7 +1,5 @@ package bjc.utils.parserutils.splitter; -import bjc.utils.ioutils.RegexStringEditor; - import java.util.HashSet; import java.util.Set; import java.util.regex.Pattern; @@ -10,9 +8,8 @@ import java.util.regex.Pattern; * Simple implementation of {@link TokenSplitter} * * @author EVE - * - * TODO rewrite using {@link RegexStringEditor} */ +@Deprecated public class SimpleTokenSplitter implements TokenSplitter { /* * This string is a format template for the delimiter matching regex diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/TokenSplitter.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/TokenSplitter.java index e59d88e..04551a7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/TokenSplitter.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/TokenSplitter.java @@ -5,6 +5,7 @@ package bjc.utils.parserutils.splitter; * * @author Ben Culkin */ +@Deprecated public interface TokenSplitter { /** * Split a provided string using configured delimiters, and keeping the diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/TwoLevelSplitter.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/TwoLevelSplitter.java index d65b06a..1d6d0a2 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/TwoLevelSplitter.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/splitter/TwoLevelSplitter.java @@ -18,6 +18,7 @@ import java.util.regex.Pattern; * @author EVE * */ +@Deprecated public class TwoLevelSplitter implements TokenSplitter { private SimpleTokenSplitter high; private SimpleTokenSplitter low; |
