M Cargo.lock => Cargo.lock +173 -0
@@ 9,6 9,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
[[package]]
+name = "block-buffer"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
+dependencies = [
+ "block-padding",
+ "byte-tools",
+ "byteorder",
+ "generic-array",
+]
+
+[[package]]
+name = "block-padding"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
+dependencies = [
+ "byte-tools",
+]
+
+[[package]]
+name = "byte-tools"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
name = "day1"
version = "0.1.0"
dependencies = [
@@ 20,4 53,144 @@ name = "day2"
version = "0.1.0"
dependencies = [
"anyhow",
+ "pest",
+ "pest_derive",
+]
+
+[[package]]
+name = "digest"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "fake-simd"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
+
+[[package]]
+name = "generic-array"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
+dependencies = [
+ "typenum",
+]
+
+[[package]]
+name = "maplit"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
+
+[[package]]
+name = "opaque-debug"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
+
+[[package]]
+name = "pest"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
+dependencies = [
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
+dependencies = [
+ "maplit",
+ "pest",
+ "sha-1",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
+dependencies = [
+ "proc-macro2",
]
+
+[[package]]
+name = "sha-1"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
+dependencies = [
+ "block-buffer",
+ "digest",
+ "fake-simd",
+ "opaque-debug",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.82"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "typenum"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
+
+[[package]]
+name = "ucd-trie"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
M day2/Cargo.toml => day2/Cargo.toml +2 -0
@@ 8,3 8,5 @@ license = "BSD-2-Clause"
[dependencies]
anyhow = "1.0"
+pest = "2.0"
+pest_derive = "2.0"
A day2/src/grammar.pest => day2/src/grammar.pest +7 -0
@@ 0,0 1,7 @@
+direction = { "up" | "down" | "forward" }
+distance = { (('1'..'9') ~ ASCII_DIGIT*) | "0" }
+instruction = { direction ~ distance }
+instructions = { instruction ~ (newline ~ instruction)* }
+WHITESPACE = _{ " " | "\t" }
+newline = _{ "\n"+ }
+document = _{ SOI ~ instructions ~ EOI }
M day2/src/main.rs => day2/src/main.rs +28 -20
@@ 1,6 1,15 @@
-use anyhow::{anyhow, Error, Result};
+use anyhow::{anyhow, Result};
+use pest::Parser;
use std::io::{stdin, BufRead, BufReader};
+extern crate pest;
+#[macro_use]
+extern crate pest_derive;
+
+#[derive(Parser)]
+#[grammar = "grammar.pest"]
+struct InstrParser;
+
#[derive(Debug, Copy, Clone)]
struct Vec3 {
x: i64,
@@ 41,39 50,38 @@ enum Instr {
Forward(i64),
}
-fn parse_instr(str: Result<String, std::io::Error>) -> Result<Instr> {
- if let Err(err) = str {
- return Err(Error::new(err));
+fn parse_instr(line: &String) -> Result<Instr> {
+ let pair = InstrParser::parse(Rule::instruction, line.as_str())?
+ .next()
+ .unwrap();
+ match pair.as_rule() {
+ Rule::instruction => (),
+ any @ _ => return Err(anyhow!("unexpected rule {:?}", any)),
}
- let str = str.unwrap();
- let mut words = str.split_whitespace();
- let dir = words
+ let mut pairs = pair.into_inner();
+ let dir = pairs
.next()
- .ok_or_else(|| anyhow!("expected direction, got nothing"))?;
- let dist = words
+ .ok_or_else(|| anyhow!("expected direction, got nothing"))?
+ .as_span();
+ let dist = pairs
.next()
- .ok_or_else(|| anyhow!("expected distance, got nothing"))?;
-
- let eol = words.next();
- if !eol.is_none() {
- return Err(anyhow!("expected end of line in instr line, got {:?}", eol));
- }
+ .ok_or_else(|| anyhow!("expected distance, got nothing"))?
+ .as_span();
- let dist = dist.parse::<i64>()?;
- match dir {
+ let dist = dist.as_str().parse::<i64>()?;
+ match dir.as_str() {
"up" => Ok(Instr::Up(dist)),
"down" => Ok(Instr::Down(dist)),
"forward" => Ok(Instr::Forward(dist)),
- _ => Err(anyhow!("unexpected direction {} in instr line", dir)),
+ any @ _ => Err(anyhow!("unexpected direction {} in instr line", any)),
}
}
fn parse_instrs(r: &mut dyn BufRead) -> Result<Vec<Instr>> {
return r
.lines()
- .filter(|s| s.as_ref().map_or(false, |s| !s.is_empty()))
- .map(parse_instr)
+ .filter_map(|s| s.ok().as_ref().map(parse_instr))
.collect();
}