From e19519e155af95698807f377a5f6b525e255c4e5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 18 Apr 2020 15:12:21 +0200 Subject: first version of the new filter pipeline --- src/fexpr/mod.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/fexpr/mod.rs (limited to 'src/fexpr/mod.rs') diff --git a/src/fexpr/mod.rs b/src/fexpr/mod.rs new file mode 100644 index 0000000..f2b1090 --- /dev/null +++ b/src/fexpr/mod.rs @@ -0,0 +1,25 @@ +//! Filter expression language. +//! +//! This module contains methods to parse a given string into an abstract filter tree, check its +//! type and convert it to a [`Filter`][super::filters::Filter]. +// Make it available in the grammar mod. +use super::{filters, FightOutcome, SearchField, Weekday}; +use lalrpop_util::lalrpop_mod; + +use thiserror::Error; + +lalrpop_mod!(pub grammar, "/fexpr/grammar.rs"); + +#[derive(Debug, Error)] +pub enum FError { + #[error("invalid regular expression: {0}")] + InvalidRegex(String), + #[error("invalid fight outcome: {0}")] + InvalidFightOutcome(String), + #[error("invalid weekday: {0}")] + InvalidWeekday(String), + #[error("invalid timestamp: {0}")] + InvalidTimestamp(String), + #[error("invalid boss name: {0}")] + InvalidBoss(String), +} -- cgit v1.2.3 From 0e4e148a0890ba206df40cffe5a5f1cc47c8079e Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 20 Apr 2020 14:27:42 +0200 Subject: hook up new expression parser to command line args This method is not perfect yet, because 1. The items are not documented as they were before 2. You need to separate the args with --, otherwise Clap tries to parse them as optional flags This should be fixed (especially the documentation part) before merging into master. --- src/fexpr/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/fexpr/mod.rs') diff --git a/src/fexpr/mod.rs b/src/fexpr/mod.rs index f2b1090..aafdea7 100644 --- a/src/fexpr/mod.rs +++ b/src/fexpr/mod.rs @@ -4,7 +4,7 @@ //! type and convert it to a [`Filter`][super::filters::Filter]. // Make it available in the grammar mod. use super::{filters, FightOutcome, SearchField, Weekday}; -use lalrpop_util::lalrpop_mod; +use lalrpop_util::{lalrpop_mod, lexer::Token, ParseError}; use thiserror::Error; @@ -23,3 +23,9 @@ pub enum FError { #[error("invalid boss name: {0}")] InvalidBoss(String), } + +pub fn parse_logfilter( + input: &str, +) -> Result, ParseError> { + grammar::LogFilterParser::new().parse(input) +} -- cgit v1.2.3 From 185a5b2f802f9d05c3eb40f807c0488f168c6661 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 21 Apr 2020 13:59:28 +0200 Subject: better error outputs --- src/fexpr/mod.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 11 deletions(-) (limited to 'src/fexpr/mod.rs') diff --git a/src/fexpr/mod.rs b/src/fexpr/mod.rs index aafdea7..5754d94 100644 --- a/src/fexpr/mod.rs +++ b/src/fexpr/mod.rs @@ -4,28 +4,63 @@ //! type and convert it to a [`Filter`][super::filters::Filter]. // Make it available in the grammar mod. use super::{filters, FightOutcome, SearchField, Weekday}; -use lalrpop_util::{lalrpop_mod, lexer::Token, ParseError}; +use std::{error, fmt}; + +use lalrpop_util::{lalrpop_mod, lexer::Token, ParseError}; use thiserror::Error; -lalrpop_mod!(pub grammar, "/fexpr/grammar.rs"); +lalrpop_mod!(#[allow(clippy::all)] pub grammar, "/fexpr/grammar.rs"); + +#[derive(Debug)] +pub struct FError { + location: usize, + data: String, + kind: FErrorKind, +} + +impl fmt::Display for FError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} (at {})", self.kind, self.location) + } +} + +impl error::Error for FError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(&self.kind) + } +} #[derive(Debug, Error)] -pub enum FError { +pub enum FErrorKind { #[error("invalid regular expression: {0}")] - InvalidRegex(String), - #[error("invalid fight outcome: {0}")] - InvalidFightOutcome(String), - #[error("invalid weekday: {0}")] - InvalidWeekday(String), + InvalidRegex(#[from] regex::Error), + #[error("invalid fight outcome")] + InvalidFightOutcome, + #[error("invalid weekday")] + InvalidWeekday, #[error("invalid timestamp: {0}")] - InvalidTimestamp(String), - #[error("invalid boss name: {0}")] - InvalidBoss(String), + InvalidTimestamp(#[from] chrono::format::ParseError), + #[error("invalid boss name")] + InvalidBoss, } +/// Shortcut to create a new parser and parse the given input. pub fn parse_logfilter( input: &str, ) -> Result, ParseError> { grammar::LogFilterParser::new().parse(input) } + +/// Extract the location from the given error. +pub fn location(err: &ParseError) -> usize { + match *err { + ParseError::InvalidToken { location } => location, + ParseError::UnrecognizedEOF { location, .. } => location, + ParseError::UnrecognizedToken { + token: (l, _, _), .. + } => l, + ParseError::ExtraToken { token: (l, _, _) } => l, + ParseError::User { ref error } => error.location, + } +} -- cgit v1.2.3 From 0a27adbc0bf3bbbf87fea9e55c00c38f61d55058 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 21 Apr 2020 14:23:50 +0200 Subject: add a small repl --- src/fexpr/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/fexpr/mod.rs') diff --git a/src/fexpr/mod.rs b/src/fexpr/mod.rs index 5754d94..5610aba 100644 --- a/src/fexpr/mod.rs +++ b/src/fexpr/mod.rs @@ -46,9 +46,9 @@ pub enum FErrorKind { } /// Shortcut to create a new parser and parse the given input. -pub fn parse_logfilter( - input: &str, -) -> Result, ParseError> { +pub fn parse_logfilter<'a>( + input: &'a str, +) -> Result, ParseError, FError>> { grammar::LogFilterParser::new().parse(input) } -- cgit v1.2.3