diff options
-rw-r--r-- | src/main.rs | 22 | ||||
-rw-r--r-- | src/path.lalrpop | 38 | ||||
-rw-r--r-- | src/path.rs | 27 | ||||
-rw-r--r-- | src/path/parser.lalrpop | 82 |
4 files changed, 113 insertions, 56 deletions
diff --git a/src/main.rs b/src/main.rs index d499ad9..2a5234f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -pub mod error; - use error::Error; use std::io; use std::io::prelude::*; @@ -7,29 +5,17 @@ use std::io::prelude::*; #[macro_use] extern crate lalrpop_util; lalrpop_mod!(pub commandline); -lalrpop_mod!(pub path); +pub mod error; +pub mod path; pub type Result<T> = std::result::Result<T, Error>; - pub enum Input { String(String), End, } -pub struct GenericPath { - absolute: bool, - directory: bool, - components: Vec<GenericPathComponent>, -} - -pub enum GenericPathComponent { - CurrentDirectory, - ParentDirectory, - Entry(String), -} - fn main() -> Result<()> { std::process::exit(match repl() { @@ -87,12 +73,12 @@ fn execute(input: &str) -> Result<()> { match invocation.as_slice() { ["paths", path_list, ..] => { println!("{:?}", path_list); - match path::PathListParser::new().parse(path_list) { + match path::parser::PathListParser::new().parse(path_list) { Ok(parsed_paths) => { println!("paths '{:?}'", parsed_paths); }, Err(_) => { - match path::PathListAllowingEmptyPathsParser::new() + match path::parser::PathListAllowingEmptyPathsParser::new() .parse(path_list) { Ok(parsed) => { diff --git a/src/path.lalrpop b/src/path.lalrpop deleted file mode 100644 index 099b217..0000000 --- a/src/path.lalrpop +++ /dev/null @@ -1,38 +0,0 @@ -grammar; - -pub PathList: Vec<&'input str> = { - => { - Vec::new() - }, - <mut left:(<Path> COLON)*> <right:Path> => { - left.push(right); - left - }, -}; - -pub PathListAllowingEmptyPaths: Vec<&'input str> = { - => vec![""], - Path => vec![<>], - <mut left:PathListAllowingEmptyPaths> COLON => { - left.push(""); - left - }, - <mut left:PathListAllowingEmptyPaths> COLON <right:Path> => { - left.push(right); - left - }, -} - -pub Path: &'input str = { - <PATH_COMPONENT>, -} - -// Whitespace is not allowed. -match { - r"[^z:/]+" => PATH_COMPONENT, - - r"/" => SLASH, - - ":" => COLON, -} - diff --git a/src/path.rs b/src/path.rs new file mode 100644 index 0000000..bfb5719 --- /dev/null +++ b/src/path.rs @@ -0,0 +1,27 @@ +lalrpop_mod!(pub parser, "/path/parser.rs"); + + +#[derive(Debug)] +pub struct DirectoryName(String); + +#[derive(Debug)] +pub struct FileName(String); + +#[derive(Debug)] +pub struct AbsoluteDirectoryPath { + components: Vec<DirectoryName>, +} + +#[derive(Debug)] +pub enum GenericPathComponent { + FileOrDirectoryName(String), + CurrentDirectory, + ParentDirectory, +} + +#[derive(Debug)] +pub struct GenericPath { + components: Vec<GenericPathComponent>, + starts_with_slash: bool, + ends_with_slash: bool, +} 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, +} + |