aboutsummaryrefslogtreecommitdiff
path: root/java/pablotron/luigi/Parser.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/pablotron/luigi/Parser.java')
-rw-r--r--java/pablotron/luigi/Parser.java114
1 files changed, 114 insertions, 0 deletions
diff --git a/java/pablotron/luigi/Parser.java b/java/pablotron/luigi/Parser.java
new file mode 100644
index 0000000..0daef25
--- /dev/null
+++ b/java/pablotron/luigi/Parser.java
@@ -0,0 +1,114 @@
+package pablotron.luigi;
+
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+import pablotron.luigi.actions.Action;
+import pablotron.luigi.actions.FilterAction;
+import pablotron.luigi.actions.TextAction;
+import pablotron.luigi.FilterReference;
+import pablotron.luigi.LuigiError;
+
+public final class Parser {
+ private static final Pattern RE_ACTION = Pattern.compile(
+ // match opening brace
+ "%\\{" +
+
+ // match optional whitespace
+ "\\s*" +
+
+ // match key
+ // "(?<key>[^\\s\\|\\}]+)" +
+ "([^\\s\\|\\}]+)" +
+
+ // match filter(s)
+ // "(?<filters>(\\s*\\|(\\s*[^\\s\\|\\}]+)+)*)" +
+ "((\\s*\\|(\\s*[^\\s\\|\\}]+)+)*)" +
+
+ // match optional whitespace
+ "\\s*" +
+
+ // match closing brace
+ "\\}" +
+
+ // or match up all non-% chars or a single % char
+ // "| (?<text>[^%]* | %)",
+ "| ([^%]* | %)",
+
+ Pattern.COMMENTS
+ );
+
+ private static final Pattern RE_FILTER = Pattern.compile(
+ // match filter name
+ // "(?<name>\\S+)" +
+ "(\\S+)" +
+
+ // match filter arguments (optional)
+ // "(?<args>(\\s*\\S+)*)" +
+ "((\\s*\\S+)*)" +
+
+ // optional trailing whitespace
+ "\\s*",
+
+ Pattern.COMMENTS
+ );
+
+ private static final Pattern RE_DELIM_FILTERS = Pattern.compile(
+ "\\s*\\|\\s*"
+ );
+
+ private static final Pattern RE_DELIM_ARGS = Pattern.compile(
+ "\\s+"
+ );
+
+ public static Action[] parse_template(
+ String template
+ ) throws LuigiError {
+ ArrayList<Action> r = new ArrayList<Action>();
+
+ // match on text
+ final Matcher m = RE_ACTION.matcher(template);
+
+ while (m.find()) {
+ // String key = m.group("key");
+ String key = m.group(1);
+
+ if (key != null && key.length() > 0) {
+ // r.add(new FilterAction(key, parse_filters(m.group("filters"))));
+ r.add(new FilterAction(key, parse_filters(m.group(2))));
+ } else {
+ // r.add(new TextAction(m.group("text")));
+ r.add(new TextAction(m.group(5)));
+ }
+ }
+
+ // build array of results
+ return r.toArray(new Action[r.size()]);
+ }
+
+ public static FilterReference[] parse_filters(
+ String filters_str
+ ) throws LuigiError {
+ ArrayList<FilterReference> r = new ArrayList<FilterReference>();
+
+ // split string into individual filters and handle each one
+ for (String f: RE_DELIM_FILTERS.split(filters_str)) {
+ // trim filter string and skip empty filters
+ f = f.trim();
+ if (f.length() == 0)
+ continue;
+
+ // match on filter and check for error
+ Matcher m = RE_FILTER.matcher(f);
+ if (!m.find())
+ throw new LuigiError("invalid filter: " + f);
+
+ // append new filter reference to result
+ r.add(new FilterReference(m.group(1), RE_DELIM_ARGS.split(m.group(2))));
+ }
+
+ // return result
+ return r.toArray(new FilterReference[r.size()]);
+ }
+};