From f5ec40b8fbbe7d4409d94dafcbfcdd41b8a6202b Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Fri, 25 Dec 2020 16:31:48 -0800 Subject: got the path stuff parsing just right --- src/main.rs | 22 +++---------- src/path.lalrpop | 38 ----------------------- src/path.rs | 27 ++++++++++++++++ src/path/parser.lalrpop | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 56 deletions(-) delete mode 100644 src/path.lalrpop create mode 100644 src/path.rs create mode 100644 src/path/parser.lalrpop 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 = std::result::Result; - pub enum Input { String(String), End, } -pub struct GenericPath { - absolute: bool, - directory: bool, - components: Vec, -} - -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() - }, - COLON)*> => { - left.push(right); - left - }, -}; - -pub PathListAllowingEmptyPaths: Vec<&'input str> = { - => vec![""], - Path => vec![<>], - COLON => { - left.push(""); - left - }, - COLON => { - left.push(right); - left - }, -} - -pub Path: &'input str = { - , -} - -// 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, +} + +#[derive(Debug)] +pub enum GenericPathComponent { + FileOrDirectoryName(String), + CurrentDirectory, + ParentDirectory, +} + +#[derive(Debug)] +pub struct GenericPath { + components: Vec, + 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 = { + => { + Vec::new() + }, + COLON)*> => { + left.push(right); + left + }, +}; + +pub PathListAllowingEmptyPaths: Vec = { + => vec![GenericPath { + components: Vec::new(), + starts_with_slash: false, + ends_with_slash: false, + }], + PathNoColons => vec![<>], + COLON => { + left.push(GenericPath { + components: Vec::new(), + starts_with_slash: false, + ends_with_slash: false, + }); + left + }, + COLON => { + left.push(right); + left + }, +} + +pub PathNoColons: GenericPath = { + SLASH => GenericPath { + components: Vec::new(), + starts_with_slash: true, + ends_with_slash: true, + }, + => GenericPath { + components: <>, + starts_with_slash: false, + ends_with_slash: false, + }, + SLASH => GenericPath { + components: <>, + starts_with_slash: false, + ends_with_slash: true, + }, + SLASH => GenericPath { + components: <>, + starts_with_slash: true, + ends_with_slash: false, + }, + SLASH SLASH => GenericPath { + components: <>, + starts_with_slash: true, + ends_with_slash: true, + }, +} + +PathNoColons2: Vec = { + => + vec![GenericPathComponent::FileOrDirectoryName(<>.to_string())], + SLASH => { + left.push(GenericPathComponent::FileOrDirectoryName(right.to_string())); + left + } +} + +// Whitespace is not allowed. +match { + r"[^z:/]+" => PATH_COMPONENT_NO_COLONS, + + r"/" => SLASH, + + ":" => COLON, +} + -- cgit 1.4.1