From a5f6bd475293d72e040a2dbb92eb145e47c09fe5 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Sun, 21 Feb 2016 18:24:05 -0500 Subject: Added parser for rule-based config files. Also, minor changes to FST --- .../utils/funcdata/FunctionalStringTokenizer.java | 19 ++++ .../utils/parserutils/RuleBasedConfigReader.java | 108 +++++++++++++++++++++ .../utils/parserutils/UnknownPragmaException.java | 12 +++ 3 files changed, 139 insertions(+) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/UnknownPragmaException.java (limited to 'BJC-Utils2') diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java index 66df7cd..ed4b9d3 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java @@ -36,6 +36,17 @@ public class FunctionalStringTokenizer { this.inp = new StringTokenizer(inp); } + /** + * Create a functional string tokenizer from a given string and set of + * seperators + * + * @param inp The string to tokenize + * @param seps The string to use for splitting + */ + public FunctionalStringTokenizer(String inp, String seps) { + this.inp = new StringTokenizer(inp, seps); + } + /** * Execute a provided action for each of the remaining tokens * @@ -84,4 +95,12 @@ public class FunctionalStringTokenizer { public static FunctionalStringTokenizer fromString(String s) { return new FunctionalStringTokenizer(new StringTokenizer(s, " ")); } + + /** + * Get the string tokenizer encapsuled by this + * @return The encapsulated tokenizer + */ + public StringTokenizer getInternal() { + return inp; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java new file mode 100644 index 0000000..1190281 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedConfigReader.java @@ -0,0 +1,108 @@ +package bjc.utils.parserutils; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +import bjc.utils.data.Pair; +import bjc.utils.funcdata.FunctionalStringTokenizer; + +/** + * 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 { + private Map> pragmas; + + private BiConsumer> startRule; + private BiConsumer continueRule; + private Consumer endRule; + + /** + * Create a new rule-based config reader + * + * @param startRule + * The action to fire when starting a rule + * @param continueRule + * The action to fire when continuing a rule + * @param endRule + * The action to fire when ending a rule + */ + public RuleBasedConfigReader( + BiConsumer> startRule, + BiConsumer continueRule, + Consumer endRule) { + this.startRule = startRule; + this.continueRule = continueRule; + this.endRule = endRule; + + this.pragmas = new HashMap<>(); + } + + public E fromStream(InputStream is, E initState) { + Scanner scn = new Scanner(is); + + E stat = initState; + + while (scn.hasNextLine()) { + String ln = scn.nextLine(); + + if (ln.equals("")) { + endRule.accept(stat); + continue; + } else if (ln.startsWith("\t")) { + continueRule.accept(new FunctionalStringTokenizer( + ln.substring(1), " "), stat); + } else { + FunctionalStringTokenizer stk = new FunctionalStringTokenizer( + ln, " "); + + String nxtToken = stk.nextToken(); + if (nxtToken.equals("#")) { + + } else if (nxtToken.equals("pragma")) { + String tk = stk.nextToken(); + + pragmas.getOrDefault(tk, (strk, ras) -> { + throw new UnknownPragmaException( + "Unknown pragma " + tk); + }).accept(stk, stat); + } else { + startRule.accept(stk, + new Pair(nxtToken, stat)); + } + } + } + + scn.close(); + + return stat; + } + + public void addPragma(String pragName, + BiConsumer pragAct) { + pragmas.put(pragName, pragAct); + } + + public void setStartRule( + BiConsumer> startRule) { + this.startRule = startRule; + } + + public void setContinueRule( + BiConsumer continueRule) { + this.continueRule = continueRule; + } + + public void setEndRule(Consumer endRule) { + this.endRule = endRule; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/UnknownPragmaException.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/UnknownPragmaException.java new file mode 100644 index 0000000..fc97a44 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/UnknownPragmaException.java @@ -0,0 +1,12 @@ +package bjc.utils.parserutils; + +import java.util.InputMismatchException; + +public class UnknownPragmaException extends InputMismatchException { + public UnknownPragmaException(String m) { + super(m); + } + + private static final long serialVersionUID = -4277573484926638662L; + +} -- cgit v1.2.3