diff options
author | Irene Knapp <ireneista@gmail.com> | 2020-09-15 20:22:35 -0700 |
---|---|---|
committer | Irene Knapp <ireneista@gmail.com> | 2020-09-15 20:22:35 -0700 |
commit | cca86b496e00605163e96d93cda4b9b248df91fe (patch) | |
tree | 3797c1c9ed3072383d7d70179140fe4f4409dac9 /src | |
parent | 320664d6b82229a4a07fa8045dd93f260ca61308 (diff) |
Use lalrpop in a trivial way as a proof of concept. Mess with some Unicode character classes.
Diffstat (limited to 'src')
-rw-r--r-- | src/commandline.lalrpop | 16 | ||||
-rw-r--r-- | src/error.rs | 15 | ||||
-rw-r--r-- | src/main.rs | 11 |
3 files changed, 40 insertions, 2 deletions
diff --git a/src/commandline.lalrpop b/src/commandline.lalrpop new file mode 100644 index 0000000..0655281 --- /dev/null +++ b/src/commandline.lalrpop @@ -0,0 +1,16 @@ +grammar; + +// +// Z is the unicode class for separators, including line, paragraph, and space +// separators. C is the class for control characters. P is the class for +// punctuation. This regexp tests for the intersection of the negation of these +// character classes, which is any character NOT in one of these three classes. +// +// [1] is the official reference, and [2] is a site that is useful for browsing +// to get an intuitive idea of what these classes mean. +// +// [1] http://www.unicode.org/reports/tr44/#General_Category_Values +// [2] https://www.compart.com/en/unicode/category +// +pub Filename: String = <filename:r"[\P{Z}&&\P{C}&&\P{P}]+"> => filename.to_string(); + diff --git a/src/error.rs b/src/error.rs index aa9e9d6..96be297 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,10 @@ +type ParseError<'a> = + lalrpop_util::ParseError<usize, lalrpop_util::lexer::Token<'a>, &'a str>; + #[derive(Debug)] pub enum Error { IO(std::io::Error), + Parse(String), } impl std::error::Error for Error { } @@ -9,6 +13,7 @@ impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Error::IO(e) => e.fmt(f), + Error::Parse(e) => e.fmt(f), } } } @@ -18,6 +23,9 @@ impl std::cmp::PartialEq for Error { match (self, other) { (Error::IO(_), Error::IO(_)) => false, + (Error::Parse(_), Error::Parse(_)) => + false, + _ => false, } } } @@ -27,3 +35,10 @@ impl From<std::io::Error> for Error { Error::IO(e) } } + +impl From<ParseError<'_>> for Error { + fn from(e: ParseError<'_>) -> Error { + Error::Parse(format!("{}", e)) + } +} + diff --git a/src/main.rs b/src/main.rs index e176dc0..816ed49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,10 @@ use error::Error; use std::io; use std::io::prelude::*; +#[macro_use] extern crate lalrpop_util; + +lalrpop_mod!(pub commandline); + pub type Result<T> = std::result::Result<T, Error>; @@ -33,7 +37,7 @@ fn repl() -> Result<()> { let input = read()?; match input { - Input::String(string) => execute(string)?, + Input::String(string) => execute(&string)?, Input::End => break, } } @@ -62,8 +66,11 @@ fn read() -> Result<Input> { } -fn execute(input: String) -> Result<()> { +fn execute(input: &str) -> Result<()> { + let filename = commandline::FilenameParser::new().parse(input)?; + println!("{}", input); + println!("filename '{}'", filename); Ok(()) } |