From d766896972c9e9be4a9e0021ec5f4f0665901865 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Sat, 9 Sep 2017 21:46:16 -0300 Subject: Update Most of it is documentation changes. The rest is more work on BlockReaders, as well as a simple command language for configuring them. --- .../bjc/utils/ioutils/RuleBasedConfigReader.java | 120 +++++++++++++++------ 1 file changed, 85 insertions(+), 35 deletions(-) (limited to 'BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java') diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java index 4216544..7c5205b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java @@ -26,21 +26,27 @@ import bjc.utils.funcdata.IMap; * */ public class RuleBasedConfigReader { - // Function to execute when starting a rule - // Takes the tokenizer, and a pair of the read token and application - // state + /* 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 + /* + * 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 + /* + * 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 + /* + * Map of pragma names to pragma actions + * Pragma actions are functions taking a tokenizer and application state + */ private final IMap> pragmas; /** @@ -71,8 +77,7 @@ public class RuleBasedConfigReader { * The function to execute when this pragma is read */ public void addPragma(final String name, final BiConsumer action) { - if (name == null) - throw new NullPointerException("Pragma name must not be null"); + 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); @@ -85,23 +90,35 @@ public class RuleBasedConfigReader { else if (continueRule == null) throw new InputMismatchException("Rule continuation not supported for current grammar"); - // Accept the rule + /* + * Accept the rule + */ continueRule.accept(new FunctionalStringTokenizer(line.substring(1), " "), state); } private boolean endRule(final E state, final boolean isRuleOpen) { - // Ignore blank line without an open rule + /* + * Ignore blank line without an open rule + */ if (isRuleOpen == false) - // Do nothing + /* + * Do nothing + */ return false; else { - // Nothing happens on rule end + /* + * Nothing happens on rule end + */ if (end != null) { - // Process the rule ending + /* + * Process the rule ending + */ end.accept(state); } - // Return a closed rule + /* + * Return a closed rule + */ return false; } } @@ -118,37 +135,56 @@ public class RuleBasedConfigReader { public E fromStream(final InputStream input, final E initialState) { if (input == null) throw new NullPointerException("Input stream must not be null"); - // Application state: We're giving this back later + /* + * Application state: We're giving this back later + */ final E state = initialState; - // Prepare our input source + /* + * Prepare our input source + */ try (Scanner source = new Scanner(input)) { source.useDelimiter("\n"); - // This is true when a rule's open + /* + * This is true when a rule's open + */ final IHolder isRuleOpen = new Identity<>(false); - // Do something for every line of the file + /* + * Do something for every line of the file + */ source.forEachRemaining((line) -> { - // Skip comment lines + /* + * Skip comment lines + */ if (line.startsWith("#") || line.startsWith("//")) - // It's a comment + /* + * It's a comment + */ return; else if (line.equals("")) { - // End the rule + /* + * End the rule + */ isRuleOpen.replace(endRule(state, isRuleOpen.getValue())); } else if (line.startsWith("\t")) { - // Continue the rule + /* + * Continue the rule + */ continueRule(state, isRuleOpen.getValue(), line); } else { - // Open a rule + /* + * Open a rule + */ isRuleOpen.replace(startRule(state, isRuleOpen.getValue(), line)); } }); } - // Return the state that the user has created + /* + * Return the state that the user has created + */ return state; - } /** @@ -184,27 +220,41 @@ public class RuleBasedConfigReader { } private boolean startRule(final E state, boolean isRuleOpen, final String line) { - // Create the line tokenizer + /* + * Create the line tokenizer + */ final FunctionalStringTokenizer tokenizer = new FunctionalStringTokenizer(line, " "); - // Get the initial token + /* + * Get the initial token + */ final String nextToken = tokenizer.nextToken(); - // Handle pragmas + /* + * Handle pragmas + */ if (nextToken.equals("pragma")) { - // Get the pragma name + /* + * Get the pragma name + */ final String token = tokenizer.nextToken(); - // Handle pragmas + /* + * Handle pragmas + */ pragmas.getOrDefault(token, (tokenzer, stat) -> { throw new UnknownPragmaException("Unknown pragma " + token); }).accept(tokenizer, state); } else { - // Make sure input is correct + /* + * Make sure input is correct + */ if (isRuleOpen == true) throw new InputMismatchException("Nested rules are currently not supported"); - // Start a rule + /* + * Start a rule + */ start.accept(tokenizer, new Pair<>(nextToken, state)); isRuleOpen = true; -- cgit v1.2.3