summary refs log tree commit diff
path: root/src/path/parser.lalrpop
diff options
context:
space:
mode:
Diffstat (limited to 'src/path/parser.lalrpop')
-rw-r--r--src/path/parser.lalrpop82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/path/parser.lalrpop b/src/path/parser.lalrpop
new file mode 100644
index 0000000..0b3be9a
--- /dev/null
+++ b/src/path/parser.lalrpop
@@ -0,0 +1,82 @@
+grammar;
+
+use crate::path::GenericPath;
+use crate::path::GenericPathComponent;
+
+pub PathList: Vec<GenericPath> = {
+  => {
+    Vec::new()
+  },
+  <mut left:(<PathNoColons> COLON)*> <right:PathNoColons> => {
+    left.push(right);
+    left
+  },
+};
+
+pub PathListAllowingEmptyPaths: Vec<GenericPath> = {
+  => vec![GenericPath {
+    components: Vec::new(),
+    starts_with_slash: false,
+    ends_with_slash: false,
+  }],
+  PathNoColons => vec![<>],
+  <mut left:PathListAllowingEmptyPaths> COLON => {
+    left.push(GenericPath {
+      components: Vec::new(),
+      starts_with_slash: false,
+      ends_with_slash: false,
+    });
+    left
+  },
+  <mut left:PathListAllowingEmptyPaths> COLON <right:PathNoColons> => {
+    left.push(right);
+    left
+  },
+}
+
+pub PathNoColons: GenericPath = {
+  SLASH => GenericPath {
+    components: Vec::new(),
+    starts_with_slash: true,
+    ends_with_slash: true,
+  },
+  <PathNoColons2> => GenericPath {
+    components: <>,
+    starts_with_slash: false,
+    ends_with_slash: false,
+  },
+  <PathNoColons2> SLASH => GenericPath {
+    components: <>,
+    starts_with_slash: false,
+    ends_with_slash: true,
+  },
+  SLASH <PathNoColons2> => GenericPath {
+    components: <>,
+    starts_with_slash: true,
+    ends_with_slash: false,
+  },
+  SLASH <PathNoColons2> SLASH => GenericPath {
+    components: <>,
+    starts_with_slash: true,
+    ends_with_slash: true,
+  },
+}
+
+PathNoColons2: Vec<GenericPathComponent> = {
+  <PATH_COMPONENT_NO_COLONS> =>
+      vec![GenericPathComponent::FileOrDirectoryName(<>.to_string())],
+  <mut left:PathNoColons2> SLASH <right:PATH_COMPONENT_NO_COLONS> => {
+    left.push(GenericPathComponent::FileOrDirectoryName(right.to_string()));
+    left
+  }
+}
+
+// Whitespace is not allowed.
+match {
+  r"[^z:/]+" => PATH_COMPONENT_NO_COLONS,
+
+  r"/" => SLASH,
+
+  ":" => COLON,
+}
+