summaryrefslogtreecommitdiff
path: root/base/src/main/java/bjc/utils/parserutils
diff options
context:
space:
mode:
authorBen Culkin <scorpress@gmail.com>2022-08-16 23:04:07 -0400
committerBen Culkin <scorpress@gmail.com>2022-08-16 23:04:07 -0400
commit05bb1067b348f43108fd04b968dc53fc338373fb (patch)
tree0abd83efa1b2e2a563cdb162ce1b5303b5ef05e7 /base/src/main/java/bjc/utils/parserutils
parent5c5f049917745f487264948aa5663ca64681f510 (diff)
Update a few things
Diffstat (limited to 'base/src/main/java/bjc/utils/parserutils')
-rw-r--r--base/src/main/java/bjc/utils/parserutils/pattern/PatternPart.java147
1 files changed, 147 insertions, 0 deletions
diff --git a/base/src/main/java/bjc/utils/parserutils/pattern/PatternPart.java b/base/src/main/java/bjc/utils/parserutils/pattern/PatternPart.java
new file mode 100644
index 0000000..6661072
--- /dev/null
+++ b/base/src/main/java/bjc/utils/parserutils/pattern/PatternPart.java
@@ -0,0 +1,147 @@
+package bjc.utils.parserutils.pattern;
+
+import java.util.StringJoiner;
+import java.util.function.Supplier;
+import java.util.regex.*;
+
+/**
+ * Builder interface for regex patterns.
+ *
+ * @author bjculkin
+ *
+ */
+public interface PatternPart {
+ /**
+ * Convert this pattern part into a regex.
+ *
+ * @return The regex this part represents.
+ */
+ public String toRegex();
+
+ public boolean canOptimize();
+
+ static PatternPart part(boolean canOptimize, Supplier<String> func) {
+ return new PatternPart() {
+
+ @Override
+ public String toRegex() {
+ return func.get();
+ }
+
+ @Override
+ public boolean canOptimize() {
+ return canOptimize;
+ }
+ };
+ }
+
+ static PatternPart var(Supplier<String> source) {
+ return part(false, source);
+ }
+ /**
+ * Create a 'raw' pattern part, which just echoes the given string.
+ *
+ * @param str The regex to include
+ *
+ * @return A pattern part which converts to the given string.
+ */
+ static PatternPart raw(String str) {
+ return part(true, () -> str);
+ }
+
+ static PatternPart joining(String joiner, PatternPart... parts) {
+ return new PatternPart() {
+
+ @Override
+ public String toRegex() {
+ StringJoiner sj = new StringJoiner(joiner);
+ for (PatternPart part : parts) sj.add(part.toRegex());
+ return sj.toString();
+ }
+
+ @Override
+ public boolean canOptimize() {
+ for (PatternPart part : parts)
+ if (!part.canOptimize()) return false;
+
+ return true;
+ }
+ };
+ }
+ /**
+ * Create a pattern part which matches the given string.
+ *
+ * @param str The string to match
+ *
+ * @return A pattern which matches the given string.
+ */
+ static PatternPart literal(String str) {
+ return part(true, () -> Pattern.quote(str));
+ }
+
+ /**
+ * Create a pattern part which matches a single digit.
+ *
+ * @return A pattern that matches a digit.
+ */
+ static PatternPart digit() {
+ return raw("\\d");
+ }
+
+ static PatternPart cclass(char... chars) {
+ return part(true, () -> {
+ StringBuilder sb = new StringBuilder("[");
+ for (char ch : chars) sb.append(ch);
+ sb.append("]");
+ return sb.toString();
+ });
+ }
+
+ static PatternPart notCClass(char... chars) {
+ return part(true, () -> {
+ StringBuilder sb = new StringBuilder("[^");
+ for (char ch : chars) sb.append(ch);
+ sb.append("]");
+ return sb.toString();
+ });
+ }
+
+ static PatternPart nonspace() {
+ return raw("\\S");
+ }
+
+ static PatternPart concat(PatternPart... parts) {
+ return joining(" ", parts);
+ }
+
+ static PatternPart alternate(PatternPart... parts) {
+ return joining("|", parts);
+ }
+
+ static PatternPart repeat(PatternPart part) {
+ return part(part.canOptimize(), () -> part.toRegex() + "*");
+ }
+
+ static PatternPart optional(PatternPart part) {
+ return part(part.canOptimize(), () -> part.toRegex() + "?");
+ }
+
+ static PatternPart repeatAtLeastOnce(PatternPart part) {
+ return part(part.canOptimize(), () -> part.toRegex() + "*");
+ }
+
+ static PatternPart surround(String lhs, String rhs, PatternPart part) {
+ return part(part.canOptimize(), () -> lhs + part.toRegex() + rhs);
+ }
+ static PatternPart group(PatternPart part) {
+ return surround("(", ")", part);
+ }
+
+ static PatternPart namedGroup(String groupName, PatternPart part) {
+ return surround("(<" + groupName + ">", ")", part);
+ }
+
+ static PatternPart nonCaptureGroup(PatternPart part) {
+ return surround("(?:", ")", part);
+ }
+}