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/grammar.lalrpop | 131 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/fexpr/grammar.lalrpop (limited to 'src/fexpr/grammar.lalrpop') diff --git a/src/fexpr/grammar.lalrpop b/src/fexpr/grammar.lalrpop new file mode 100644 index 0000000..cb16153 --- /dev/null +++ b/src/fexpr/grammar.lalrpop @@ -0,0 +1,131 @@ +use super::{ + FError, + FightOutcome, + filters, + SearchField, + Weekday, +}; +use evtclib::statistics::gamedata::Boss; +use std::collections::HashSet; +use lalrpop_util::ParseError; + +use chrono::NaiveDateTime; +use regex::Regex; + +grammar; + +extern { + type Error = FError; +} + +pub LogFilter: Box = { + Disjunction, +} + +PlayerFilter: Box = { + Disjunction, +} + +Disjunction: T = { + > "or" > => a | b, + Conjunction, +} + +Conjunction: T = { + > "and"? > => a & b, + Negation, +} + +Negation: T = { + "not" => ! <>, + "!" => ! <>, + T, +} + +LogPredicate: Box = { + "-success" => filters::log::OutcomeFilter::success(), + "-wipe" => filters::log::OutcomeFilter::wipe(), + "-outcome" > => filters::log::OutcomeFilter::new(<>), + + "-weekday" > => filters::log::WeekdayFilter::new(<>), + "-before" => filters::log::TimeFilter::new(None, Some(<>)), + "-after" => filters::log::TimeFilter::new(Some(<>), None), + + "-boss" > => filters::log::BossFilter::new(<>), + + "all" "(" "player" ":" ")" => filters::player::all(<>), + "any" "(" "player" ":" ")" => filters::player::any(<>), + "exists" "(" "player" ":" ")" => filters::player::any(<>), + + "(" ")", +} + +PlayerPredicate: Box = { + "-character" => filters::player::NameFilter::new(SearchField::Character, <>), + "-account" => filters::player::NameFilter::new(SearchField::Account, <>), + "-name" => + filters::player::NameFilter::new(SearchField::Account, <>.clone()) + | filters::player::NameFilter::new(SearchField::Character, <>), + + "(" ")", +} + +Regex: Regex = { + =>? Regex::new(&s[1..s.len() - 1]).map_err(|_| ParseError::User { + error: FError::InvalidRegex(s.into()), + }), + =>? Regex::new(s).map_err(|e| ParseError::User { + error: FError::InvalidRegex(s.into()), + }), +} + +FightOutcome: FightOutcome = { + =>? <>.parse().map_err(|_| ParseError::User { + error: FError::InvalidFightOutcome(<>.into()), + }), +} + +Weekday: Weekday = { + =>? <>.parse().map_err(|_| ParseError::User { + error: FError::InvalidWeekday(<>.into()), + }), +} + +Boss: Boss = { + =>? <>.parse().map_err(|_| ParseError::User { + error: FError::InvalidBoss(<>.into()), + }), +} + +Date: NaiveDateTime = { + =>? NaiveDateTime::parse_from_str(<>, "%Y-%m-%d %H:%M:%S") + .map_err(|_| ParseError::User { + error: FError::InvalidTimestamp(<>.into()), + }), + =>? NaiveDateTime::parse_from_str(&format!("{} 00:00:00", <>), "%Y-%m-%d %H:%M:%S") + .map_err(|_| ParseError::User { + error: FError::InvalidTimestamp(<>.into()), + }), +} + +Comma: HashSet = { + ",")*> => { + let mut result = v.into_iter().collect::>(); + result.insert(e); + result + }, +} + +match { + "player" => "player", + "not" => "not", + "any" => "any", + "all" => "all", + "exists" => "exists", + + r"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d" => datetime, + r"\d\d\d\d-\d\d-\d\d" => date, + r"\w+" => word, + + _ +} -- cgit v1.2.3