finished parser, just gotta get that tree working...

This commit is contained in:
Gabe Venberg 2023-11-05 20:20:34 -06:00
parent c01c4e62d9
commit 3f60887645
3 changed files with 221 additions and 126 deletions

73
Cargo.lock generated
View file

@ -6,8 +6,10 @@ version = 3
name = "advent_of_code_2022" name = "advent_of_code_2022"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"nom",
"once_cell", "once_cell",
"regex", "regex",
"thiserror",
] ]
[[package]] [[package]]
@ -25,12 +27,46 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.16.0" version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.7.0" version = "1.7.0"
@ -47,3 +83,40 @@ name = "regex-syntax"
version = "0.6.28" version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "syn"
version = "2.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"

View file

@ -40,4 +40,6 @@ path="src/day07/solve.rs"
[dependencies] [dependencies]
regex="1" regex="1"
once_cell = "1.16.0" once_cell = "1.16"
nom = "7.1"
thiserror = "1.0"

View file

@ -3,6 +3,11 @@ use crate::file_tree::*;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::Regex; use regex::Regex;
static IS_COMMAND_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^\$").unwrap());
static PARSE_CD_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^\$ cd (\S*)$").unwrap());
static PARSE_LS_ENTRY_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^([[:alnum:]]*) (\S*)$").unwrap());
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum Command { pub enum Command {
CdRoot, CdRoot,
@ -21,136 +26,151 @@ pub struct ParseFile {
size: usize, size: usize,
name: String, name: String,
} }
//parses a single line
pub fn parse_to_commands(input: &str) -> Vec<Command> {
let mut ret = Vec::new();
let mut lines = input.lines().peekable();
while lines.peek().is_some() {
let line = lines.next().unwrap();
if line == "$ ls" {
ret.push(Command::Ls(parse_ls(&mut lines)));
} else {
let captures = PARSE_CD_REGEX
.captures(line)
.unwrap_or_else(|| panic!("invalid line {}", line));
ret.push(match &captures[1] {
".." => Command::CdUp,
"/" => Command::CdRoot,
s => Command::Cd(s.to_string()),
})
}
}
ret
}
fn parse_ls(lines: &mut std::iter::Peekable<std::str::Lines<'_>>) -> Vec<LsEntry> {
let mut ret: Vec<LsEntry> = Vec::new();
while lines.peek().is_some() {
// if the next line is a command, then we are at the end of the ls listing.
let line = lines.peek().expect("no next line");
if IS_COMMAND_REGEX.is_match(line) {
break;
}
let captures = PARSE_LS_ENTRY_REGEX
.captures(line)
.unwrap_or_else(|| panic!("invalid line {}", line));
ret.push(match &captures[1] {
"dir" => LsEntry::Dir(captures[2].to_string()),
s => LsEntry::File(ParseFile {
size: str::parse(&captures[1]).unwrap_or_else(|_| panic!("invalid line {}", line)),
name: captures[2].to_string(),
}),
});
lines.next();
}
ret
}
pub fn parse(input: &str) -> Dir { pub fn parse(input: &str) -> Dir {
unimplemented!() unimplemented!()
} }
pub fn parse_to_tree(input: Vec<Command>) -> Dir { pub fn commands_to_tree(input: Vec<Command>) -> Dir {
unimplemented!() unimplemented!()
} }
//parses a single line #[cfg(test)]
pub fn parse_to_commands(input: &str) -> Vec<Command> { mod tests {
static PARSE_COMMAND_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^$").unwrap()); use super::*;
unimplemented!()
}
// #[cfg(test)] #[test]
// mod tests { fn test_parse_to_commands() {
// use super::*; let input = concat!(
// "$ cd /\n",
// /* #[test] "$ ls\n",
// fn test_parse() { "dir a\n",
// let input = "$ cd / "14848514 b.txt\n",
// $ ls "8504156 c.dat\n",
// dir a "dir d\n",
// 14848514 b.txt "$ cd a\n",
// 8504156 c.dat "$ ls\n",
// dir d "dir e\n",
// $ cd a "29116 f\n",
// $ ls "2557 g\n",
// dir e "62596 h.lst\n",
// 29116 f "$ cd e\n",
// 2557 g "$ ls\n",
// 62596 h.lst "584 i\n",
// $ cd e "$ cd ..\n",
// $ ls "$ cd ..\n",
// 584 i "$ cd d\n",
// $ cd .. "$ ls\n",
// $ cd .. "4060174 j\n",
// $ cd d "8033020 d.log\n",
// $ ls "5626152 d.ext\n",
// 4060174 j "7214296 k"
// 8033020 d.log );
// 5626152 d.ext assert_eq!(
// 7214296 k"; parse_to_commands(input),
// assert_eq!(parse(input), 0); vec![
// } */ Command::CdRoot,
// Command::Ls(vec![
// #[test] LsEntry::Dir(String::from("a")),
// fn test_parse_to_commands() { LsEntry::File(ParseFile {
// let input = "$ cd / size: 14848514,
// $ ls name: String::from("b.txt")
// dir a }),
// 14848514 b.txt LsEntry::File(ParseFile {
// 8504156 c.dat size: 8504156,
// dir d name: String::from("c.dat")
// $ cd a }),
// $ ls LsEntry::Dir(String::from("d"))
// dir e ]),
// 29116 f Command::Cd(String::from("a")),
// 2557 g Command::Ls(vec![
// 62596 h.lst LsEntry::Dir(String::from("e")),
// $ cd e LsEntry::File(ParseFile {
// $ ls size: 29116,
// 584 i name: String::from("f")
// $ cd .. }),
// $ cd .. LsEntry::File(ParseFile {
// $ cd d size: 2557,
// $ ls name: String::from("g")
// 4060174 j }),
// 8033020 d.log LsEntry::File(ParseFile {
// 5626152 d.ext size: 62596,
// 7214296 k"; name: String::from("h.lst")
// assert_eq!( }),
// parse_to_commands(input), ]),
// vec![ Command::Cd(String::from("e")),
// Command::CdRoot, Command::Ls(vec![LsEntry::File(ParseFile {
// Command::Ls(vec![ size: 584,
// LsEntry::Dir(String::from("a")), name: String::from("i")
// LsEntry::File(ParseFile { }),]),
// size: 14848514, Command::CdUp,
// name: String::from("b.txt") Command::CdUp,
// }), Command::Cd(String::from("d")),
// LsEntry::File(ParseFile { Command::Ls(vec![
// size: 8504156, LsEntry::File(ParseFile {
// name: String::from("c.dat") size: 4060174,
// }), name: String::from("j")
// LsEntry::Dir(String::from("d")) }),
// ]), LsEntry::File(ParseFile {
// Command::Cd(String::from("a")), size: 8033020,
// Command::Ls(vec![ name: String::from("d.log")
// LsEntry::Dir(String::from("e")), }),
// LsEntry::File(ParseFile { LsEntry::File(ParseFile {
// size: 29116, size: 5626152,
// name: String::from("f") name: String::from("d.ext")
// }), }),
// LsEntry::File(ParseFile { LsEntry::File(ParseFile {
// size: 2557, size: 7214296,
// name: String::from("g") name: String::from("k")
// }), }),
// LsEntry::File(ParseFile { ]),
// size: 62596, ]
// name: String::from("h.lst") )
// }), }
// ]), }
// Command::Cd(String::from("e")),
// Command::Ls(vec![LsEntry::File(ParseFile {
// size: 484,
// name: String::from("i")
// }),]),
// Command::CdUp,
// Command::CdUp,
// Command::Cd(String::from("d")),
// Command::Ls(vec![
// LsEntry::File(ParseFile {
// size: 4060174,
// name: String::from("j")
// }),
// LsEntry::File(ParseFile {
// size: 8033020,
// name: String::from("d.log")
// }),
// LsEntry::File(ParseFile {
// size: 5626152,
// name: String::from("d.ext")
// }),
// LsEntry::File(ParseFile {
// size: 7214296,
// name: String::from("k")
// }),
// ]),
// ]
// )
// }
// }