From b53c1ef47c438fb1144b961d1939c37a4bfe9120 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Sat, 25 Mar 2017 20:34:42 -0400 Subject: Separate general I/O from parsing. --- .../components/ComponentDescriptionFileParser.java | 6 +- .../main/java/bjc/utils/ioutils/BlockReader.java | 208 ++++++++++++++++++++ .../bjc/utils/ioutils/RuleBasedConfigReader.java | 215 +++++++++++++++++++++ .../bjc/utils/ioutils/RuleBasedReaderPragmas.java | 80 ++++++++ .../java/bjc/utils/parserutils/BlockReader.java | 208 -------------------- .../utils/parserutils/RuleBasedConfigReader.java | 215 --------------------- .../utils/parserutils/RuleBasedReaderPragmas.java | 80 -------- 7 files changed, 506 insertions(+), 506 deletions(-) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/ioutils/BlockReader.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedReaderPragmas.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/BlockReader.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedReaderPragmas.java diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java index c939708..5f98ce9 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java @@ -1,11 +1,11 @@ package bjc.utils.components; -import bjc.utils.parserutils.RuleBasedConfigReader; +import static bjc.utils.ioutils.RuleBasedReaderPragmas.buildInteger; +import static bjc.utils.ioutils.RuleBasedReaderPragmas.buildStringCollapser; import java.io.InputStream; -import static bjc.utils.parserutils.RuleBasedReaderPragmas.buildInteger; -import static bjc.utils.parserutils.RuleBasedReaderPragmas.buildStringCollapser; +import bjc.utils.ioutils.RuleBasedConfigReader; /** * Read a component description from a file diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/BlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/BlockReader.java new file mode 100644 index 0000000..33bbbd5 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/BlockReader.java @@ -0,0 +1,208 @@ +package bjc.utils.ioutils; + +import java.io.LineNumberReader; +import java.io.Reader; +import java.util.NoSuchElementException; +import java.util.Scanner; +import java.util.function.Consumer; +import java.util.regex.Pattern; + +/** + * Implements reading numbered blocks from a source. + * + * A block is a series of characters, seperated by some regular expression. + * + * NOTE: The EOF marker is always treated as a delimiter. You are expected to + * handle blocks that may be shorter than you expect. + * + * @author EVE + * + */ +public class BlockReader implements AutoCloseable { + /** + * Represents a block of text read in from a source. + * + * @author EVE + * + */ + public static class Block { + /** + * The contents of this block. + */ + public final String contents; + + /** + * The line of the source this block started on. + */ + public final int startLine; + + /** + * The line of the source this block ended on. + */ + public final int endLine; + + /** + * The number of this block. + */ + public final int blockNo; + + /** + * Create a new block. + * + * @param blockNo + * The number of this block. + * @param contents + * The contents of this block. + * @param startLine + * The line this block started on. + * @param endLine + * The line this block ended. + */ + public Block(int blockNo, String contents, int startLine, int endLine) { + this.contents = contents; + this.startLine = startLine; + this.endLine = endLine; + this.blockNo = blockNo; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + + result = prime * result + blockNo; + result = prime * result + ((contents == null) ? 0 : contents.hashCode()); + result = prime * result + endLine; + result = prime * result + startLine; + + return result; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + if(obj == null) return false; + if(!(obj instanceof Block)) return false; + + Block other = (Block) obj; + + if(blockNo != other.blockNo) return false; + + if(contents == null) { + if(other.contents != null) return false; + } else if(!contents.equals(other.contents)) return false; + + if(endLine != other.endLine) return false; + if(startLine != other.startLine) return false; + + return true; + } + + @Override + public String toString() { + return String.format("Block #%d (from lines %d to %d) length: %d characters", blockNo, startLine, + endLine, contents.length()); + } + } + + /* + * I/O source for blocks. + */ + private LineNumberReader lnReader; + private Scanner blockReader; + + /* + * The current block. + */ + private Block currBlock; + private int blockNo; + + /** + * Create a new block reader. + * + * @param blockDelim + * The pattern that separates blocks. Note that the end + * of file is always considered to end a block. + * + * @param source + * The source to read blocks from. + */ + public BlockReader(String blockDelim, Reader source) { + lnReader = new LineNumberReader(source); + + blockReader = new Scanner(lnReader); + + String pattern = String.format("(?:%s)|\\Z", blockDelim); + Pattern pt = Pattern.compile(pattern, Pattern.MULTILINE); + + blockReader.useDelimiter(pt); + } + + /** + * Check if this reader has an available block. + * + * @return Whether or not another block is available. + */ + public boolean hasNextBlock() { + return blockReader.hasNext(); + } + + /** + * Get the current block. + * + * @return The current block, or null if there is no current block. + */ + public Block getBlock() { + return currBlock; + } + + /** + * Move to the next block. + * + * @return Whether or not the next block was succesfully read. + */ + public boolean nextBlock() { + try { + int blockStartLine = lnReader.getLineNumber(); + String blockContents = blockReader.next(); + int blockEndLine = lnReader.getLineNumber(); + blockNo += 1; + + currBlock = new Block(blockNo, blockContents, blockStartLine, blockEndLine); + + return true; + } catch(NoSuchElementException nseex) { + return false; + } + } + + /** + * Execute an action for each remaining block. + * + * @param action + * The action to execute for each block + */ + public void forEachBlock(Consumer action) { + while(hasNextBlock()) { + nextBlock(); + + action.accept(currBlock); + } + } + + /** + * Retrieve the number of blocks that have been read so far. + * + * @return The number of blocks read so far. + */ + public int getBlockCount() { + return blockNo; + } + + @Override + public void close() throws Exception { + blockReader.close(); + + lnReader.close(); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java new file mode 100644 index 0000000..b4d56a1 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java @@ -0,0 +1,215 @@ +package bjc.utils.ioutils; + +import bjc.utils.data.IHolder; +import bjc.utils.data.IPair; +import bjc.utils.data.Identity; +import bjc.utils.data.Pair; +import bjc.utils.exceptions.UnknownPragmaException; +import bjc.utils.funcdata.FunctionalMap; +import bjc.utils.funcdata.FunctionalStringTokenizer; +import bjc.utils.funcdata.IMap; + +import java.io.InputStream; +import java.util.InputMismatchException; +import java.util.Scanner; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +/** + * This class parses a rules based config file, and uses it to drive a provided + * set of actions + * + * @author ben + * + * @param + * The type of the state object to use + * + */ +public class RuleBasedConfigReader { + // Function to execute when starting a rule + // Takes the tokenizer, and a pair of the read token and application + // state + private BiConsumer> start; + + // Function to use when continuing a rule + // Takes a tokenizer and application state + private BiConsumer continueRule; + + // Function to use when ending a rule + // Takes an application state + private Consumer end; + + // Map of pragma names to pragma actions + // Pragma actions are functions taking a tokenizer and application state + private IMap> pragmas; + + /** + * Create a new rule-based config reader + * + * @param start + * The action to fire when starting a rule + * @param continueRule + * The action to fire when continuing a rule + * @param end + * The action to fire when ending a rule + */ + public RuleBasedConfigReader(BiConsumer> start, + BiConsumer continueRule, Consumer end) { + this.start = start; + this.continueRule = continueRule; + this.end = end; + + this.pragmas = new FunctionalMap<>(); + } + + /** + * Add a pragma to this reader + * + * @param name + * The name of the pragma to add + * @param action + * The function to execute when this pragma is read + */ + public void addPragma(String name, BiConsumer action) { + if(name == null) + throw new NullPointerException("Pragma name must not be null"); + else if(action == null) throw new NullPointerException("Pragma action must not be null"); + + pragmas.put(name, action); + } + + private void continueRule(E state, boolean isRuleOpen, String line) { + // Make sure our input is correct + if(isRuleOpen == false) + throw new InputMismatchException("Cannot continue rule with no rule open"); + else if(continueRule == null) + throw new InputMismatchException("Rule continuation not supported for current grammar"); + + // Accept the rule + continueRule.accept(new FunctionalStringTokenizer(line.substring(1), " "), state); + } + + private boolean endRule(E state, boolean isRuleOpen) { + // Ignore blank line without an open rule + if(isRuleOpen == false) + // Do nothing + return false; + else { + // Nothing happens on rule end + if(end != null) { + // Process the rule ending + end.accept(state); + } + + // Return a closed rule + return false; + } + } + + /** + * Run a stream through this reader + * + * @param input + * The stream to get input + * @param initialState + * The initial state of the reader + * @return The final state of the reader + */ + public E fromStream(InputStream input, E initialState) { + if(input == null) throw new NullPointerException("Input stream must not be null"); + + // Application state: We're giving this back later + E state = initialState; + + // Prepare our input source + try(Scanner source = new Scanner(input)) { + source.useDelimiter("\n"); + // This is true when a rule's open + IHolder isRuleOpen = new Identity<>(false); + + // Do something for every line of the file + source.forEachRemaining((line) -> { + // Skip comment lines + if(line.startsWith("#") || line.startsWith("//")) + // It's a comment + return; + else if(line.equals("")) { + // End the rule + isRuleOpen.replace(endRule(state, isRuleOpen.getValue())); + } else if(line.startsWith("\t")) { + // Continue the rule + continueRule(state, isRuleOpen.getValue(), line); + } else { + // Open a rule + isRuleOpen.replace(startRule(state, isRuleOpen.getValue(), line)); + } + }); + } + + // Return the state that the user has created + return state; + + } + + /** + * Set the action to execute when continuing a rule + * + * @param continueRule + * The action to execute on continuation of a rule + */ + public void setContinueRule(BiConsumer continueRule) { + this.continueRule = continueRule; + } + + /** + * Set the action to execute when ending a rule + * + * @param end + * The action to execute on ending of a rule + */ + public void setEndRule(Consumer end) { + this.end = end; + } + + /** + * Set the action to execute when starting a rule + * + * @param start + * The action to execute on starting of a rule + */ + public void setStartRule(BiConsumer> start) { + if(start == null) throw new NullPointerException("Action on rule start must be non-null"); + + this.start = start; + } + + private boolean startRule(E state, boolean isRuleOpen, String line) { + // Create the line tokenizer + FunctionalStringTokenizer tokenizer = new FunctionalStringTokenizer(line, " "); + + // Get the initial token + String nextToken = tokenizer.nextToken(); + + // Handle pragmas + if(nextToken.equals("pragma")) { + // Get the pragma name + String token = tokenizer.nextToken(); + + // Handle pragmas + pragmas.getOrDefault(token, (tokenzer, stat) -> { + throw new UnknownPragmaException("Unknown pragma " + token); + }).accept(tokenizer, state); + } else { + // Make sure input is correct + if(isRuleOpen == true) + throw new InputMismatchException("Nested rules are currently not supported"); + + // Start a rule + start.accept(tokenizer, new Pair<>(nextToken, state)); + + isRuleOpen = true; + } + + return isRuleOpen; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedReaderPragmas.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedReaderPragmas.java new file mode 100644 index 0000000..f19eb2c --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedReaderPragmas.java @@ -0,0 +1,80 @@ +package bjc.utils.ioutils; + +import bjc.utils.exceptions.PragmaFormatException; +import bjc.utils.funcdata.FunctionalStringTokenizer; +import bjc.utils.funcutils.ListUtils; + +import java.util.function.BiConsumer; + +/** + * Contains factory methods for common pragma types + * + * @author ben + * + */ +public class RuleBasedReaderPragmas { + + /** + * Creates a pragma that takes a single integer argument + * + * @param + * The type of state that goes along with this pragma + * @param name + * The name of this pragma, for error message purpose + * @param consumer + * The function to invoke with the parsed integer + * @return A pragma that functions as described above. + */ + public static BiConsumer buildInteger(String name, + BiConsumer consumer) { + return (tokenizer, state) -> { + // Check our input is correct + if(!tokenizer.hasMoreTokens()) + throw new PragmaFormatException("Pragma " + name + " requires one integer argument"); + + // Read the argument + String token = tokenizer.nextToken(); + + try { + // Run the pragma + consumer.accept(Integer.parseInt(token), state); + } catch(NumberFormatException nfex) { + // Tell the user their argument isn't correct + PragmaFormatException pfex = new PragmaFormatException( + "Argument " + token + " to " + name + " pragma isn't a valid integer. " + + "This pragma requires a integer argument"); + + pfex.initCause(nfex); + + throw pfex; + } + }; + } + + /** + * Creates a pragma that takes any number of arguments and collapses + * them all into a single string + * + * @param + * The type of state that goes along with this pragma + * @param name + * The name of this pragma, for error message purpose + * @param consumer + * The function to invoke with the parsed string + * @return A pragma that functions as described above. + */ + public static BiConsumer buildStringCollapser(String name, + BiConsumer consumer) { + return (tokenizer, state) -> { + // Check our input + if(!tokenizer.hasMoreTokens()) throw new PragmaFormatException( + "Pragma " + name + " requires one or more string arguments"); + + // Build our argument + String collapsed = ListUtils.collapseTokens(tokenizer.toList()); + + // Run the pragma + consumer.accept(collapsed, state); + }; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/BlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/BlockReader.java deleted file mode 100644 index 1f0d6d0..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/BlockReader.java +++ /dev/null @@ -1,208 +0,0 @@ -package bjc.utils.parserutils; - -import java.io.LineNumberReader; -import java.io.Reader; -import java.util.NoSuchElementException; -import java.util.Scanner; -import java.util.function.Consumer; -import java.util.regex.Pattern; - -/** - * Implements reading numbered blocks from a source. - * - * A block is a series of characters, seperated by some regular expression. - * - * NOTE: The EOF marker is always treated as a delimiter. You are expected to - * handle blocks that may be shorter than you expect. - * - * @author EVE - * - */ -public class BlockReader implements AutoCloseable { - /** - * Represents a block of text read in from a source. - * - * @author EVE - * - */ - public static class Block { - /** - * The contents of this block. - */ - public final String contents; - - /** - * The line of the source this block started on. - */ - public final int startLine; - - /** - * The line of the source this block ended on. - */ - public final int endLine; - - /** - * The number of this block. - */ - public final int blockNo; - - /** - * Create a new block. - * - * @param blockNo - * The number of this block. - * @param contents - * The contents of this block. - * @param startLine - * The line this block started on. - * @param endLine - * The line this block ended. - */ - public Block(int blockNo, String contents, int startLine, int endLine) { - this.contents = contents; - this.startLine = startLine; - this.endLine = endLine; - this.blockNo = blockNo; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - - result = prime * result + blockNo; - result = prime * result + ((contents == null) ? 0 : contents.hashCode()); - result = prime * result + endLine; - result = prime * result + startLine; - - return result; - } - - @Override - public boolean equals(Object obj) { - if(this == obj) return true; - if(obj == null) return false; - if(!(obj instanceof Block)) return false; - - Block other = (Block) obj; - - if(blockNo != other.blockNo) return false; - - if(contents == null) { - if(other.contents != null) return false; - } else if(!contents.equals(other.contents)) return false; - - if(endLine != other.endLine) return false; - if(startLine != other.startLine) return false; - - return true; - } - - @Override - public String toString() { - return String.format("Block #%d (from lines %d to %d) length: %d characters", blockNo, startLine, - endLine, contents.length()); - } - } - - /* - * I/O source for blocks. - */ - private LineNumberReader lnReader; - private Scanner blockReader; - - /* - * The current block. - */ - private Block currBlock; - private int blockNo; - - /** - * Create a new block reader. - * - * @param blockDelim - * The pattern that separates blocks. Note that the end - * of file is always considered to end a block. - * - * @param source - * The source to read blocks from. - */ - public BlockReader(String blockDelim, Reader source) { - lnReader = new LineNumberReader(source); - - blockReader = new Scanner(lnReader); - - String pattern = String.format("(?:%s)|\\Z", blockDelim); - Pattern pt = Pattern.compile(pattern, Pattern.MULTILINE); - - blockReader.useDelimiter(pt); - } - - /** - * Check if this reader has an available block. - * - * @return Whether or not another block is available. - */ - public boolean hasNextBlock() { - return blockReader.hasNext(); - } - - /** - * Get the current block. - * - * @return The current block, or null if there is no current block. - */ - public Block getBlock() { - return currBlock; - } - - /** - * Move to the next block. - * - * @return Whether or not the next block was succesfully read. - */ - public boolean nextBlock() { - try { - int blockStartLine = lnReader.getLineNumber(); - String blockContents = blockReader.next(); - int blockEndLine = lnReader.getLineNumber(); - blockNo += 1; - - currBlock = new Block(blockNo, blockContents, blockStartLine, blockEndLine); - - return true; - } catch(NoSuchElementException nseex) { - return false; - } - } - - /** - * Execute an action for each remaining block. - * - * @param action - * The action to execute for each block - */ - public void forEachBlock(Consumer action) { - while(hasNextBlock()) { - nextBlock(); - - action.accept(currBlock); - } - } - - /** - * Retrieve the number of blocks that have been read so far. - * - * @return The number of blocks read so far. - */ - public int getBlockCount() { - return blockNo; - } - - @Override - public void close() throws Exception { - blockReader.close(); - - lnReader.close(); - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java deleted file mode 100644 index b26030c..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java +++ /dev/null @@ -1,215 +0,0 @@ -package bjc.utils.parserutils; - -import bjc.utils.data.IHolder; -import bjc.utils.data.IPair; -import bjc.utils.data.Identity; -import bjc.utils.data.Pair; -import bjc.utils.exceptions.UnknownPragmaException; -import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.FunctionalStringTokenizer; -import bjc.utils.funcdata.IMap; - -import java.io.InputStream; -import java.util.InputMismatchException; -import java.util.Scanner; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -/** - * This class parses a rules based config file, and uses it to drive a provided - * set of actions - * - * @author ben - * - * @param - * The type of the state object to use - * - */ -public class RuleBasedConfigReader { - // Function to execute when starting a rule - // Takes the tokenizer, and a pair of the read token and application - // state - private BiConsumer> start; - - // Function to use when continuing a rule - // Takes a tokenizer and application state - private BiConsumer continueRule; - - // Function to use when ending a rule - // Takes an application state - private Consumer end; - - // Map of pragma names to pragma actions - // Pragma actions are functions taking a tokenizer and application state - private IMap> pragmas; - - /** - * Create a new rule-based config reader - * - * @param start - * The action to fire when starting a rule - * @param continueRule - * The action to fire when continuing a rule - * @param end - * The action to fire when ending a rule - */ - public RuleBasedConfigReader(BiConsumer> start, - BiConsumer continueRule, Consumer end) { - this.start = start; - this.continueRule = continueRule; - this.end = end; - - this.pragmas = new FunctionalMap<>(); - } - - /** - * Add a pragma to this reader - * - * @param name - * The name of the pragma to add - * @param action - * The function to execute when this pragma is read - */ - public void addPragma(String name, BiConsumer action) { - if(name == null) - throw new NullPointerException("Pragma name must not be null"); - else if(action == null) throw new NullPointerException("Pragma action must not be null"); - - pragmas.put(name, action); - } - - private void continueRule(E state, boolean isRuleOpen, String line) { - // Make sure our input is correct - if(isRuleOpen == false) - throw new InputMismatchException("Cannot continue rule with no rule open"); - else if(continueRule == null) - throw new InputMismatchException("Rule continuation not supported for current grammar"); - - // Accept the rule - continueRule.accept(new FunctionalStringTokenizer(line.substring(1), " "), state); - } - - private boolean endRule(E state, boolean isRuleOpen) { - // Ignore blank line without an open rule - if(isRuleOpen == false) - // Do nothing - return false; - else { - // Nothing happens on rule end - if(end != null) { - // Process the rule ending - end.accept(state); - } - - // Return a closed rule - return false; - } - } - - /** - * Run a stream through this reader - * - * @param input - * The stream to get input - * @param initialState - * The initial state of the reader - * @return The final state of the reader - */ - public E fromStream(InputStream input, E initialState) { - if(input == null) throw new NullPointerException("Input stream must not be null"); - - // Application state: We're giving this back later - E state = initialState; - - // Prepare our input source - try(Scanner source = new Scanner(input)) { - source.useDelimiter("\n"); - // This is true when a rule's open - IHolder isRuleOpen = new Identity<>(false); - - // Do something for every line of the file - source.forEachRemaining((line) -> { - // Skip comment lines - if(line.startsWith("#") || line.startsWith("//")) - // It's a comment - return; - else if(line.equals("")) { - // End the rule - isRuleOpen.replace(endRule(state, isRuleOpen.getValue())); - } else if(line.startsWith("\t")) { - // Continue the rule - continueRule(state, isRuleOpen.getValue(), line); - } else { - // Open a rule - isRuleOpen.replace(startRule(state, isRuleOpen.getValue(), line)); - } - }); - } - - // Return the state that the user has created - return state; - - } - - /** - * Set the action to execute when continuing a rule - * - * @param continueRule - * The action to execute on continuation of a rule - */ - public void setContinueRule(BiConsumer continueRule) { - this.continueRule = continueRule; - } - - /** - * Set the action to execute when ending a rule - * - * @param end - * The action to execute on ending of a rule - */ - public void setEndRule(Consumer end) { - this.end = end; - } - - /** - * Set the action to execute when starting a rule - * - * @param start - * The action to execute on starting of a rule - */ - public void setStartRule(BiConsumer> start) { - if(start == null) throw new NullPointerException("Action on rule start must be non-null"); - - this.start = start; - } - - private boolean startRule(E state, boolean isRuleOpen, String line) { - // Create the line tokenizer - FunctionalStringTokenizer tokenizer = new FunctionalStringTokenizer(line, " "); - - // Get the initial token - String nextToken = tokenizer.nextToken(); - - // Handle pragmas - if(nextToken.equals("pragma")) { - // Get the pragma name - String token = tokenizer.nextToken(); - - // Handle pragmas - pragmas.getOrDefault(token, (tokenzer, stat) -> { - throw new UnknownPragmaException("Unknown pragma " + token); - }).accept(tokenizer, state); - } else { - // Make sure input is correct - if(isRuleOpen == true) - throw new InputMismatchException("Nested rules are currently not supported"); - - // Start a rule - start.accept(tokenizer, new Pair<>(nextToken, state)); - - isRuleOpen = true; - } - - return isRuleOpen; - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedReaderPragmas.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedReaderPragmas.java deleted file mode 100644 index 65add27..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedReaderPragmas.java +++ /dev/null @@ -1,80 +0,0 @@ -package bjc.utils.parserutils; - -import bjc.utils.exceptions.PragmaFormatException; -import bjc.utils.funcdata.FunctionalStringTokenizer; -import bjc.utils.funcutils.ListUtils; - -import java.util.function.BiConsumer; - -/** - * Contains factory methods for common pragma types - * - * @author ben - * - */ -public class RuleBasedReaderPragmas { - - /** - * Creates a pragma that takes a single integer argument - * - * @param - * The type of state that goes along with this pragma - * @param name - * The name of this pragma, for error message purpose - * @param consumer - * The function to invoke with the parsed integer - * @return A pragma that functions as described above. - */ - public static BiConsumer buildInteger(String name, - BiConsumer consumer) { - return (tokenizer, state) -> { - // Check our input is correct - if(!tokenizer.hasMoreTokens()) - throw new PragmaFormatException("Pragma " + name + " requires one integer argument"); - - // Read the argument - String token = tokenizer.nextToken(); - - try { - // Run the pragma - consumer.accept(Integer.parseInt(token), state); - } catch(NumberFormatException nfex) { - // Tell the user their argument isn't correct - PragmaFormatException pfex = new PragmaFormatException( - "Argument " + token + " to " + name + " pragma isn't a valid integer. " - + "This pragma requires a integer argument"); - - pfex.initCause(nfex); - - throw pfex; - } - }; - } - - /** - * Creates a pragma that takes any number of arguments and collapses - * them all into a single string - * - * @param - * The type of state that goes along with this pragma - * @param name - * The name of this pragma, for error message purpose - * @param consumer - * The function to invoke with the parsed string - * @return A pragma that functions as described above. - */ - public static BiConsumer buildStringCollapser(String name, - BiConsumer consumer) { - return (tokenizer, state) -> { - // Check our input - if(!tokenizer.hasMoreTokens()) throw new PragmaFormatException( - "Pragma " + name + " requires one or more string arguments"); - - // Build our argument - String collapsed = ListUtils.collapseTokens(tokenizer.toList()); - - // Run the pragma - consumer.accept(collapsed, state); - }; - } -} -- cgit v1.2.3